diff --git a/src/mol-script/script.ts b/src/mol-script/script.ts
index 866d5f1efa36a27d188efd1a13b760ae46bc100a..553e5e2425ce417962cf2b29b60d1daec4c43e7f 100644
--- a/src/mol-script/script.ts
+++ b/src/mol-script/script.ts
@@ -25,12 +25,12 @@ export { Script };
 
 interface Script { expression: string, language: Script.Language}
 
-function Script(expression: string = "(sel.atom.all)", language: Script.Language = "mol-script"): Script {
+function Script(expression: string = '(sel.atom.all)', language: Script.Language = 'mol-script'): Script {
     return { expression, language };
 }
 
 namespace Script {
-    export type Language = 'mol-script' | 'pymol' | 'vmd' | 'jmol' | 'rasmol' 
+    export type Language = 'mol-script' | 'pymol' | 'vmd' | 'jmol' | 'rasmol'
 
     export function is(x: any): x is Script {
         return !!x && typeof (x as Script).expression === 'string' && !!(x as Script).language;
@@ -42,20 +42,20 @@ namespace Script {
 
     export function toExpression(script: Script): Expression {
         switch (script.language) {
-	case 'mol-script':
+            case 'mol-script':
 	    const parsed = parseMolScript(script.expression);
 	    if (parsed.length === 0) throw new Error('No query');
 	    return transpileMolScript(parsed[0]);
-	case 'pymol':	    
-	    return parse("pymol",script.expression) as Expression;	           
-	case 'jmol':
-	    return parse("jmol",script.expression) as Expression;
-	case 'vmd':
-	    return parse("vmd",script.expression) as Expression;
-	case 'rasmol':
-	    return parse("rasmol",script.expression) as Expression;	   
+            case 'pymol':
+	    return parse('pymol', script.expression) as Expression;
+            case 'jmol':
+	    return parse('jmol', script.expression) as Expression;
+            case 'vmd':
+	    return parse('vmd', script.expression) as Expression;
+            case 'rasmol':
+	    return parse('rasmol', script.expression) as Expression;
         }
- 
+
         throw new Error('unsupported script language');
     }
 
diff --git a/src/mol-script/transpile.ts b/src/mol-script/transpile.ts
index da85f253bec8ba8933a745cc51de3ae742666647..db9a69301484d0aec7d25b4d7562827ccd764629 100644
--- a/src/mol-script/transpile.ts
+++ b/src/mol-script/transpile.ts
@@ -7,22 +7,22 @@
  * Adapted from MolQL src/transpile.ts
  */
 
-import Transpiler from './transpilers/transpiler'
-import _transpiler from './transpilers/all'
-const transpiler: {[index: string]: Transpiler} = _transpiler
+import { Transpiler } from './transpilers/transpiler';
+import { _transpiler } from './transpilers/all';
+const transpiler: {[index: string]: Transpiler} = _transpiler;
 
 export function parse(lang: string, str: string) {
     try {
-	const query = transpiler[lang](str);
-	
-	console.log(str)
-//	console.log(util.inspect(query, {depth: 20, color: true}))
-	console.log('\n')
-	
-	return query;      
+        const query = transpiler[lang](str);
+
+        console.log(str);
+        //	console.log(util.inspect(query, {depth: 20, color: true}))
+        console.log('\n');
+
+        return query;
     } catch (e) {
-	console.log(str)
-	console.log(e.message)
-	console.log('\n')
+        console.log(str);
+        console.log(e.message);
+        console.log('\n');
     }
 }
diff --git a/src/mol-script/transpilers/_spec/pymol.spec.ts b/src/mol-script/transpilers/_spec/pymol.spec.ts
index 8e85d1281b899c2e64bc446cdf6cc9f9dfe821b6..606f813bb005e77e56125ff9710f3e73b71960de 100644
--- a/src/mol-script/transpilers/_spec/pymol.spec.ts
+++ b/src/mol-script/transpilers/_spec/pymol.spec.ts
@@ -7,13 +7,13 @@
 
 import * as u from './utils';
 import { parse } from '../../transpile';
-//import { transpiler } from '../pymol/parser';
+// import { transpiler } from '../pymol/parser';
 import { keywords } from '../pymol/keywords';
 import { properties } from '../pymol/properties';
 import { operators } from '../pymol/operators';
 
 /* FAULTY IMPORTS */
-//import compile from '../../compiler';
+// import compile from '../../compiler';
 
 const general = {
     supported: [
@@ -47,14 +47,14 @@ const general = {
 describe('pymol general', () => {
     general.supported.forEach(str => {
         it(str, () => {
-            const expr = parse("pymol",str);
+            const expr = parse('pymol', str);
 	    expect(expr).toThrow();
-  //          compile(expr);
+            //          compile(expr);
         });
     });
     general.unsupported.forEach(str => {
         it(str, () => {
-            const transpileStr = () => parse("pymol",str);
+            const transpileStr = () => parse('pymol', str);
             expect(transpileStr).toThrow();
             expect(transpileStr).not.toThrowError(RangeError);
         });
@@ -72,6 +72,6 @@ describe('pymol general', () => {
 // 'b = 1',
 // 'fc.=.1',
 
-describe('pymol keywords', () => u.testKeywords(keywords, "pymol"));
-describe('pymol operators', () => u.testOperators(operators, "pymol"));
-describe('pymol properties', () => u.testProperties(properties, "pymol"));
+describe('pymol keywords', () => u.testKeywords(keywords, 'pymol'));
+describe('pymol operators', () => u.testOperators(operators, 'pymol'));
+describe('pymol properties', () => u.testProperties(properties, 'pymol'));
diff --git a/src/mol-script/transpilers/_spec/utils.ts b/src/mol-script/transpilers/_spec/utils.ts
index 7b6be58a3c9cdcbced77d50330830d6cba4cb7cb..dc1497d9d13e4594aee758b725573edb3dda74d4 100644
--- a/src/mol-script/transpilers/_spec/utils.ts
+++ b/src/mol-script/transpilers/_spec/utils.ts
@@ -9,18 +9,18 @@ import { parse } from '../../transpile';
 import { KeywordDict, PropertyDict, OperatorList } from '../types';
 
 /* FAULTY IMPORTS */
-//import compile from '../../compiler';
+// import compile from '../../compiler';
 
-export function testKeywords(keywords: KeywordDict,language: string) {
+export function testKeywords(keywords: KeywordDict, language: string) {
     for (const name in keywords) {
         it(name, () => {
             const k = keywords[name];
             if (k.map) {
-                const expr = parse(language,name);
-  //              compile(expr);
+                const expr = parse(language, name);
+                //              compile(expr);
                 expect(expr).toEqual(k.map());
             } else {
-                const transpile = () => parse(language,name);
+                const transpile = () => parse(language, name);
                 expect(transpile).toThrow();
                 expect(transpile).not.toThrowError(RangeError);
             }
@@ -28,17 +28,17 @@ export function testKeywords(keywords: KeywordDict,language: string) {
     }
 }
 
-export function testProperties(properties: PropertyDict, language : string) {
+export function testProperties(properties: PropertyDict, language: string) {
     for (const name in properties) {
         const p = properties[name];
         p['@examples'].forEach(example => {
             it(name, () => {
                 if (!p.isUnsupported) {
-                    const expr = parse(language,example);
+                    const expr = parse(language, example);
 		    expect(expr).toBe(p);
-//                    compile(expr);
+                    //                    compile(expr);
                 } else {
-                    const transpile = () => parse(language,example);
+                    const transpile = () => parse(language, example);
                     expect(transpile).toThrow();
                     expect(transpile).not.toThrowError(RangeError);
                 }
@@ -52,15 +52,15 @@ export function testProperties(properties: PropertyDict, language : string) {
     }
 }
 
-export function testOperators(operators: OperatorList,language: string) {
+export function testOperators(operators: OperatorList, language: string) {
     operators.forEach(o => {
         o['@examples'].forEach(example => {
             it(o.name, () => {
                 if (!o.isUnsupported) {
-                    const expr = parse(language,example);
+                    const expr = parse(language, example);
 		    expect(expr).toBe(o);
                 } else {
-                    const transpile = () => parse(language,example);
+                    const transpile = () => parse(language, example);
                     expect(transpile).toThrow();
                     expect(transpile).not.toThrowError(RangeError);
                 }
diff --git a/src/mol-script/transpilers/_spec/vmd.spec.ts b/src/mol-script/transpilers/_spec/vmd.spec.ts
index 9b9d8557a28aea1bc55d28229d12ce250cf6d78c..efd6fd302dff959446f8eb5b4f6933ca42c1e2a8 100644
--- a/src/mol-script/transpilers/_spec/vmd.spec.ts
+++ b/src/mol-script/transpilers/_spec/vmd.spec.ts
@@ -7,14 +7,14 @@
  */
 
 import * as u from './utils';
-//import { transpiler } from '../vmd/parser';
+// import { transpiler } from '../vmd/parser';
 import { parse } from '../../transpile';
 import { keywords } from '../vmd/keywords';
 import { properties } from '../vmd/properties';
 import { operators } from '../vmd/operators';
 
 /* FAULTY IMPORTS */
-//import compile from '../../compiler';
+// import compile from '../../compiler';
 
 const general = {
     supported: [
@@ -46,19 +46,19 @@ const general = {
 describe('vmd general', () => {
     general.supported.forEach(str => {
         it(str, () => {
-            const expr = parse("vmd",str);
+            const expr = parse('vmd', str);
             expect(expr).toThrow();
         });
     });
     general.unsupported.forEach(str => {
         it(str, () => {
-            const transpileStr = () => parse("vmd",str);
+            const transpileStr = () => parse('vmd', str);
             expect(transpileStr).toThrow();
             expect(transpileStr).not.toThrowError(RangeError);
         });
     });
 });
 
-describe('vmd keywords', () => u.testKeywords(keywords, "vmd"));
-describe('vmd operators', () => u.testOperators(operators, "vmd"));
-describe('vmd properties', () => u.testProperties(properties, "vmd"));
+describe('vmd keywords', () => u.testKeywords(keywords, 'vmd'));
+describe('vmd operators', () => u.testOperators(operators, 'vmd'));
+describe('vmd properties', () => u.testProperties(properties, 'vmd'));
diff --git a/src/mol-script/transpilers/all.ts b/src/mol-script/transpilers/all.ts
index 1af141305a748ab7895f19a0690a4ebf9ee75f46..67e32483d6eb64f070e30a7ced2bce00c2ad41a8 100644
--- a/src/mol-script/transpilers/all.ts
+++ b/src/mol-script/transpilers/all.ts
@@ -1,19 +1,19 @@
- /*
+/*
  * Copyright (c) 2017 MolQL contributors, licensed under MIT, See LICENSE file for more info.
  *
  * @author David Sehnal <david.sehnal@gmail.com>
  */
 
-import jmol from './jmol/parser'
-//import json from './json/parser'
-//import molQLscript from './molql-script/parser'
-import pymol from './pymol/parser'
-import vmd from './vmd/parser'
-import rasmol from './rasmol/parser'
+import { transpiler as jmol } from './jmol/parser';
+// import json from './json/parser'
+// import molQLscript from './molql-script/parser'
+import { transpiler as pymol } from './pymol/parser';
+import { transpiler as vmd } from './vmd/parser';
+import { transpiler as rasmol } from './rasmol/parser';
 
-export default {
+export const _transpiler = {
     pymol,
     vmd,
     jmol,
     rasmol
-}
+};
diff --git a/src/mol-script/transpilers/helper.ts b/src/mol-script/transpilers/helper.ts
index de6a0726791e45cf12cc94784c63e924bfe9afcf..d799f64b0097ea1dfeafb20e1c5c0cdade4e3a2b 100644
--- a/src/mol-script/transpilers/helper.ts
+++ b/src/mol-script/transpilers/helper.ts
@@ -4,7 +4,7 @@
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
  * @author Panagiotis Tourlas <panagiot_tourlov@hotmail.com>
  */
-//import * as Q from 'parsimmon';
+// import * as Q from 'parsimmon';
 import * as P from '../../mol-util/monadic-parser';
 import { MolScriptBuilder } from '../../mol-script/language/builder';
 const B = MolScriptBuilder;
@@ -47,11 +47,11 @@ export function postfix(opParser: P.MonadicParser<any>, nextParser: P.MonadicPar
     // INPUT  :: "4!!!"
     // PARSE  :: [4, "factorial", "factorial", "factorial"]
     // REDUCE :: ["factorial", ["factorial", ["factorial", 4]]]
-    return P.MonadicParser.seqMap( /* no seqMap() in monadic-parser.ts, any suitable replacement? */
+    return P.MonadicParser.seqMap(/* no seqMap() in monadic-parser.ts, any suitable replacement? */
         nextParser,
         opParser.many(),
-        (x:any, suffixes:any) =>
-            suffixes.reduce((acc:any, x:any) => {
+        (x: any, suffixes: any) =>
+            suffixes.reduce((acc: any, x: any) => {
                 return mapFn(x, acc);
             }, x)
     );
@@ -95,9 +95,9 @@ export function binaryLeft(opParser: P.MonadicParser<any>, nextParser: P.Monadic
     return P.MonadicParser.seqMap(
         nextParser,
         P.MonadicParser.seq(opParser, nextParser).many(),
-        (first:any, rest:any) => {
-            return rest.reduce((acc:any, ch:any) => {
-                let [op, another] = ch;
+        (first: any, rest: any) => {
+            return rest.reduce((acc: any, ch: any) => {
+                const [op, another] = ch;
                 return mapFn(op, acc, another);
             }, first);
         }
@@ -216,7 +216,7 @@ export function getPropertyRules(properties: PropertyDict) {
     Object.keys(properties).sort(strLenSortFn).forEach(name => {
         const ps = properties[name];
         const errorFn = makeError(`property '${name}' not supported`);
-        const rule = P.MonadicParser.regexp(ps.regex).map((x:any) => {
+        const rule = P.MonadicParser.regexp(ps.regex).map((x: any) => {
             if (ps.isUnsupported) errorFn();
             return testExpr(ps.property, ps.map(x));
         });
@@ -235,7 +235,7 @@ export function getNamedPropertyRules(properties: PropertyDict) {
     Object.keys(properties).sort(strLenSortFn).forEach(name => {
         const ps = properties[name];
         const errorFn = makeError(`property '${name}' not supported`);
-        const rule = P.MonadicParser.regexp(ps.regex).map((x:any) => {
+        const rule = P.MonadicParser.regexp(ps.regex).map((x: any) => {
             if (ps.isUnsupported) errorFn();
             return testExpr(ps.property, ps.map(x));
         });
@@ -247,7 +247,7 @@ export function getNamedPropertyRules(properties: PropertyDict) {
                 nameRule.then(P.MonadicParser.seq(
                     P.MonadicParser.regexp(/>=|<=|=|!=|>|</).trim(P.MonadicParser.optWhitespace),
                     P.MonadicParser.regexp(ps.regex).map(ps.map)
-                )).map((x:any) => {
+                )).map((x: any) => {
                     if (ps.isUnsupported) errorFn();
                     return testExpr(ps.property, { op: x[0], val: x[1] });
                 }).map(groupMap)
@@ -288,10 +288,10 @@ export function getFunctionRules(functions: FunctionDict, argRule: P.MonadicPars
     return functionsList;
 }
 
-//const rule = P.regex(getNamesRegex(name, ps.abbr)).lookahead(lookahead).map(() => {
+// const rule = P.regex(getNamesRegex(name, ps.abbr)).lookahead(lookahead).map(() => {
 //    if (ps.isUnsupported) errorFn()
 //    return ps.property
-//})
+// })
 
 export function getPropertyNameRules(properties: PropertyDict, lookahead: RegExp) {
     const list: P.MonadicParser<any>[] = [];
@@ -357,7 +357,7 @@ const entityProps = ['entityKey', 'label_entity_id', 'entityType'];
 const chainProps = ['chainKey', 'label_asym_id', 'label_entity_id', 'auth_asym_id', 'entityType'];
 const residueProps = ['residueKey', 'label_comp_id', 'label_seq_id', 'auth_comp_id', 'auth_seq_id', 'pdbx_formal_charge', 'secondaryStructureKey', 'secondaryStructureFlags', 'isModified', 'modifiedParentName'];
 export function testLevel(property: any) {
-   if (property.head.startsWith(propPrefix)) {
+    if (property.head.startsWith(propPrefix)) {
         const name = property.head.substr(propPrefix.length);
         if (entityProps.indexOf(name) !== -1) return 'entity-test' as string;
         if (chainProps.indexOf(name) !== -1) return 'chain-test' as string;
diff --git a/src/mol-script/transpilers/jmol/examples.ts b/src/mol-script/transpilers/jmol/examples.ts
index d1169426baca6c6911dacf24c7dd05f52564811e..25106ef0bf68740f52c95539326a46d4c063110d 100644
--- a/src/mol-script/transpilers/jmol/examples.ts
+++ b/src/mol-script/transpilers/jmol/examples.ts
@@ -5,7 +5,7 @@
  * @author David Sehnal <david.sehnal@gmail.com>
  */
 
-export default [{
+export const jmolSelectionsExamples = [{
     name: 'Residue 50 or 135',
     value: '50 or 135'
 }, {
@@ -23,4 +23,4 @@ export default [{
 }, {
     name: 'Pyrimidine residues',
     value: 'pyrimidine'
-}]
\ No newline at end of file
+}];
diff --git a/src/mol-script/transpilers/jmol/keywords.ts b/src/mol-script/transpilers/jmol/keywords.ts
index 6445b917db050e6c8e88b439d9e212426cf6c600..186b149dbee2fed2c0018f56abac032eaed17d42 100644
--- a/src/mol-script/transpilers/jmol/keywords.ts
+++ b/src/mol-script/transpilers/jmol/keywords.ts
@@ -1,5 +1,5 @@
-/**                                                                                                                                        
- * Copyright (c) 2017-2021 mol* contributors, licensed under MIT, See LICENSE file for more info.                                           
+/**
+ * Copyright (c) 2017-2021 mol* contributors, licensed under MIT, See LICENSE file for more info.
  * @author Alexander Rose <alexander.rose@weirdbyte.de>                                                                                      * @author Panagiotis Tourlas <panagiot_tourlov@hotmail.com>                                                                                 *
  * @author Koya Sakuma                                                                                                                       * This module was taken from MolQL and modified in similar manner as pymol and vmd tranpilers.
 **/
@@ -12,504 +12,504 @@ import { KeywordDict } from '../types';
 
 
 function nucleicExpr() {
-  return B.struct.combinator.merge([
-    B.struct.generator.atomGroups({
-      'residue-test': B.core.set.has([
-        B.set(...['G', 'C', 'A', 'T', 'U', 'I', 'DG', 'DC', 'DA', 'DT', 'DU', 'DI', '+G', '+C', '+A', '+T', '+U', '+I']),
-        B.ammp('label_comp_id')
-      ])
-    }),
-    B.struct.filter.pick({
-      0: B.struct.generator.atomGroups({
-        'group-by': B.ammp('residueKey')
-      }),
-      test: B.core.logic.and([
-        B.core.rel.eq([ B.struct.atomSet.atomCount(), 1 ]),
-        B.core.rel.eq([ B.ammp('label_atom_id'), B.atomName('P') ]),
-      ])
-    }),
-    B.struct.filter.pick({
-      0: B.struct.generator.atomGroups({
-        'group-by': B.ammp('residueKey')
-      }),
-      test: B.core.logic.or([
-        B.core.set.isSubset([
-          h.atomNameSet([ "C1'", "C2'", "O3'", "C3'", "C4'", "C5'", "O5'" ]),
-          B.ammpSet('label_atom_id')
-        ]),
-        B.core.set.isSubset([
-          h.atomNameSet([ 'C1*', 'C2*', 'O3*', 'C3*', 'C4*', 'C5*', 'O5*' ]),
-          B.ammpSet('label_atom_id')
-        ])
-      ])
-    })
-  ])
+    return B.struct.combinator.merge([
+        B.struct.generator.atomGroups({
+            'residue-test': B.core.set.has([
+                B.set(...['G', 'C', 'A', 'T', 'U', 'I', 'DG', 'DC', 'DA', 'DT', 'DU', 'DI', '+G', '+C', '+A', '+T', '+U', '+I']),
+                B.ammp('label_comp_id')
+            ])
+        }),
+        B.struct.filter.pick({
+            0: B.struct.generator.atomGroups({
+                'group-by': B.ammp('residueKey')
+            }),
+            test: B.core.logic.and([
+                B.core.rel.eq([B.struct.atomSet.atomCount(), 1]),
+                B.core.rel.eq([B.ammp('label_atom_id'), B.atomName('P')]),
+            ])
+        }),
+        B.struct.filter.pick({
+            0: B.struct.generator.atomGroups({
+                'group-by': B.ammp('residueKey')
+            }),
+            test: B.core.logic.or([
+                B.core.set.isSubset([
+                    h.atomNameSet(["C1'", "C2'", "O3'", "C3'", "C4'", "C5'", "O5'"]),
+                    B.ammpSet('label_atom_id')
+                ]),
+                B.core.set.isSubset([
+                    h.atomNameSet(['C1*', 'C2*', 'O3*', 'C3*', 'C4*', 'C5*', 'O5*']),
+                    B.ammpSet('label_atom_id')
+                ])
+            ])
+        })
+    ]);
 }
 
 const ResDict = {
-  acidic: ['ASP', 'GLU'],
-  aliphatic: ['ALA', 'GLY', 'ILE', 'LEU', 'VAL'],
-  amino: ['ALA', 'ARG', 'ASN', 'ASP', 'CYS', 'GLN', 'GLU', 'GLY', 'HIS', 'ILE', 'LEU', 'LYS', 'MET', 'PHE', 'PRO', 'SER', 'THR', 'TRP', 'TYR', 'VAL', 'ASX', 'GLX', 'UNK', ],
-  aromatic: ['HIS', 'PHE', 'TRP', 'TYR'],
-  basic: ['ARG', 'HIS', 'LYS'],
-  buried: ['ALA','CYS', 'ILE', 'LEU', 'MET', 'PHE', 'TRP', 'VAL'],
-  cg: ['CYT', 'C', 'GUA', 'G'],
-  cyclic: ['HIS', 'PHE', 'PRO', 'TRP', 'TYR'],
-  hydrophobic: ['ALA', 'GLY', 'ILE', 'LEU', 'MET', 'PHE', 'PRO', 'TRP', 'TYR', 'VAL'],
-  large: ['ARG', 'GLU', 'GLN', 'HIS', 'ILE', 'LEU', 'LYS', 'MET', 'PHE', 'TRP', 'TYR'],
-  medium: ['ASN', 'ASP', 'CYS', 'PRO', 'THR', 'VAL'],
-  small: ['ALA', 'GLY', 'SER'],
-}
+    acidic: ['ASP', 'GLU'],
+    aliphatic: ['ALA', 'GLY', 'ILE', 'LEU', 'VAL'],
+    amino: ['ALA', 'ARG', 'ASN', 'ASP', 'CYS', 'GLN', 'GLU', 'GLY', 'HIS', 'ILE', 'LEU', 'LYS', 'MET', 'PHE', 'PRO', 'SER', 'THR', 'TRP', 'TYR', 'VAL', 'ASX', 'GLX', 'UNK'],
+    aromatic: ['HIS', 'PHE', 'TRP', 'TYR'],
+    basic: ['ARG', 'HIS', 'LYS'],
+    buried: ['ALA', 'CYS', 'ILE', 'LEU', 'MET', 'PHE', 'TRP', 'VAL'],
+    cg: ['CYT', 'C', 'GUA', 'G'],
+    cyclic: ['HIS', 'PHE', 'PRO', 'TRP', 'TYR'],
+    hydrophobic: ['ALA', 'GLY', 'ILE', 'LEU', 'MET', 'PHE', 'PRO', 'TRP', 'TYR', 'VAL'],
+    large: ['ARG', 'GLU', 'GLN', 'HIS', 'ILE', 'LEU', 'LYS', 'MET', 'PHE', 'TRP', 'TYR'],
+    medium: ['ASN', 'ASP', 'CYS', 'PRO', 'THR', 'VAL'],
+    small: ['ALA', 'GLY', 'SER'],
+};
 
 export const keywords: KeywordDict = {
-  // general terms
-  all: {
-    '@desc': 'all atoms; same as *',
-    abbr: ['*'],
-    map: () => B.struct.generator.all()
-  },
-  bonded: {
-    '@desc': 'covalently bonded',
-    map: () => B.struct.generator.atomGroups({
-      'atom-test': B.core.rel.gr([B.struct.atomProperty.core.bondCount({
-        flags: B.struct.type.bondFlags(['covalent', 'metallic', 'sulfide'])
-      }), 0])
-    })
-  },
-  clickable: {
-    '@desc': 'actually visible -- having some visible aspect such as wireframe, spacefill, or a label showing, or the alpha-carbon or phosphorus atom in a biomolecule that is rendered with only cartoon, rocket, or other biomolecule-specific shape.'
-  },
-  connected: {
-    '@desc': 'bonded in any way, including hydrogen bonds',
-    map: () => B.struct.generator.atomGroups({
-      'atom-test': B.core.rel.gr([B.struct.atomProperty.core.bondCount({
-        flags: B.struct.type.bondFlags()
-      }), 0])
-    })
-  },
-  displayed: {
-    '@desc': 'displayed using the display or hide command; not necessarily visible'
-  },
-  hidden: {
-    '@desc': 'hidden using the display or hide command'
-  },
-  none: {
-    '@desc': 'no atoms',
-    map: () => B.struct.generator.empty()
-  },
-  selected: {
-    '@desc': 'atoms that have been selected; defaults to all when a file is first loaded'
-  },
-  thisModel: {
-    '@desc': 'atoms in the current frame set, as defined by frame, model, or animation commands. If more than one model is in this set, "thisModel" refers to all of them, regardless of atom displayed/hidden status.'
-  },
-  visible: {
-    '@desc': 'visible in any way, including PDB residue atoms for which a cartoon or other such rendering makes their group visible, even if they themselves are not visible.'
-  },
-  subset: {
-    '@desc': 'the currently defined subset. Note that if a subset is currently defined, then select/display all is the same as select/display subset, restrict none is the same as restrict not subset. In addition, select not subset selects nothing.'
-  },
-  specialPosition: {
-    '@desc': 'atoms in crystal structures that are at special positions - that is, for which there is more than one operator that leads to them.'
-  },
-  unitcell: {
-    '@desc': 'atoms within the current unitcell, which may be offset. This includes atoms on the faces and at the vertices of the unitcell.'
-  },
-  polyhedra: {
-    '@desc': 'all central atoms for which polyhedra have been created. See also polyhera(n), below. (Jmol 14.4)'
-  },
-  nonmetal: {
-    '@desc': '_H,_He,_B,_C,_N,_O,_F,_Ne,_Si,_P,_S,_Cl,_Ar,_As,_Se,_Br,_Kr,_Te,_I,_Xe,_At,_Rn',
-    map: () => B.struct.generator.atomGroups({
-      'atom-test': B.core.set.has([
-        B.set(...['H','He','B','C','N','O','F','Ne','Si','P','S','Cl','Ar','As','Se','Br','Kr','Te','I','Xe','At','Rn'].map(B.es)),
-        B.acp('elementSymbol')
-      ])
-    })
-  },
-  metal: {
-    '@desc': '!nonmetal',
-    map: () => B.struct.generator.atomGroups({
-      'atom-test': B.core.logic.not([
-        B.core.set.has([
-          B.set(...['H','He','B','C','N','O','F','Ne','Si','P','S','Cl','Ar','As','Se','Br','Kr','Te','I','Xe','At','Rn'].map(B.es)),
-          B.acp('elementSymbol')
-        ])
-      ])
-    })
-  },
-  alkaliMetal: {
-    '@desc': '_Li,_Na,_K,_Rb,_Cs,_Fr',
-    map: () => B.struct.generator.atomGroups({
-      'atom-test': B.core.set.has([
-        B.set(...['Li','Na','K','Rb','Cs','Fr'].map(B.es)),
-        B.acp('elementSymbol')
-      ])
-    })
-  },
-  alkalineEarth: {
-    '@desc': '_Be,_Mg,_Ca,_Sr,_Ba,_Ra',
-    map: () => B.struct.generator.atomGroups({
-      'atom-test': B.core.set.has([
-        B.set(...['Be','Mg','Ca','Sr','Ba','Ra'].map(B.es)),
-        B.acp('elementSymbol')
-      ])
-    })
-  },
-  nobleGas: {
-    '@desc': '_He,_Ne,_Ar,_Kr,_Xe,_Rn',
-    map: () => B.struct.generator.atomGroups({
-      'atom-test': B.core.set.has([
-        B.set(...['He','Ne','Ar','Kr','Xe','Rn'].map(B.es)),
-        B.acp('elementSymbol')
-      ])
-    })
-  },
-  metalloid: {
-    '@desc': '_B,_Si,_Ge,_As,_Sb,_Te',
-    map: () => B.struct.generator.atomGroups({
-      'atom-test': B.core.set.has([
-        B.set(...['B','Si','Ge','As','Sb','Te'].map(B.es)),
-        B.acp('elementSymbol')
-      ])
-    })
-  },
-  transitionMetal: {
-    '@desc': '(includes La and Ac) elemno>=21 and elemno<=30, elemno=57, elemno=89, elemno>=39 and elemno<=48, elemno>=72 and elemno<=80, elemno>=104 and elemno<=112',
-    map: () => B.struct.generator.atomGroups({
-      'atom-test': B.core.logic.or([
-        B.core.rel.inRange([B.acp('atomicNumber'), 21, 30]),
-        B.core.rel.inRange([B.acp('atomicNumber'), 39, 48]),
-        B.core.rel.inRange([B.acp('atomicNumber'), 72, 80]),
-        B.core.rel.inRange([B.acp('atomicNumber'), 104, 112]),
-        B.core.set.has([B.set(57, 89), B.acp('atomicNumber')])
-      ])
-    })
-  },
-  lanthanide: {
-    '@desc': '(does not include La) elemno>57 and elemno<=71',
-    map: () => B.struct.generator.atomGroups({
-      'atom-test': B.core.rel.inRange([B.acp('atomicNumber'), 57, 71])
-    })
-  },
-  actinide: {
-    '@desc': '(does not include Ac) elemno>89 and elemno<=103',
-    map: () => B.struct.generator.atomGroups({
-      'atom-test': B.core.rel.inRange([B.acp('atomicNumber'), 89, 103])
-    })
-  },
-  isaromatic: {
-    '@desc': 'atoms connected with the AROMATIC, AROMATICSINGLE, or AROMATICDOUBLE bond types',
-    map: () => B.struct.generator.atomGroups({
-      'atom-test': B.core.rel.gr([
-        B.struct.atomProperty.core.bondCount({
-          flags: B.struct.type.bondFlags(['aromatic'])
-        }),
-        0
-      ])
-    })
-  },
+    // general terms
+    all: {
+        '@desc': 'all atoms; same as *',
+        abbr: ['*'],
+        map: () => B.struct.generator.all()
+    },
+    bonded: {
+        '@desc': 'covalently bonded',
+        map: () => B.struct.generator.atomGroups({
+            'atom-test': B.core.rel.gr([B.struct.atomProperty.core.bondCount({
+                flags: B.struct.type.bondFlags(['covalent', 'metallic', 'sulfide'])
+            }), 0])
+        })
+    },
+    clickable: {
+        '@desc': 'actually visible -- having some visible aspect such as wireframe, spacefill, or a label showing, or the alpha-carbon or phosphorus atom in a biomolecule that is rendered with only cartoon, rocket, or other biomolecule-specific shape.'
+    },
+    connected: {
+        '@desc': 'bonded in any way, including hydrogen bonds',
+        map: () => B.struct.generator.atomGroups({
+            'atom-test': B.core.rel.gr([B.struct.atomProperty.core.bondCount({
+                flags: B.struct.type.bondFlags()
+            }), 0])
+        })
+    },
+    displayed: {
+        '@desc': 'displayed using the display or hide command; not necessarily visible'
+    },
+    hidden: {
+        '@desc': 'hidden using the display or hide command'
+    },
+    none: {
+        '@desc': 'no atoms',
+        map: () => B.struct.generator.empty()
+    },
+    selected: {
+        '@desc': 'atoms that have been selected; defaults to all when a file is first loaded'
+    },
+    thisModel: {
+        '@desc': 'atoms in the current frame set, as defined by frame, model, or animation commands. If more than one model is in this set, "thisModel" refers to all of them, regardless of atom displayed/hidden status.'
+    },
+    visible: {
+        '@desc': 'visible in any way, including PDB residue atoms for which a cartoon or other such rendering makes their group visible, even if they themselves are not visible.'
+    },
+    subset: {
+        '@desc': 'the currently defined subset. Note that if a subset is currently defined, then select/display all is the same as select/display subset, restrict none is the same as restrict not subset. In addition, select not subset selects nothing.'
+    },
+    specialPosition: {
+        '@desc': 'atoms in crystal structures that are at special positions - that is, for which there is more than one operator that leads to them.'
+    },
+    unitcell: {
+        '@desc': 'atoms within the current unitcell, which may be offset. This includes atoms on the faces and at the vertices of the unitcell.'
+    },
+    polyhedra: {
+        '@desc': 'all central atoms for which polyhedra have been created. See also polyhera(n), below. (Jmol 14.4)'
+    },
+    nonmetal: {
+        '@desc': '_H,_He,_B,_C,_N,_O,_F,_Ne,_Si,_P,_S,_Cl,_Ar,_As,_Se,_Br,_Kr,_Te,_I,_Xe,_At,_Rn',
+        map: () => B.struct.generator.atomGroups({
+            'atom-test': B.core.set.has([
+                B.set(...['H', 'He', 'B', 'C', 'N', 'O', 'F', 'Ne', 'Si', 'P', 'S', 'Cl', 'Ar', 'As', 'Se', 'Br', 'Kr', 'Te', 'I', 'Xe', 'At', 'Rn'].map(B.es)),
+                B.acp('elementSymbol')
+            ])
+        })
+    },
+    metal: {
+        '@desc': '!nonmetal',
+        map: () => B.struct.generator.atomGroups({
+            'atom-test': B.core.logic.not([
+                B.core.set.has([
+                    B.set(...['H', 'He', 'B', 'C', 'N', 'O', 'F', 'Ne', 'Si', 'P', 'S', 'Cl', 'Ar', 'As', 'Se', 'Br', 'Kr', 'Te', 'I', 'Xe', 'At', 'Rn'].map(B.es)),
+                    B.acp('elementSymbol')
+                ])
+            ])
+        })
+    },
+    alkaliMetal: {
+        '@desc': '_Li,_Na,_K,_Rb,_Cs,_Fr',
+        map: () => B.struct.generator.atomGroups({
+            'atom-test': B.core.set.has([
+                B.set(...['Li', 'Na', 'K', 'Rb', 'Cs', 'Fr'].map(B.es)),
+                B.acp('elementSymbol')
+            ])
+        })
+    },
+    alkalineEarth: {
+        '@desc': '_Be,_Mg,_Ca,_Sr,_Ba,_Ra',
+        map: () => B.struct.generator.atomGroups({
+            'atom-test': B.core.set.has([
+                B.set(...['Be', 'Mg', 'Ca', 'Sr', 'Ba', 'Ra'].map(B.es)),
+                B.acp('elementSymbol')
+            ])
+        })
+    },
+    nobleGas: {
+        '@desc': '_He,_Ne,_Ar,_Kr,_Xe,_Rn',
+        map: () => B.struct.generator.atomGroups({
+            'atom-test': B.core.set.has([
+                B.set(...['He', 'Ne', 'Ar', 'Kr', 'Xe', 'Rn'].map(B.es)),
+                B.acp('elementSymbol')
+            ])
+        })
+    },
+    metalloid: {
+        '@desc': '_B,_Si,_Ge,_As,_Sb,_Te',
+        map: () => B.struct.generator.atomGroups({
+            'atom-test': B.core.set.has([
+                B.set(...['B', 'Si', 'Ge', 'As', 'Sb', 'Te'].map(B.es)),
+                B.acp('elementSymbol')
+            ])
+        })
+    },
+    transitionMetal: {
+        '@desc': '(includes La and Ac) elemno>=21 and elemno<=30, elemno=57, elemno=89, elemno>=39 and elemno<=48, elemno>=72 and elemno<=80, elemno>=104 and elemno<=112',
+        map: () => B.struct.generator.atomGroups({
+            'atom-test': B.core.logic.or([
+                B.core.rel.inRange([B.acp('atomicNumber'), 21, 30]),
+                B.core.rel.inRange([B.acp('atomicNumber'), 39, 48]),
+                B.core.rel.inRange([B.acp('atomicNumber'), 72, 80]),
+                B.core.rel.inRange([B.acp('atomicNumber'), 104, 112]),
+                B.core.set.has([B.set(57, 89), B.acp('atomicNumber')])
+            ])
+        })
+    },
+    lanthanide: {
+        '@desc': '(does not include La) elemno>57 and elemno<=71',
+        map: () => B.struct.generator.atomGroups({
+            'atom-test': B.core.rel.inRange([B.acp('atomicNumber'), 57, 71])
+        })
+    },
+    actinide: {
+        '@desc': '(does not include Ac) elemno>89 and elemno<=103',
+        map: () => B.struct.generator.atomGroups({
+            'atom-test': B.core.rel.inRange([B.acp('atomicNumber'), 89, 103])
+        })
+    },
+    isaromatic: {
+        '@desc': 'atoms connected with the AROMATIC, AROMATICSINGLE, or AROMATICDOUBLE bond types',
+        map: () => B.struct.generator.atomGroups({
+            'atom-test': B.core.rel.gr([
+                B.struct.atomProperty.core.bondCount({
+                    flags: B.struct.type.bondFlags(['aromatic'])
+                }),
+                0
+            ])
+        })
+    },
 
-  carbohydrate: {
-    '@desc': ''
-  },
-  ions: {
-    '@desc': '(specifically the PDB designations "PO4" and "SO4")'
-  },
-  ligand: {
-    '@desc': '(originally "hetero and not solvent"; changed to "!(protein,nucleic,water,UREA)" for Jmol 12.2)'
-  },
-  nucleic: {
-    '@desc': 'any group that (a) has one of the following group names: G, C, A, T, U, I, DG, DC, DA, DT, DU, DI, +G, +C, +A, +T, +U, +I; or (b) can be identified as a group that is only one atom, with name "P"; or (c) has all of the following atoms (prime, \', can replace * here): C1*, C2*, C3*, O3*, C4*, C5*, and O5*.',
-    map: () => nucleicExpr()
-  },
-  purine: {
-    '@desc': 'any nucleic group that (a) has one of the following group names: A, G, I, DA, DG, DI, +A, +G, or +I; or (b) also has atoms N7, C8, and N9.',
-    map: () => B.struct.modifier.intersectBy({
-      0: nucleicExpr(),
-      by: B.struct.combinator.merge([
-        B.struct.generator.atomGroups({
-          'residue-test': B.core.set.has([
-            B.set(...['A', 'G', 'I', 'DA', 'DG', 'DI', '+A', '+G', '+I']),
-            B.ammp('label_comp_id')
-          ])
-        }),
-        B.struct.filter.pick({
-          0: B.struct.generator.atomGroups({
-            'group-by': B.ammp('residueKey')
-          }),
-          test: B.core.set.isSubset([
-            h.atomNameSet([ 'N7', 'C8', 'N9' ]),
-            B.ammpSet('label_atom_id')
-          ])
+    carbohydrate: {
+        '@desc': ''
+    },
+    ions: {
+        '@desc': '(specifically the PDB designations "PO4" and "SO4")'
+    },
+    ligand: {
+        '@desc': '(originally "hetero and not solvent"; changed to "!(protein,nucleic,water,UREA)" for Jmol 12.2)'
+    },
+    nucleic: {
+        '@desc': 'any group that (a) has one of the following group names: G, C, A, T, U, I, DG, DC, DA, DT, DU, DI, +G, +C, +A, +T, +U, +I; or (b) can be identified as a group that is only one atom, with name "P"; or (c) has all of the following atoms (prime, \', can replace * here): C1*, C2*, C3*, O3*, C4*, C5*, and O5*.',
+        map: () => nucleicExpr()
+    },
+    purine: {
+        '@desc': 'any nucleic group that (a) has one of the following group names: A, G, I, DA, DG, DI, +A, +G, or +I; or (b) also has atoms N7, C8, and N9.',
+        map: () => B.struct.modifier.intersectBy({
+            0: nucleicExpr(),
+            by: B.struct.combinator.merge([
+                B.struct.generator.atomGroups({
+                    'residue-test': B.core.set.has([
+                        B.set(...['A', 'G', 'I', 'DA', 'DG', 'DI', '+A', '+G', '+I']),
+                        B.ammp('label_comp_id')
+                    ])
+                }),
+                B.struct.filter.pick({
+                    0: B.struct.generator.atomGroups({
+                        'group-by': B.ammp('residueKey')
+                    }),
+                    test: B.core.set.isSubset([
+                        h.atomNameSet(['N7', 'C8', 'N9']),
+                        B.ammpSet('label_atom_id')
+                    ])
+                })
+            ])
         })
-      ])
-    })
-  },
-  pyrimidine: {
-    '@desc': 'any nucleic group that (a) has one of the following group names: C, T, U, DC, DT, DU, +C, +T, +U; or (b) also has atom O2.',
-    map: () => B.struct.modifier.intersectBy({
-      0: nucleicExpr(),
-      by: B.struct.combinator.merge([
-        B.struct.generator.atomGroups({
-          'residue-test': B.core.set.has([
-            B.set(...['C', 'T', 'U', 'DC', 'DT', 'DU', '+C', '+T', '+U']),
-            B.ammp('label_comp_id')
-          ])
-        }),
-        B.struct.filter.pick({
-          0: B.struct.generator.atomGroups({
-            'group-by': B.ammp('residueKey')
-          }),
-          test: B.core.logic.or([
-            B.core.set.has([
-              B.ammpSet('label_atom_id'),
-              B.atomName('O2*')
-            ]),
-            B.core.set.has([
-              B.ammpSet('label_atom_id'),
-              B.atomName("O2'")
+    },
+    pyrimidine: {
+        '@desc': 'any nucleic group that (a) has one of the following group names: C, T, U, DC, DT, DU, +C, +T, +U; or (b) also has atom O2.',
+        map: () => B.struct.modifier.intersectBy({
+            0: nucleicExpr(),
+            by: B.struct.combinator.merge([
+                B.struct.generator.atomGroups({
+                    'residue-test': B.core.set.has([
+                        B.set(...['C', 'T', 'U', 'DC', 'DT', 'DU', '+C', '+T', '+U']),
+                        B.ammp('label_comp_id')
+                    ])
+                }),
+                B.struct.filter.pick({
+                    0: B.struct.generator.atomGroups({
+                        'group-by': B.ammp('residueKey')
+                    }),
+                    test: B.core.logic.or([
+                        B.core.set.has([
+                            B.ammpSet('label_atom_id'),
+                            B.atomName('O2*')
+                        ]),
+                        B.core.set.has([
+                            B.ammpSet('label_atom_id'),
+                            B.atomName("O2'")
+                        ])
+                    ])
+                })
             ])
-          ])
         })
-      ])
-    })
-  },
-  dna: {
-    '@desc': 'any nucleic group that (a) has one of the following group names: DG, DC, DA, DT, DU, DI, T, +G, +C, +A, +T; or (b) has neither atom O2* or O2\'.',
-    map: () => B.struct.modifier.intersectBy({
-      0: nucleicExpr(),
-      by: B.struct.combinator.merge([
-        B.struct.generator.atomGroups({
-          'residue-test': B.core.set.has([
-            B.set(...['DG', 'DC', 'DA', 'DT', 'DU', 'DI', 'T', '+G', '+C', '+A', '+T']),
-            B.ammp('label_comp_id')
-          ])
-        }),
-        B.struct.filter.pick({
-          0: B.struct.generator.atomGroups({
-            'group-by': B.ammp('residueKey')
-          }),
-          test: B.core.logic.not([
-            B.core.logic.or([
-              B.core.set.has([
-                B.ammpSet('label_atom_id'),
-                B.atomName('O2*')
-              ]),
-              B.core.set.has([
-                B.ammpSet('label_atom_id'),
-                B.atomName("O2'")
-              ])
+    },
+    dna: {
+        '@desc': 'any nucleic group that (a) has one of the following group names: DG, DC, DA, DT, DU, DI, T, +G, +C, +A, +T; or (b) has neither atom O2* or O2\'.',
+        map: () => B.struct.modifier.intersectBy({
+            0: nucleicExpr(),
+            by: B.struct.combinator.merge([
+                B.struct.generator.atomGroups({
+                    'residue-test': B.core.set.has([
+                        B.set(...['DG', 'DC', 'DA', 'DT', 'DU', 'DI', 'T', '+G', '+C', '+A', '+T']),
+                        B.ammp('label_comp_id')
+                    ])
+                }),
+                B.struct.filter.pick({
+                    0: B.struct.generator.atomGroups({
+                        'group-by': B.ammp('residueKey')
+                    }),
+                    test: B.core.logic.not([
+                        B.core.logic.or([
+                            B.core.set.has([
+                                B.ammpSet('label_atom_id'),
+                                B.atomName('O2*')
+                            ]),
+                            B.core.set.has([
+                                B.ammpSet('label_atom_id'),
+                                B.atomName("O2'")
+                            ])
+                        ])
+                    ])
+                })
             ])
-          ])
         })
-      ])
-    })
-  },
-  rna: {
-    '@desc': 'any nucleic group that (a) has one of the following group names: G, C, A, U, I, +U, +I; or (b) has atom O2* or O2\'.',
-    map: () => B.struct.modifier.intersectBy({
-      0: nucleicExpr(),
-      by: B.struct.combinator.merge([
-        B.struct.generator.atomGroups({
-          'residue-test': B.core.set.has([
-            B.set(...['G', 'C', 'A', 'U', 'I', '+U', '+I']),
-            B.ammp('label_comp_id')
-          ])
-        }),
-        B.struct.filter.pick({
-          0: B.struct.generator.atomGroups({
-            'group-by': B.ammp('residueKey')
-          }),
-          test: B.core.logic.or([
-            B.core.set.has([
-              B.ammpSet('label_atom_id'),
-              B.atomName('O2*')
-            ]),
-            B.core.set.has([
-              B.ammpSet('label_atom_id'),
-              B.atomName("O2'")
+    },
+    rna: {
+        '@desc': 'any nucleic group that (a) has one of the following group names: G, C, A, U, I, +U, +I; or (b) has atom O2* or O2\'.',
+        map: () => B.struct.modifier.intersectBy({
+            0: nucleicExpr(),
+            by: B.struct.combinator.merge([
+                B.struct.generator.atomGroups({
+                    'residue-test': B.core.set.has([
+                        B.set(...['G', 'C', 'A', 'U', 'I', '+U', '+I']),
+                        B.ammp('label_comp_id')
+                    ])
+                }),
+                B.struct.filter.pick({
+                    0: B.struct.generator.atomGroups({
+                        'group-by': B.ammp('residueKey')
+                    }),
+                    test: B.core.logic.or([
+                        B.core.set.has([
+                            B.ammpSet('label_atom_id'),
+                            B.atomName('O2*')
+                        ]),
+                        B.core.set.has([
+                            B.ammpSet('label_atom_id'),
+                            B.atomName("O2'")
+                        ])
+                    ])
+                })
             ])
-          ])
         })
-      ])
-    })
-  },
-  protein: {
-    '@desc': 'defined as a group that (a) has one of the following group names: ALA, ARG, ASN, ASP, CYS, GLN, GLU, GLY, HIS, ILE, LEU, LYS, MET, PHE, PRO, SER, THR, TRP, TYR, VAL, ASX, GLX, or UNK; or (b) contains PDB atom designations [C, O, CA, and N] bonded correctly; or (c) does not contain "O" but contains [C, CA, and N] bonded correctly; or (d) has only one atom, which has name CA and does not have the group name CA (indicating a calcium atom).'
-  },
-  acidic: {
-    '@desc': 'ASP GLU',
-    map: () => h.resnameExpr(ResDict.acidic)
-  },
-  acyclic: {
-    '@desc': 'amino and not cyclic',
-    map: () => B.struct.modifier.intersectBy({
-      0: h.resnameExpr(ResDict.amino),
-      by: h.invertExpr(h.resnameExpr(ResDict.cyclic))
-    })
-  },
-  aliphatic: {
-    '@desc': 'ALA GLY ILE LEU VAL',
-    map: () => h.resnameExpr(ResDict.aliphatic)
-  },
-  amino: {
-    '@desc': 'all twenty standard amino acids, plus ASX, GLX, UNK',
-    map: () => h.resnameExpr(ResDict.amino)
-  },
-  aromatic: {
-    '@desc': 'HIS PHE TRP TYR (see also "isaromatic" for aromatic bonds)',
-    map: () => h.resnameExpr(ResDict.aromatic)
-  },
-  basic: {
-    '@desc': 'ARG HIS LYS',
-    map: () => h.resnameExpr(ResDict.basic)
-  },
-  buried: {
-    '@desc': 'ALA CYS ILE LEU MET PHE TRP VAL',
-    map: () => h.resnameExpr(ResDict.buried)
-  },
-  charged: {
-    '@desc': 'same as acidic or basic -- ASP GLU, ARG HIS LYS',
-    map: () => h.resnameExpr(ResDict.acidic.concat(ResDict.basic))
-  },
-  cyclic: {
-    '@desc': 'HIS PHE PRO TRP TYR',
-    map: () => h.resnameExpr(ResDict.cyclic)
-  },
-  helix: {
-    '@desc': 'secondary structure-related.',
-    map: () => B.struct.generator.atomGroups({
-      'residue-test': B.core.flags.hasAny([
-        B.struct.type.secondaryStructureFlags(['helix']),
-        B.ammp('secondaryStructureFlags')
-      ])
-    })
-  },
-  helixalpha: {
-    '@desc': 'secondary structure-related.',
-    map: () => B.struct.generator.atomGroups({
-      'residue-test': B.core.flags.hasAny([
-        B.struct.type.secondaryStructureFlags(['alpha']),
-        B.ammp('secondaryStructureFlags')
-      ])
-    })
-  },
-  helix310: {
-    '@desc': 'secondary structure-related.',
-    map: () => B.struct.generator.atomGroups({
-      'residue-test': B.core.flags.hasAny([
-        B.struct.type.secondaryStructureFlags(['3-10']),
-        B.ammp('secondaryStructureFlags')
-      ])
-    })
-  },
-  helixpi: {
-    '@desc': 'secondary structure-related.',
-    map: () => B.struct.generator.atomGroups({
-      'residue-test': B.core.flags.hasAny([
-        B.struct.type.secondaryStructureFlags(['pi']),
-        B.ammp('secondaryStructureFlags')
-      ])
-    })
-  },
-  hetero: {
-    '@desc': 'PDB atoms designated as HETATM',
-    map: () => B.struct.generator.atomGroups({
-      'atom-test': B.ammp('isHet')
-    })
-  },
-  hydrophobic: {
-    '@desc': 'ALA GLY ILE LEU MET PHE PRO TRP TYR VAL',
-    map: () => h.resnameExpr(ResDict.hydrophobic)
-  },
-  large: {
-    '@desc': 'ARG GLU GLN HIS ILE LEU LYS MET PHE TRP TYR',
-    map: () => h.resnameExpr(ResDict.large)
-  },
-  medium: {
-    '@desc': 'ASN ASP CYS PRO THR VAL',
-    map: () => h.resnameExpr(ResDict.medium)
-  },
-  negative: {
-    '@desc': 'same as acidic -- ASP GLU',
-    map: () => h.resnameExpr(ResDict.acidic)
-  },
-  neutral: {
-    '@desc': 'amino and not (acidic or basic)',
-    map: () => B.struct.modifier.intersectBy({
-      0: h.resnameExpr(ResDict.amino),
-      by: h.invertExpr(h.resnameExpr(ResDict.acidic.concat(ResDict.basic)))
-    })
-  },
-  polar: {
-    '@desc': 'amino and not hydrophobic',
-    map: () => B.struct.modifier.intersectBy({
-      0: h.resnameExpr(ResDict.amino),
-      by: h.invertExpr(h.resnameExpr(ResDict.hydrophobic))
-    })
-  },
-  positive: {
-    '@desc': 'same as basic -- ARG HIS LYS',
-    map: () => h.resnameExpr(ResDict.basic)
-  },
-  sheet: {
-    '@desc': 'secondary structure-related',
-    map: () => B.struct.generator.atomGroups({
-      'residue-test': B.core.flags.hasAny([
-        B.struct.type.secondaryStructureFlags(['sheet']),
-        B.ammp('secondaryStructureFlags')
-      ])
-    })
-  },
-  small: {
-    '@desc': 'ALA GLY SER',
-    map: () => h.resnameExpr(ResDict.small)
-  },
-  surface: {
-    '@desc': 'amino and not buried',
-    map: () => B.struct.modifier.intersectBy({
-      0: h.resnameExpr(ResDict.amino),
-      by: h.invertExpr(h.resnameExpr(ResDict.buried))
-    })
-  },
-  turn: {
-    '@desc': 'secondary structure-related',
-    map: () => B.struct.generator.atomGroups({
-      'residue-test': B.core.flags.hasAny([
-        B.struct.type.secondaryStructureFlags(['turn']),
-        B.ammp('secondaryStructureFlags')
-      ])
-    })
-  },
-  alpha: {
-    '@desc': '(*.CA)',
-    map: () => B.struct.generator.atomGroups({
-      'atom-test': B.core.rel.eq([
-        B.atomName('CA'),
-        B.ammp('label_atom_id')
-      ])
-    })
-  },
-  base: {
-    '@desc': '(nucleic bases)'
-  },
-  backbone: {
-    '@desc': '(*.C, *.CA, *.N, and all nucleic other than the bases themselves)',
-    abbr: ['mainchain']
-  },
-  sidechain: {
-    '@desc': '((protein or nucleic) and not backbone)'
-  },
-  spine: {
-    '@desc': '(*.CA, *.N, *.C for proteins; *.P, *.O3\', *.O5\', *.C3\', *.C4\', *.C5 for nucleic acids)'
-  },
-  leadatom: {
-    '@desc': '(*.CA, *.P, and terminal *.O5\')'
-  },
-  solvent: {
-    '@desc': 'PDB "HOH", water, also the connected set of H-O-H in any model'
-  },
-}
+    },
+    protein: {
+        '@desc': 'defined as a group that (a) has one of the following group names: ALA, ARG, ASN, ASP, CYS, GLN, GLU, GLY, HIS, ILE, LEU, LYS, MET, PHE, PRO, SER, THR, TRP, TYR, VAL, ASX, GLX, or UNK; or (b) contains PDB atom designations [C, O, CA, and N] bonded correctly; or (c) does not contain "O" but contains [C, CA, and N] bonded correctly; or (d) has only one atom, which has name CA and does not have the group name CA (indicating a calcium atom).'
+    },
+    acidic: {
+        '@desc': 'ASP GLU',
+        map: () => h.resnameExpr(ResDict.acidic)
+    },
+    acyclic: {
+        '@desc': 'amino and not cyclic',
+        map: () => B.struct.modifier.intersectBy({
+            0: h.resnameExpr(ResDict.amino),
+            by: h.invertExpr(h.resnameExpr(ResDict.cyclic))
+        })
+    },
+    aliphatic: {
+        '@desc': 'ALA GLY ILE LEU VAL',
+        map: () => h.resnameExpr(ResDict.aliphatic)
+    },
+    amino: {
+        '@desc': 'all twenty standard amino acids, plus ASX, GLX, UNK',
+        map: () => h.resnameExpr(ResDict.amino)
+    },
+    aromatic: {
+        '@desc': 'HIS PHE TRP TYR (see also "isaromatic" for aromatic bonds)',
+        map: () => h.resnameExpr(ResDict.aromatic)
+    },
+    basic: {
+        '@desc': 'ARG HIS LYS',
+        map: () => h.resnameExpr(ResDict.basic)
+    },
+    buried: {
+        '@desc': 'ALA CYS ILE LEU MET PHE TRP VAL',
+        map: () => h.resnameExpr(ResDict.buried)
+    },
+    charged: {
+        '@desc': 'same as acidic or basic -- ASP GLU, ARG HIS LYS',
+        map: () => h.resnameExpr(ResDict.acidic.concat(ResDict.basic))
+    },
+    cyclic: {
+        '@desc': 'HIS PHE PRO TRP TYR',
+        map: () => h.resnameExpr(ResDict.cyclic)
+    },
+    helix: {
+        '@desc': 'secondary structure-related.',
+        map: () => B.struct.generator.atomGroups({
+            'residue-test': B.core.flags.hasAny([
+                B.struct.type.secondaryStructureFlags(['helix']),
+                B.ammp('secondaryStructureFlags')
+            ])
+        })
+    },
+    helixalpha: {
+        '@desc': 'secondary structure-related.',
+        map: () => B.struct.generator.atomGroups({
+            'residue-test': B.core.flags.hasAny([
+                B.struct.type.secondaryStructureFlags(['alpha']),
+                B.ammp('secondaryStructureFlags')
+            ])
+        })
+    },
+    helix310: {
+        '@desc': 'secondary structure-related.',
+        map: () => B.struct.generator.atomGroups({
+            'residue-test': B.core.flags.hasAny([
+                B.struct.type.secondaryStructureFlags(['3-10']),
+                B.ammp('secondaryStructureFlags')
+            ])
+        })
+    },
+    helixpi: {
+        '@desc': 'secondary structure-related.',
+        map: () => B.struct.generator.atomGroups({
+            'residue-test': B.core.flags.hasAny([
+                B.struct.type.secondaryStructureFlags(['pi']),
+                B.ammp('secondaryStructureFlags')
+            ])
+        })
+    },
+    hetero: {
+        '@desc': 'PDB atoms designated as HETATM',
+        map: () => B.struct.generator.atomGroups({
+            'atom-test': B.ammp('isHet')
+        })
+    },
+    hydrophobic: {
+        '@desc': 'ALA GLY ILE LEU MET PHE PRO TRP TYR VAL',
+        map: () => h.resnameExpr(ResDict.hydrophobic)
+    },
+    large: {
+        '@desc': 'ARG GLU GLN HIS ILE LEU LYS MET PHE TRP TYR',
+        map: () => h.resnameExpr(ResDict.large)
+    },
+    medium: {
+        '@desc': 'ASN ASP CYS PRO THR VAL',
+        map: () => h.resnameExpr(ResDict.medium)
+    },
+    negative: {
+        '@desc': 'same as acidic -- ASP GLU',
+        map: () => h.resnameExpr(ResDict.acidic)
+    },
+    neutral: {
+        '@desc': 'amino and not (acidic or basic)',
+        map: () => B.struct.modifier.intersectBy({
+            0: h.resnameExpr(ResDict.amino),
+            by: h.invertExpr(h.resnameExpr(ResDict.acidic.concat(ResDict.basic)))
+        })
+    },
+    polar: {
+        '@desc': 'amino and not hydrophobic',
+        map: () => B.struct.modifier.intersectBy({
+            0: h.resnameExpr(ResDict.amino),
+            by: h.invertExpr(h.resnameExpr(ResDict.hydrophobic))
+        })
+    },
+    positive: {
+        '@desc': 'same as basic -- ARG HIS LYS',
+        map: () => h.resnameExpr(ResDict.basic)
+    },
+    sheet: {
+        '@desc': 'secondary structure-related',
+        map: () => B.struct.generator.atomGroups({
+            'residue-test': B.core.flags.hasAny([
+                B.struct.type.secondaryStructureFlags(['sheet']),
+                B.ammp('secondaryStructureFlags')
+            ])
+        })
+    },
+    small: {
+        '@desc': 'ALA GLY SER',
+        map: () => h.resnameExpr(ResDict.small)
+    },
+    surface: {
+        '@desc': 'amino and not buried',
+        map: () => B.struct.modifier.intersectBy({
+            0: h.resnameExpr(ResDict.amino),
+            by: h.invertExpr(h.resnameExpr(ResDict.buried))
+        })
+    },
+    turn: {
+        '@desc': 'secondary structure-related',
+        map: () => B.struct.generator.atomGroups({
+            'residue-test': B.core.flags.hasAny([
+                B.struct.type.secondaryStructureFlags(['turn']),
+                B.ammp('secondaryStructureFlags')
+            ])
+        })
+    },
+    alpha: {
+        '@desc': '(*.CA)',
+        map: () => B.struct.generator.atomGroups({
+            'atom-test': B.core.rel.eq([
+                B.atomName('CA'),
+                B.ammp('label_atom_id')
+            ])
+        })
+    },
+    base: {
+        '@desc': '(nucleic bases)'
+    },
+    backbone: {
+        '@desc': '(*.C, *.CA, *.N, and all nucleic other than the bases themselves)',
+        abbr: ['mainchain']
+    },
+    sidechain: {
+        '@desc': '((protein or nucleic) and not backbone)'
+    },
+    spine: {
+        '@desc': '(*.CA, *.N, *.C for proteins; *.P, *.O3\', *.O5\', *.C3\', *.C4\', *.C5 for nucleic acids)'
+    },
+    leadatom: {
+        '@desc': '(*.CA, *.P, and terminal *.O5\')'
+    },
+    solvent: {
+        '@desc': 'PDB "HOH", water, also the connected set of H-O-H in any model'
+    },
+};
 
 
diff --git a/src/mol-script/transpilers/jmol/markdown-docs.ts b/src/mol-script/transpilers/jmol/markdown-docs.ts
index 825d55612a6b6bbbdb0a51a56988b09867178c08..d1b0222500b23ba5ffb8edb0596f94621d1ac752 100644
--- a/src/mol-script/transpilers/jmol/markdown-docs.ts
+++ b/src/mol-script/transpilers/jmol/markdown-docs.ts
@@ -1,9 +1,9 @@
-/* 
- * Copyright (c) 2017-2021 mol* contributors, licensed under MIT, See LICENSE file for more info.                                           
- * @author Alexander Rose <alexander.rose@weirdbyte.de>                                                                                     
- * @author Panagiotis Tourlas <panagiot_tourlov@hotmail.com> 
- * 
- * @author Koya Sakuma 
+/*
+ * Copyright (c) 2017-2021 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * @author Alexander Rose <alexander.rose@weirdbyte.de>
+ * @author Panagiotis Tourlas <panagiot_tourlov@hotmail.com>
+ *
+ * @author Koya Sakuma
  * This module was taken from MolQL and modified in similar manner as pymol and vmd tranpilers.                                             */
 
 import { properties } from './properties';
@@ -11,53 +11,53 @@ import { operators } from './operators';
 import { keywords } from './keywords';
 
 
-const docs: string[] = [
+const _docs: string[] = [
     'Jmol',
     '============',
     '--------------------------------',
     ''
 ];
 
-docs.push(`## Properties\n\n`);
-docs.push('--------------------------------\n');
+_docs.push(`## Properties\n\n`);
+_docs.push('--------------------------------\n');
 for (const name in properties) {
-    if (properties[name].isUnsupported) continue
+    if (properties[name].isUnsupported) continue;
 
-    const names = [name]
-    if (properties[name].abbr) names.push(...properties[name].abbr!)
-    docs.push(`\`\`\`\n${names.join(', ')}\n\`\`\`\n`);
+    const names = [name];
+    if (properties[name].abbr) names.push(...properties[name].abbr!);
+    _docs.push(`\`\`\`\n${names.join(', ')}\n\`\`\`\n`);
 
     if (properties[name]['@desc']) {
-        docs.push(`*${properties[name]['@desc']}*\n`);
+        _docs.push(`*${properties[name]['@desc']}*\n`);
     }
 }
 
-docs.push(`## Operators\n\n`);
-docs.push('--------------------------------\n');
+_docs.push(`## Operators\n\n`);
+_docs.push('--------------------------------\n');
 operators.forEach(o => {
-    if (o.isUnsupported) return
+    if (o.isUnsupported) return;
 
-    const names = [o.name]
-    if (o.abbr) names.push(...o.abbr!)
-    docs.push(`\`\`\`\n${names.join(', ')}\n\`\`\`\n`);
+    const names = [o.name];
+    if (o.abbr) names.push(...o.abbr!);
+    _docs.push(`\`\`\`\n${names.join(', ')}\n\`\`\`\n`);
 
     if (o['@desc']) {
-        docs.push(`*${o['@desc']}*\n`);
+        _docs.push(`*${o['@desc']}*\n`);
     }
-})
+});
 
-docs.push(`## Keywords\n\n`);
-docs.push('--------------------------------\n');
+_docs.push(`## Keywords\n\n`);
+_docs.push('--------------------------------\n');
 for (const name in keywords) {
-    if (!keywords[name].map) continue
+    if (!keywords[name].map) continue;
 
-    const names = [name]
-    if (keywords[name].abbr) names.push(...keywords[name].abbr!)
-    docs.push(`\`\`\`\n${names.join(', ')}\n\`\`\`\n`);
+    const names = [name];
+    if (keywords[name].abbr) names.push(...keywords[name].abbr!);
+    _docs.push(`\`\`\`\n${names.join(', ')}\n\`\`\`\n`);
 
     if (keywords[name]['@desc']) {
-        docs.push(`*${keywords[name]['@desc']}*\n`);
+        _docs.push(`*${keywords[name]['@desc']}*\n`);
     }
 }
 
-export default docs.join('\n')
+export const docs = _docs.join('\n');
diff --git a/src/mol-script/transpilers/jmol/operators.ts b/src/mol-script/transpilers/jmol/operators.ts
index d673daa8a9cbbcef9df5d05b80a0c30595fcaa88..cf0777504b252b79713074d806b85f619bf74458 100644
--- a/src/mol-script/transpilers/jmol/operators.ts
+++ b/src/mol-script/transpilers/jmol/operators.ts
@@ -1,9 +1,9 @@
-/*                                                                                                                                           
- * Copyright (c) 2017-2021 mol* contributors, licensed under MIT, See LICENSE file for more info.                                           
- * @author Alexander Rose <alexander.rose@weirdbyte.de>                                                                                     
- * @author Panagiotis Tourlas <panagiot_tourlov@hotmail.com>                                                                                 
- *                                                                                                                                           
- * @author Koya Sakuma                                                                                                                       
+/*
+ * Copyright (c) 2017-2021 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * @author Alexander Rose <alexander.rose@weirdbyte.de>
+ * @author Panagiotis Tourlas <panagiot_tourlov@hotmail.com>
+ *
+ * @author Koya Sakuma
  * This module was taken from MolQL and modified in similar manner as pymol and vmd tranpilers.                                             \
  */
 
@@ -13,33 +13,33 @@ import * as h from '../helper';
 import { MolScriptBuilder } from '../../../mol-script/language/builder';
 const B = MolScriptBuilder;
 import { OperatorList } from '../types';
-//import { Expression } from '../../language/expression';
+// import { Expression } from '../../language/expression';
 
 
 export const operators: OperatorList = [
-  {
-    '@desc': 'Selects atoms that are not included in s1.',
-    '@examples': ['not ARG'],
-    name: 'not',
-    type: h.prefix,
-    rule: P.MonadicParser.alt(P.MonadicParser.regex(/NOT/i).skip(P.MonadicParser.whitespace), P.MonadicParser.string('!').skip(P.MonadicParser.optWhitespace)),
-    map: (op, selection) => h.invertExpr(selection),
-  },
-  {
-    '@desc': 'Selects atoms included in both s1 and s2.',
-    '@examples': ['ASP and .CA'],
-    name: 'and',
-    type: h.binaryLeft,
-    rule: h.infixOp(/AND|&/i),
-    map: (op, selection, by) => B.struct.modifier.intersectBy({ 0: selection, by })
-  },
-  {
-    '@desc': 'Selects atoms included in either s1 or s2.',
-    '@examples': ['ASP or GLU'],
-    name: 'or',
-    type: h.binaryLeft,
-    rule: h.infixOp(/OR|\|/i),
-    map: (op, s1, s2) => B.struct.combinator.merge([s1, s2])
-  }
-]
+    {
+        '@desc': 'Selects atoms that are not included in s1.',
+        '@examples': ['not ARG'],
+        name: 'not',
+        type: h.prefix,
+        rule: P.MonadicParser.alt(P.MonadicParser.regex(/NOT/i).skip(P.MonadicParser.whitespace), P.MonadicParser.string('!').skip(P.MonadicParser.optWhitespace)),
+        map: (op, selection) => h.invertExpr(selection),
+    },
+    {
+        '@desc': 'Selects atoms included in both s1 and s2.',
+        '@examples': ['ASP and .CA'],
+        name: 'and',
+        type: h.binaryLeft,
+        rule: h.infixOp(/AND|&/i),
+        map: (op, selection, by) => B.struct.modifier.intersectBy({ 0: selection, by })
+    },
+    {
+        '@desc': 'Selects atoms included in either s1 or s2.',
+        '@examples': ['ASP or GLU'],
+        name: 'or',
+        type: h.binaryLeft,
+        rule: h.infixOp(/OR|\|/i),
+        map: (op, s1, s2) => B.struct.combinator.merge([s1, s2])
+    }
+];
 
diff --git a/src/mol-script/transpilers/jmol/parser.ts b/src/mol-script/transpilers/jmol/parser.ts
index b6cc60afefc9af626f882f634ea836bbc11209fb..1014c90d312bc7ff0864f041efb02886543a5bc8 100644
--- a/src/mol-script/transpilers/jmol/parser.ts
+++ b/src/mol-script/transpilers/jmol/parser.ts
@@ -1,8 +1,8 @@
 /**
- * Copyright (c) 2017-2021 mol* contributors, licensed under MIT, See LICENSE file for more info.                                           
+ * Copyright (c) 2017-2021 mol* contributors, licensed under MIT, See LICENSE file for more info.
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
- * @author Panagiotis Tourlas <panagiot_tourlov@hotmail.com>                                                                                
- *                                                                                                                                          
+ * @author Panagiotis Tourlas <panagiot_tourlov@hotmail.com>
+ *
  * @author Koya Sakuma
  * This module was taken from MolQL and modified in similar manner as pymol and vmd tranpilers.                                              **/
 
@@ -18,239 +18,238 @@ import { AtomGroupArgs } from '../types';
 import { Transpiler } from '../transpiler';
 import { OperatorList } from '../types';
 
-//const propertiesDict = h.getPropertyRules(properties);
+// const propertiesDict = h.getPropertyRules(properties);
 
-//const slash = P.MonadicParser.string('/');
+// const slash = P.MonadicParser.string('/');
 
 
 // <, <=, =, >=, >, !=, and LIKE
 const valueOperators: OperatorList = [
-  {
-    '@desc': 'value comparisons',
-    '@examples': [],
-    name: '=',
-    abbr: ['=='],
-    type: h.binaryLeft,
-    rule: P.MonadicParser.regexp(/\s*(LIKE|>=|<=|=|!=|>|<)\s*/i, 1),
-    map: (op, e1, e2) => {
-      // console.log(op, e1, e2)
-      let expr
-      if (e1 === 'structure') {
-        expr = B.core.flags.hasAny([B.ammp('secondaryStructureFlags'), structureMap(e2)])
-      } else if (e2 === 'structure') {
-        expr = B.core.flags.hasAny([B.ammp('secondaryStructureFlags'), structureMap(e1)])
-      } else if (e1.head === 'core.type.regex') {
-        expr = B.core.str.match([ e1, B.core.type.str([e2]) ])
-      } else if (e2.head === 'core.type.regex') {
-        expr = B.core.str.match([ e2, B.core.type.str([e1]) ])
-      } else if (op.toUpperCase() === 'LIKE') {
-        if (e1.head) {
-          expr = B.core.str.match([
-            B.core.type.regex([`^${e2}$`, 'i']),
-            B.core.type.str([e1])
-          ])
-        } else {
-          expr = B.core.str.match([
-            B.core.type.regex([`^${e1}$`, 'i']),
-            B.core.type.str([e2])
-          ])
+    {
+        '@desc': 'value comparisons',
+        '@examples': [],
+        name: '=',
+        abbr: ['=='],
+        type: h.binaryLeft,
+        rule: P.MonadicParser.regexp(/\s*(LIKE|>=|<=|=|!=|>|<)\s*/i, 1),
+        map: (op, e1, e2) => {
+            // console.log(op, e1, e2)
+            let expr;
+            if (e1 === 'structure') {
+                expr = B.core.flags.hasAny([B.ammp('secondaryStructureFlags'), structureMap(e2)]);
+            } else if (e2 === 'structure') {
+                expr = B.core.flags.hasAny([B.ammp('secondaryStructureFlags'), structureMap(e1)]);
+            } else if (e1.head === 'core.type.regex') {
+                expr = B.core.str.match([e1, B.core.type.str([e2])]);
+            } else if (e2.head === 'core.type.regex') {
+                expr = B.core.str.match([e2, B.core.type.str([e1])]);
+            } else if (op.toUpperCase() === 'LIKE') {
+                if (e1.head) {
+                    expr = B.core.str.match([
+                        B.core.type.regex([`^${e2}$`, 'i']),
+                        B.core.type.str([e1])
+                    ]);
+                } else {
+                    expr = B.core.str.match([
+                        B.core.type.regex([`^${e1}$`, 'i']),
+                        B.core.type.str([e2])
+                    ]);
+                }
+            }
+            if (!expr) {
+                if (e1.head) e2 = h.wrapValue(e1, e2);
+                if (e2.head) e1 = h.wrapValue(e2, e1);
+                switch (op) {
+                    case '=':
+                        expr = B.core.rel.eq([e1, e2]);
+                        break;
+                    case '!=':
+                        expr = B.core.rel.neq([e1, e2]);
+                        break;
+                    case '>':
+                        expr = B.core.rel.gr([e1, e2]);
+                        break;
+                    case '<':
+                        expr = B.core.rel.lt([e1, e2]);
+                        break;
+                    case '>=':
+                        expr = B.core.rel.gre([e1, e2]);
+                        break;
+                    case '<=':
+                        expr = B.core.rel.lte([e1, e2]);
+                        break;
+                    default: throw new Error(`value operator '${op}' not supported`);
+                }
+            }
+            return B.struct.generator.atomGroups({ 'atom-test': expr });
         }
-      }
-      if (!expr) {
-        if (e1.head) e2 = h.wrapValue(e1, e2)
-        if (e2.head) e1 = h.wrapValue(e2, e1)
-        switch (op) {
-          case '=':
-            expr = B.core.rel.eq([e1, e2])
-            break
-          case '!=':
-            expr = B.core.rel.neq([e1, e2])
-            break
-          case '>':
-            expr = B.core.rel.gr([e1, e2])
-            break
-          case '<':
-            expr = B.core.rel.lt([e1, e2])
-            break
-          case '>=':
-            expr = B.core.rel.gre([e1, e2])
-            break
-          case '<=':
-            expr = B.core.rel.lte([e1, e2])
-            break
-          default: throw new Error(`value operator '${op}' not supported`);
-        }
-      }
-      return B.struct.generator.atomGroups({ 'atom-test': expr })
     }
-  }
-]
+];
 
-function atomExpressionQuery (x: any[]) {
-  const [resno, inscode, chainname, atomname, altloc, ] = x[1]
-  const tests: AtomGroupArgs = {}
+function atomExpressionQuery(x: any[]) {
+    const [resno, inscode, chainname, atomname, altloc] = x[1];
+    const tests: AtomGroupArgs = {};
 
-  if (chainname) {
+    if (chainname) {
     // should be configurable, there is an option in Jmol to use auth or label
-    tests['chain-test'] = B.core.rel.eq([ B.ammp('auth_asym_id'), chainname ])
-  }
+        tests['chain-test'] = B.core.rel.eq([B.ammp('auth_asym_id'), chainname]);
+    }
 
-  const resProps = []
-  if (resno) resProps.push(B.core.rel.eq([ B.ammp('auth_seq_id'), resno ]))
-  if (inscode) resProps.push(B.core.rel.eq([ B.ammp('pdbx_PDB_ins_code'), inscode ]))
-  if (resProps.length) tests['residue-test'] = h.andExpr(resProps)
+    const resProps = [];
+    if (resno) resProps.push(B.core.rel.eq([B.ammp('auth_seq_id'), resno]));
+    if (inscode) resProps.push(B.core.rel.eq([B.ammp('pdbx_PDB_ins_code'), inscode]));
+    if (resProps.length) tests['residue-test'] = h.andExpr(resProps);
 
-  const atomProps = []
-  if (atomname) atomProps.push(B.core.rel.eq([ B.ammp('auth_atom_id'), atomname ]))
-  if (altloc) atomProps.push(B.core.rel.eq([ B.ammp('label_alt_id'), altloc ]))
-  if (atomProps.length) tests['atom-test'] = h.andExpr(atomProps)
+    const atomProps = [];
+    if (atomname) atomProps.push(B.core.rel.eq([B.ammp('auth_atom_id'), atomname]));
+    if (altloc) atomProps.push(B.core.rel.eq([B.ammp('label_alt_id'), altloc]));
+    if (atomProps.length) tests['atom-test'] = h.andExpr(atomProps);
 
-  return B.struct.generator.atomGroups(tests)
+    return B.struct.generator.atomGroups(tests);
 }
 
 const lang = P.MonadicParser.createLanguage({
-  Integer: () => P.MonadicParser.regexp(/-?[0-9]+/).map(Number).desc('integer'),
-
-    Parens: function (r:any) {
-    return P.MonadicParser.alt(
-      r.Parens,
-      r.Operator,
-      r.Expression
-    ).wrap(P.MonadicParser.string('('), P.MonadicParser.string(')'))
-  },
-
-    Expression: function(r:any) {
-    return P.MonadicParser.alt(
-      r.Keywords,
-
-	r.Resno.lookahead(P.MonadicParser.regexp(/\s*(?!(LIKE|>=|<=|!=|[:^%/.=><]))/i)).map((x:any) => B.struct.generator.atomGroups({
-          'residue-test': B.core.rel.eq([ B.ammp('auth_seq_id'), x ])
-      })),
-      r.AtomExpression.map(atomExpressionQuery),
-
-      r.ValueQuery,
-
-      r.Element.map((x: string) => B.struct.generator.atomGroups({
-        'atom-test': B.core.rel.eq([ B.acp('elementSymbol'), B.struct.type.elementSymbol(x) ])
-      })),
-      r.Resname.map((x: string) => B.struct.generator.atomGroups({
-        'residue-test': B.core.rel.eq([ B.ammp('label_comp_id'), x ])
-      })),
-    )
-  },
-
-Operator: function(r:any) {
-    return h.combineOperators(operators, P.MonadicParser.alt(r.Parens, r.Expression))
-  },
-
-AtomExpression: function(r:any) {
-    return P.MonadicParser.seq(
-      P.MonadicParser.lookahead(r.AtomPrefix),
-      P.MonadicParser.seq(
-        r.Resno.or(P.MonadicParser.of(null)),
-        r.Inscode.or(P.MonadicParser.of(null)),
-        r.Chainname.or(P.MonadicParser.of(null)),
-        r.Atomname.or(P.MonadicParser.of(null)),
-        r.Altloc.or(P.MonadicParser.of(null)),
-        r.Model.or(P.MonadicParser.of(null))
-      )
-    )
-  },
-
-  AtomPrefix: () => P.MonadicParser.regexp(/[0-9:^%/.]/).desc('atom-prefix'),
-
-  Chainname: () => P.MonadicParser.regexp(/:([A-Za-z]{1,3})/, 1).desc('chainname'),
-  Model: () => P.MonadicParser.regexp(/\/([0-9]+)/, 1).map(Number).desc('model'),
-  Element: () => P.MonadicParser.regexp(/_([A-Za-z]{1,3})/, 1).desc('element'),
-  Atomname: () => P.MonadicParser.regexp(/\.([a-zA-Z0-9]{1,4})/, 1).map(B.atomName).desc('atomname'),
-  Resname: () => P.MonadicParser.regexp(/[a-zA-Z0-9]{1,4}/).desc('resname'),
-Resno: (r:any) => r.Integer.desc('resno'),
-  Altloc: () => P.MonadicParser.regexp(/%([a-zA-Z0-9])/, 1).desc('altloc'),
-  Inscode: () => P.MonadicParser.regexp(/\^([a-zA-Z0-9])/, 1).desc('inscode'),
-
-  // BracketedResname: function (r) {
-  //   return P.MonadicParser.regexp(/\.([a-zA-Z0-9]{1,4})/, 1)
-  //     .desc('bracketed-resname')
-  //   // [0SD]
-  // },
-
-  // ResnoRange: function (r) {
-  //   return P.MonadicParser.regexp(/\.([\s]){1,3}/, 1)
-  //     .desc('resno-range')
-  //   // 123-200
-  //   // -12--3
-  // },
-
-  Keywords: () => P.MonadicParser.alt(...h.getKeywordRules(keywords)),
-
-Query: function(r:any) {
-    return P.MonadicParser.alt(
-      r.Operator,
-      r.Parens,
-      r.Expression
-    ).trim(P.MonadicParser.optWhitespace)
-  },
-
-  Number: function () {
-    return P.MonadicParser.regexp(/-?(0|[1-9][0-9]*)([.][0-9]+)?([eE][+-]?[0-9]+)?/)
-      .map(Number)
-      .desc('number')
-  },
-
-  String: function () {
-    const w = h.getReservedWords(properties, keywords, operators)
-      .sort(h.strLenSortFn).map(h.escapeRegExp).join('|')
-    return P.MonadicParser.alt(
-      P.MonadicParser.regexp(new RegExp(`(?!(${w}))[A-Z0-9_]+`, 'i')),
-      P.MonadicParser.regexp(/'((?:[^"\\]|\\.)*)'/, 1),
-      P.MonadicParser.regexp(/"((?:[^"\\]|\\.)*)"/, 1).map(x => B.core.type.regex([`^${x}$`, 'i']))
-    )
-  },
-
-Value: function (r:any) {
-    return P.MonadicParser.alt(r.Number, r.String)
-  },
-
-ValueParens: function (r:any) {
-    return P.MonadicParser.alt(
-      r.ValueParens,
-      r.ValueOperator,
-      r.ValueExpressions
-    ).wrap(P.MonadicParser.string('('), P.MonadicParser.string(')'))
-  },
-
-  ValuePropertyNames: function() {
-    return P.MonadicParser.alt(...h.getPropertyNameRules(properties, /LIKE|>=|<=|=|!=|>|<|\)|\s/i))
-  },
-
-ValueOperator: function(r:any) {
-    return h.combineOperators(valueOperators, P.MonadicParser.alt(r.ValueParens, r.ValueExpressions))
-  },
-
-ValueExpressions: function(r:any) {
-    return P.MonadicParser.alt(
-      r.Value,
-      r.ValuePropertyNames
-    )
-  },
-
-ValueQuery: function(r:any) {
-    return P.MonadicParser.alt(
-	r.ValueOperator.map((x:any) => {
-        if (x.head) {
-          if (x.head.startsWith('structure-query.generator')) return x
-        } else {
-          if (typeof x === 'string' && x.length <= 4) {
-            return B.struct.generator.atomGroups({
-              'residue-test': B.core.rel.eq([ B.ammp('label_comp_id'), x ])
+    Integer: () => P.MonadicParser.regexp(/-?[0-9]+/).map(Number).desc('integer'),
+
+    Parens: function (r: any) {
+        return P.MonadicParser.alt(
+            r.Parens,
+            r.Operator,
+            r.Expression
+        ).wrap(P.MonadicParser.string('('), P.MonadicParser.string(')'));
+    },
+
+    Expression: function (r: any) {
+        return P.MonadicParser.alt(
+            r.Keywords,
+
+            r.Resno.lookahead(P.MonadicParser.regexp(/\s*(?!(LIKE|>=|<=|!=|[:^%/.=><]))/i)).map((x: any) => B.struct.generator.atomGroups({
+                'residue-test': B.core.rel.eq([B.ammp('auth_seq_id'), x])
+            })),
+            r.AtomExpression.map(atomExpressionQuery),
+
+            r.ValueQuery,
+
+            r.Element.map((x: string) => B.struct.generator.atomGroups({
+                'atom-test': B.core.rel.eq([B.acp('elementSymbol'), B.struct.type.elementSymbol(x)])
+            })),
+            r.Resname.map((x: string) => B.struct.generator.atomGroups({
+                'residue-test': B.core.rel.eq([B.ammp('label_comp_id'), x])
+            })),
+        );
+    },
+
+    Operator: function (r: any) {
+        return h.combineOperators(operators, P.MonadicParser.alt(r.Parens, r.Expression));
+    },
+
+    AtomExpression: function (r: any) {
+        return P.MonadicParser.seq(
+            P.MonadicParser.lookahead(r.AtomPrefix),
+            P.MonadicParser.seq(
+                r.Resno.or(P.MonadicParser.of(null)),
+                r.Inscode.or(P.MonadicParser.of(null)),
+                r.Chainname.or(P.MonadicParser.of(null)),
+                r.Atomname.or(P.MonadicParser.of(null)),
+                r.Altloc.or(P.MonadicParser.of(null)),
+                r.Model.or(P.MonadicParser.of(null))
+            )
+        );
+    },
+
+    AtomPrefix: () => P.MonadicParser.regexp(/[0-9:^%/.]/).desc('atom-prefix'),
+
+    Chainname: () => P.MonadicParser.regexp(/:([A-Za-z]{1,3})/, 1).desc('chainname'),
+    Model: () => P.MonadicParser.regexp(/\/([0-9]+)/, 1).map(Number).desc('model'),
+    Element: () => P.MonadicParser.regexp(/_([A-Za-z]{1,3})/, 1).desc('element'),
+    Atomname: () => P.MonadicParser.regexp(/\.([a-zA-Z0-9]{1,4})/, 1).map(B.atomName).desc('atomname'),
+    Resname: () => P.MonadicParser.regexp(/[a-zA-Z0-9]{1,4}/).desc('resname'),
+    Resno: (r: any) => r.Integer.desc('resno'),
+    Altloc: () => P.MonadicParser.regexp(/%([a-zA-Z0-9])/, 1).desc('altloc'),
+    Inscode: () => P.MonadicParser.regexp(/\^([a-zA-Z0-9])/, 1).desc('inscode'),
+
+    // BracketedResname: function (r) {
+    //   return P.MonadicParser.regexp(/\.([a-zA-Z0-9]{1,4})/, 1)
+    //     .desc('bracketed-resname')
+    //   // [0SD]
+    // },
+
+    // ResnoRange: function (r) {
+    //   return P.MonadicParser.regexp(/\.([\s]){1,3}/, 1)
+    //     .desc('resno-range')
+    //   // 123-200
+    //   // -12--3
+    // },
+
+    Keywords: () => P.MonadicParser.alt(...h.getKeywordRules(keywords)),
+
+    Query: function (r: any) {
+        return P.MonadicParser.alt(
+            r.Operator,
+            r.Parens,
+            r.Expression
+        ).trim(P.MonadicParser.optWhitespace);
+    },
+
+    Number: function () {
+        return P.MonadicParser.regexp(/-?(0|[1-9][0-9]*)([.][0-9]+)?([eE][+-]?[0-9]+)?/)
+            .map(Number)
+            .desc('number');
+    },
+
+    String: function () {
+        const w = h.getReservedWords(properties, keywords, operators)
+            .sort(h.strLenSortFn).map(h.escapeRegExp).join('|');
+        return P.MonadicParser.alt(
+            P.MonadicParser.regexp(new RegExp(`(?!(${w}))[A-Z0-9_]+`, 'i')),
+            P.MonadicParser.regexp(/'((?:[^"\\]|\\.)*)'/, 1),
+            P.MonadicParser.regexp(/"((?:[^"\\]|\\.)*)"/, 1).map(x => B.core.type.regex([`^${x}$`, 'i']))
+        );
+    },
+
+    Value: function (r: any) {
+        return P.MonadicParser.alt(r.Number, r.String);
+    },
+
+    ValueParens: function (r: any) {
+        return P.MonadicParser.alt(
+            r.ValueParens,
+            r.ValueOperator,
+            r.ValueExpressions
+        ).wrap(P.MonadicParser.string('('), P.MonadicParser.string(')'));
+    },
+
+    ValuePropertyNames: function () {
+        return P.MonadicParser.alt(...h.getPropertyNameRules(properties, /LIKE|>=|<=|=|!=|>|<|\)|\s/i));
+    },
+
+    ValueOperator: function (r: any) {
+        return h.combineOperators(valueOperators, P.MonadicParser.alt(r.ValueParens, r.ValueExpressions));
+    },
+
+    ValueExpressions: function (r: any) {
+        return P.MonadicParser.alt(
+            r.Value,
+            r.ValuePropertyNames
+        );
+    },
+
+    ValueQuery: function (r: any) {
+        return P.MonadicParser.alt(
+            r.ValueOperator.map((x: any) => {
+                if (x.head) {
+                    if (x.head.startsWith('structure-query.generator')) return x;
+                } else {
+                    if (typeof x === 'string' && x.length <= 4) {
+                        return B.struct.generator.atomGroups({
+                            'residue-test': B.core.rel.eq([B.ammp('label_comp_id'), x])
+                        });
+                    }
+                }
+                throw new Error(`values must be part of an comparison, value '${x}'`);
             })
-          }
-        }
-        throw new Error(`values must be part of an comparison, value '${x}'`)
-      })
-    )
-  }
-})
-
-const transpiler: Transpiler = str => lang.Query.tryParse(str)
-export default transpiler
+        );
+    }
+});
+
+export const transpiler: Transpiler = str => lang.Query.tryParse(str);
diff --git a/src/mol-script/transpilers/jmol/properties.ts b/src/mol-script/transpilers/jmol/properties.ts
index f86bbb9981e0052c4d61955efb9a9422f6ccae80..e80f98646314c48c8b25b488b94ff2c89c416639 100644
--- a/src/mol-script/transpilers/jmol/properties.ts
+++ b/src/mol-script/transpilers/jmol/properties.ts
@@ -1,9 +1,9 @@
-/*                                                                                                                                           
- * Copyright (c) 2017-2021 mol* contributors, licensed under MIT, See LICENSE file for more info.                                           
- * @author Alexander Rose <alexander.rose@weirdbyte.de>                                                                                     
- * @author Panagiotis Tourlas <panagiot_tourlov@hotmail.com>                                                                                 
- *                                                                                                                                           
- * @author Koya Sakuma                                                                                                                       
+/*
+ * Copyright (c) 2017-2021 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * @author Alexander Rose <alexander.rose@weirdbyte.de>
+ * @author Panagiotis Tourlas <panagiot_tourlov@hotmail.com>
+ *
+ * @author Koya Sakuma
  * This module was taken from MolQL and modified in similar manner as pymol and vmd tranpilers.                                             \
 */
 
@@ -11,655 +11,655 @@ import { MolScriptBuilder } from '../../../mol-script/language/builder';
 const B = MolScriptBuilder;
 import { PropertyDict } from '../types';
 
-const reFloat = /[-+]?[0-9]*\.?[0-9]+/
-const rePosInt = /[0-9]+/
+const reFloat = /[-+]?[0-9]*\.?[0-9]+/;
+const rePosInt = /[0-9]+/;
 
-function str(x: string) { return x }
+function str(x: string) { return x; }
 
 const structureDict: {[key: string]: string} = {
-  none: 'none',
-  turn: 'turn',
-  sheet: 'beta',
-  helix: 'helix',
-  dna: 'dna',
-  rna: 'rna',
-  carbohydrate: 'carbohydrate',
-  helix310: '3-10',
-  helixalpha: 'alpha',
-  helixpi: 'pi',
+    none: 'none',
+    turn: 'turn',
+    sheet: 'beta',
+    helix: 'helix',
+    dna: 'dna',
+    rna: 'rna',
+    carbohydrate: 'carbohydrate',
+    helix310: '3-10',
+    helixalpha: 'alpha',
+    helixpi: 'pi',
 
-  0: 'none',
-  1: 'turn',
-  2: 'beta',
-  3: 'helix',
-  4: 'dna',
-  5: 'rna',
-  6: 'carbohydrate',
-  7: '3-10',
-  8: 'alpha',
-  9: 'pi',
-}
+    0: 'none',
+    1: 'turn',
+    2: 'beta',
+    3: 'helix',
+    4: 'dna',
+    5: 'rna',
+    6: 'carbohydrate',
+    7: '3-10',
+    8: 'alpha',
+    9: 'pi',
+};
 export function structureMap(x: any) {
-  if (x.head && x.head === 'core.type.regex') x = x.args[0].replace(/^\^|\$$/g, '')
-  x = structureDict[x.toString().toLowerCase()] || 'none'
-  if (['dna', 'rna', 'carbohydrate'].indexOf(x) !== -1) {
-    throw new Error("values 'dna', 'rna', 'carbohydrate' not yet supported for 'structure' property")
-  } else {
-    return B.struct.type.secondaryStructureFlags([x])
-  }
+    if (x.head && x.head === 'core.type.regex') x = x.args[0].replace(/^\^|\$$/g, '');
+    x = structureDict[x.toString().toLowerCase()] || 'none';
+    if (['dna', 'rna', 'carbohydrate'].indexOf(x) !== -1) {
+        throw new Error("values 'dna', 'rna', 'carbohydrate' not yet supported for 'structure' property");
+    } else {
+        return B.struct.type.secondaryStructureFlags([x]);
+    }
 }
 
 export const properties: PropertyDict = {
-  adpmax: {
-    '@desc': 'the maximum anisotropic displacement parameter for the selected atom',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: reFloat, map: x => parseFloat(x),
-    level: 'atom-test'
-  },
-  adpmin: {
-    '@desc': 'the minimum anisotropic displacement parameter for the selected atom',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: reFloat, map: x => parseFloat(x),
-    level: 'atom-test'
-  },
-  altloc: {
-    '@desc': 'PDB alternate location identifier',
-    '@examples': ['altloc = A'],
-    regex: /[a-zA-Z0-9]/, map: str,
-    level: 'atom-test', property: B.ammp('label_alt_id')
-  },
-  altname: {
-    '@desc': 'an alternative name given to atoms by some file readers (for example, P2N)',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[a-zA-Z0-9]/, map: str,
-    level: 'atom-test'
-  },
-  atomID: {
-    '@desc': 'special atom IDs for PDB atoms assigned by Jmol',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: rePosInt, map: x => parseInt(x),
-    level: 'atom-test'
-  },
-  atomIndex: {
-    '@desc': 'atom 0-based index; a unique number for each atom regardless of the number of models loaded',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: rePosInt, map: x => parseInt(x),
-    level: 'atom-test'
-  },
-  atomName: {
-    '@desc': 'atom name',
-    '@examples': ['atomName = CA'],
-    regex: /[a-zA-Z0-9]+/, map: v => B.atomName(v),
-    level: 'atom-test', property: B.ammp('label_atom_id')
-  },
-  atomno: {
-    '@desc': 'sequential number; you can use "@" instead of "atomno=" -- for example, select @33 or Var x = @33 or @35',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: rePosInt, map: x => parseInt(x),
-    level: 'atom-test'
-  },
-  atomType: {
-    '@desc': 'atom type (mol2, AMBER files) or atom name (other file types)',
-    '@examples': ['atomType = OH'],
-    regex: /[a-zA-Z0-9]+/, map: v => B.atomName(v),
-    level: 'atom-test', property: B.ammp('label_atom_id')
-  },
-  atomX: {
-    '@desc': 'Cartesian X coordinate (or just X)',
-    '@examples': ['x = 4.2'],
-    abbr: ['X'],
-    isNumeric: true,
-    regex: reFloat, map: x => parseFloat(x),
-    level: 'atom-test', property: B.acp('x')
-  },
-  atomY: {
-    '@desc': 'Cartesian Y coordinate (or just Y)',
-    '@examples': ['y < 42'],
-    abbr: ['Y'],
-    isNumeric: true,
-    regex: reFloat, map: x => parseFloat(x),
-    level: 'atom-test', property: B.acp('y')
-  },
-  atomZ: {
-    '@desc': 'Cartesian Z coordinate (or just Z)',
-    '@examples': ['Z > 10'],
-    abbr: ['Z'],
-    isNumeric: true,
-    regex: reFloat, map: x => parseFloat(x),
-    level: 'atom-test', property: B.acp('z')
-  },
-  bondcount: {
-    '@desc': 'covalent bond count',
-    '@examples': ['bondcount = 0'],
-    isNumeric: true,
-    regex: rePosInt, map: x => parseInt(x),
-    level: 'atom-test', property: B.acp('bondCount')
-  },
-  bondingRadius: {
-    '@desc': 'radius used for auto bonding; synonymous with ionic and ionicRadius',
-    '@examples': [''],
-    abbr: ['ionic', 'ionicRadius'],
-    isUnsupported: true,
-    regex: reFloat, map: x => parseFloat(x),
-    level: 'atom-test'
-  },
-  cell: {
-    '@desc': 'crystallographic unit cell, expressed either in lattice integer notation (111-999) or as a coordinate in ijk space, where {1 1 1} is the same as 555. ANDing two cells, for example select cell=555 and cell=556, selects the atoms on the common face. (Note: in the specifc case of CELL, only "=" is allowed as a comparator.)',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  configuration: {
-    '@desc': 'Only in the context {configuration=n}, this option selects the set of atoms with either no ALTLOC specified or those atoms having this index into the array of altlocs within its model. So, for example, if the model has altloc "A" and "B", select configuration=1 is equivalent to select altloc="" or altloc="A", and print {configuration=2} is equivalent to print {altloc="" or altloc="B"}. Configuration 0 is "all atoms in a model having configurations", and an invalid configuration number gives no atoms. (Note: in the specifc case of CONFIGURATION, only "=" is allowed as a comparator.)',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: rePosInt, map: x => parseInt(x),
-    level: 'atom-test'
-  },
-  chain: {
-    '@desc': 'protein chain. For newer CIF files allowing multicharacter chain specifications, use quotations marks: select chain="AA". For these multicharacter desigations, case is not checked unless the CIF file has lower-case chain designations.',
-    '@examples': ['chain = A', 'chain = "AA"'],
-    regex: /[a-zA-Z0-9]+/, map: str,
-    level: 'chain-test', property: B.ammp('auth_asym_id')
-  },
-  chainNo: {
-    '@desc': 'chain number; sequentially counted from 1 for each model; chainNo == 0 means"no chain" or PDB chain identifier indicated as a blank (Jmol 14.0).',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  color: {
-    '@desc': 'the atom color',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  covalentRadius: {
-    '@desc': 'covalent bonding radius, synonymous with covalent. Not used by Jmol, but could be used, for example, in {*}.spacefill={*}.covalentRadius.all.',
-    '@examples': [''],
-    abbr: ['covalent'],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  cs: {
-    '@desc': 'chemical shift calculated using computational results that include magnetic shielding tensors.',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  element: {
-    '@desc': 'element symbol. The value of this parameter depends upon the context. Used with select structure=x, x can be either the quoted element symbol, "H", "He", "Li", etc. or atomic number. In all other contexts, the value is the element symbol. When the atom is a specific isotope, the string will contain the isotope number -- "13C", for example.',
-    '@examples': ['element=Fe'],
-    regex: /[a-zA-Z]+/, map: x => B.es(x),
-    level: 'atom-test', property: B.acp('elementSymbol')
-  },
-  elemno: {
-    '@desc': 'atomic element number',
-    '@examples': ['elemno=8'],
-    regex: /[0-9\s{}-]+/, map: x => parseInt(x),
-    level: 'atom-test', property: B.acp('atomicNumber')
-  },
-  eta: {
-    '@desc': 'Based on Carlos M. Duarte, Leven M. Wadley, and Anna Marie Pyle, RNA structure comparison, motif search and discovery using a reduced representation of RNA conformational space, Nucleic Acids Research, 2003, Vol. 31, No. 16 4755-4761. The parameter eta is the C4\'[i-1]-P[i]-C4\'[i]-P[i+1] dihedral angle; theta is the P[i]-C4\'[i]-P[i+1]-C4\'[i+1] dihedral angle. Both are measured on a 0-360 degree scale because they are commonly near 180 degrees. Using the commands plot PROPERTIES eta theta resno; select visible;wireframe only one can create these authors\' "RNA worm" graph.',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  theta: {
-    '@desc': 'Based on Carlos M. Duarte, Leven M. Wadley, and Anna Marie Pyle, RNA structure comparison, motif search and discovery using a reduced representation of RNA conformational space, Nucleic Acids Research, 2003, Vol. 31, No. 16 4755-4761. The parameter eta is the C4\'[i-1]-P[i]-C4\'[i]-P[i+1] dihedral angle; theta is the P[i]-C4\'[i]-P[i+1]-C4\'[i+1] dihedral angle. Both are measured on a 0-360 degree scale because they are commonly near 180 degrees. Using the commands plot PROPERTIES eta theta resno; select visible;wireframe only one can create these authors\' "RNA worm" graph.',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  file: {
-    '@desc': 'file number containing this atom',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  formalCharge: {
-    '@desc': 'formal charge',
-    '@examples': ['formalCharge=1'],
-    regex: reFloat, map: x => parseFloat(x),
-    level: 'atom-test', property: B.ammp('pdbx_formal_charge')
-  },
-  format: {
-    '@desc': 'format (label) of the atom.',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  fXyz: {
-    '@desc': 'fractional XYZ coordinates',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  fX: {
-    '@desc': 'fractional X coordinate',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  fY: {
-    '@desc': 'fractional Y coordinate',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  fZ: {
-    '@desc': 'fractional Z coordinate',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  fuxyz: {
-    '@desc': 'fractional XYZ coordinates in the unitcell coordinate system',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  fux: {
-    '@desc': 'fractional X coordinate in the unitcell coordinate system',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  fuy: {
-    '@desc': 'fractional Y coordinate in the unitcell coordinate system',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  fuz: {
-    '@desc': 'fractional Z coordinate in the unit cell coordinate system',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  group: {
-    '@desc': '3-letter residue code',
-    '@examples': ['group = ALA'],
-    regex: /[a-zA-Z0-9]{1,3}/, map: str,
-    level: 'residue-test', property: B.ammp('label_comp_id')
-  },
-  group1: {
-    '@desc': 'single-letter residue code (amino acids only)',
-    '@examples': ['group1 = G'],
-    regex: /[a-zA-Z]/, map: str,
-    level: 'residue-test', property: B.ammp('label_comp_id')
-  },
-  groupID: {
-    '@desc': 'group ID number: A unique ID for each amino acid or nucleic acid residue in a PDB file. 0  noGroup 1-5  ALA, ARG, ASN, ASP, CYS 6-10  GLN, GLU, GLY, HIS, ILE 11-15  LEU, LYS, MET, PHE, PRO 16-20  SER, THR, TRP, TYR, VAL 21-23  ASX, GLX, UNK 24-29  A, +A, G, +G, I, +I 30-35  C, +C, T, +T, U, +U Additional unique numbers are assigned arbitrarily by Jmol and cannot be used reproducibly.',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  groupindex: {
-    '@desc': 'overall group index',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  hydrophobicity: {
-    '@desc': 'Aminoacid residue scale of hydrophobicity based on Rose, G. D., Geselowitz, A. R., Lesser, G. J., Lee, R. H., and Zehfus, M. H. (1985). Hydrophobicity of amino acid residues in globular proteins, Science, 229(4716):834-838.',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  identify: {
-    '@desc': 'for a PDB/mmCIF file, a label such as [ILE]7^1:A.CD1%A/3 #47, which includes the group ([ILE]), residue number with optional insertion code (7^1), chain (:A), atom name (CD1), alternate location if present (%A), PDB model number (/3, for NMR models when one file is loaded; /file.model such as /2.3 if more than one file is loaded), and atom number (#47). For non-PDB data, the information is shorter -- for example, H15/2.1 #6, indicating atom name (H15), full file.model number (/2.1), and atom number (#6). If only a single model is loaded, %[identify] does not include the model number.',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  insertion: {
-    '@desc': 'protein residue insertion code',
-    '@examples': ['insertion=A'],
-    regex: /[a-zA-Z0-9]/, map: str,
-    level: 'atom-test', property: B.ammp('pdbx_PDB_ins_code')
-  },
-  label: {
-    '@desc': 'current atom label (same as format)',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  mass: {
-    '@desc': 'atomic mass -- especially useful with appended .max or .sum',
-    '@examples': ['mass > 13'],
-    regex: reFloat, map: x => parseFloat(x),
-    level: 'atom-test', property: B.acp('mass')
-  },
-  model: {
-    '@desc': 'model number',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  modelindex: {
-    '@desc': 'a unique number for each model, starting with 0 and spanning all models in all files',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  modO: {
-    '@desc': 'currently calculated occupancy from modulation (0 to 100; NaN if atom has no occupancy modulation)',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  modXYZ: {
-    '@desc': 'currently calculated displacement modulation (for incommensurately modulated structures). Also modX, modY, modZ for individual components. For atoms without modultion, {xx}.modXYZ is -1 and {xx}.modX is NaN, and in a label %[modXYZ] and %[modX] are blank.',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  molecule: {
-    '@desc': 'molecule number',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  monomer: {
-    '@desc': 'monomer number (group number) in a polymer (usually a chain), starting with 1, or 0 if not part of a biopolymer -- that is, not a connected carbohydrate, amino acid, or nucleic acid (Jmol 14.3.15)',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  ms: {
-    '@desc': 'magnetic shielding calculated from file-loaded tensors.',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  occupancy: {
-    '@desc': 'CIF file site occupancy. In SELECT command comparisons ("select occupancy < 90"), an integer n implies measurement on a 0-100 scale; also, in the context %[occupancy] or %q for a label, the reported number is a percentage. In all other cases, such as when %Q is used in a label or when a decimal number is used in a comparison, the scale is 0.0 - 1.0.',
-    '@examples': ['occupancy < 1'],
-    regex: reFloat, map: x => parseFloat(x),
-    level: 'atom-test', property: B.ammp('occupancy')
-  },
-  partialCharge: {
-    '@desc': 'partial charge',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: reFloat, map: x => parseFloat(x),
-    level: 'atom-test'
-  },
-  phi: {
-    '@desc': 'protein group PHI angle for atom\'s residue',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  polymer: {
-    '@desc': 'sequential polymer number in a model, starting with 1.',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  polymerLength: {
-    '@desc': 'polymer length',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  property_xx: {
-    '@desc': 'a property created using the DATA command',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  psi: {
-    '@desc': 'protein group PSI angle for the atom\'s residue',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  radius: {
-    '@desc': 'currently displayed radius -- In SELECT command comparisons ("select radius=n"), integer n implies Rasmol units 1/250 Angstroms; in all other cases or when a decimal number is used, the units are Angstroms.',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  resno: {
-    '@desc': 'PDB residue number, not including insertion code (see also seqcode, below)',
-    '@examples': ['resno = 100'],
-    regex: /-?[0-9]+/, map: x => parseInt(x),
-    level: 'residue-test', property: B.ammp('auth_seq_id')
-  },
-  selected: {
-    '@desc': '1.0 if atom is selected; 0.0 if not',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  sequence: {
-    '@desc': 'PDB one-character sequence code, as a string of characters, with "?" indicated where single-character codes are not available',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  seqcode: {
-    '@desc': 'PDB residue number, including insertion code (for example, 234^2; "seqcode" option added in Jmol 14.3.16)',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  seqid: {
-    '@desc': '(mmCIF only) the value from _atom_site.label_seq_id; a pointer to _entity_poly_seq.num in the ENTITY_POLY_SEQ category specifying the sequence of monomers in a polymer. Allowance is made for the possibility of microheterogeneity in a sample by allowing a given sequence number to be correlated with more than one monomer id. (Jmol 14.2.3)',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  shape: {
-    '@desc': 'hybridization geometry such as "tetrahedral"',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  site: {
-    '@desc': 'crystallographic site number',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  spacefill: {
-    '@desc': 'currently displayed radius',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  straightness: {
-    '@desc': 'quaternion-derived straightness (second derivative of the quaternion describing the orientation of the residue. This quantity will have different values depending upon the setting of quaternionFrame as "A" (alpha-carbon/phosphorus atom only), "C" (alpha-carbon/pyrimidine or purine base based), "P" (carbonyl-carbon peptide plane/phosphorus tetrahedron based), or "N" (amide-nitrogen based). The default is alpha-carbon based, which corresponds closely to the following combination of Ramachandran angles involving three consecutive residues i-1, i, and i+1: -psii-1 - phii + psii + phii+1.',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  strucno: {
-    '@desc': 'a unique number for each helix, sheet, or turn in a model, starting with 1.',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  structure: {
-    '@desc': 'The value of this parameter depends upon the context. Used with select structure=x, x can be either the quoted keyword "none", "turn", "sheet", "helix", "dna", "rna", or "carbohydrate" or a respective number 0-6. In the context {*}.structure, the return value is a number; in the context label %[structure], the return is one of the six keywords.',
-    '@examples': ['structure="helix"', 'structure=3'],
-    regex: /none|turn|sheet|helix|dna|rna|carbohydrate|[0-6]/i, map: str,
-    level: 'residue-test', property: 'structure'
-  },
-  substructure: {
-    '@desc': 'like structure, the value of this parameter depends upon the context. Used with select substructure=x, x can be either the quoted keyword "none", "turn", "sheet", "helix", "dna", "rna", "carbohydrate", "helix310", "helixalpha", or "helixpi", or the respective number 0-9. In the context {*}.substructure, the return value is a number; in the context label %[substructure], the return is one of the nine keywords.',
-    '@examples': ['substructure = "alphahelix"', 'substructure =9'],
-    regex: /none|turn|sheet|helix|dna|rna|carbohydrate|helix310|helixalpha|helixpi|[0-9]/i, map: str,
-    level: 'residue-test', property: 'structure'
-  },
-  surfacedistance: {
-    '@desc': 'A value related to the distance of an atom to a nominal molecular surface. 0 indicates at the surface. Positive numbers are minimum distances in Angstroms from the given atom to the surface.',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  symop: {
-    '@desc': 'the first symmetry operation code that generated this atom by Jmol; an integer starting with 1. See also symmetry, below. This operator is only present if the file contains space group information and the file was loaded using the {i, j, k} option so as to generate symmetry-based atoms. To select only the original atoms prior to application of symmetry, you can either use "SYMOP=n", where n is the symmetry operator corresponding to "x,y,z", or you can specify instead simply "NOT symmetry" the way you might specify "NOT hydrogen". Note that atoms in special positions will have multiple operator matches. These atoms can be selected using the keyword SPECIALPOSITION. The special form select SYMOP=nijk selects a specific translation of atoms from the given crystallographic symmetry operation. Comparators <, <=, >, >=, and != can be used and only apply to the ijk part of the designation. The ijk are relative, not absolute. Thus, symop=2555 selects for atoms that have been transformed by symop=2 but not subjected to any further translation. select symop=1555 is identical to select not symmetry. All other ijk are relative to these selections for 555. If the model was loaded using load "filename.cif" {444 666 1}, where the 1 indicates that all symmetry-generated atoms are to be packed within cell 555 and then translated to fill the other 26 specified cells, then select symop=3555 is nearly the same as select symop=3 and cell=555. (The difference being that cell=555 selects for all atoms that are on any edge of the cell, while symop=3555 does not.) However, the situation is different if instead the model was loaded using load "filename.cif" {444 666 0}, where the 0 indicates that symmetry-generated atoms are to be placed exactly where their symmetry operator would put them (x,-y,z being different then from x, 1-y, z). In that case, select symop=3555 is for all atoms that have been generated using symmetry operation 3 but have not had any additional translations applied to the x,y,z expression found in the CIF file. If, for example, symmetry operation 3 is -x,-y,-z, then load "filename.cif" {444 666 0} will place an atom originally at {1/2, 1/2, 1/2} at positions {-1/2, -1/2, -1/2} (symop=3555) and {-3/2, -3/2, -3/2} (symop=3444) and 24 other sites.',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  symmetry: {
-    '@desc': 'as "symmetry" or in a label as lower-case "o" gives list of crystallographic symmetry operators generating this atom with lattice designations,such as 3555; upper-case "%O" in a label gives a list without the lattice designations. See also symop, above.',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  temperature: {
-    '@desc': 'yes  yes  temperature factor (B-factor)',
-    '@examples': ['temperature >= 20'],
-    regex: reFloat, map: x => parseFloat(x),
-    level: 'atom-test', property: B.ammp('B_iso_or_equiv')
-  },
-  unitXyz: {
-    '@desc': 'unit cell XYZ coordinates',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  uX: {
-    '@desc': 'unit cell X coordinate normalized to [0,1)',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  uY: {
-    '@desc': 'unit cell Y coordinate normalized to [0,1)',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  uZ: {
-    '@desc': 'unit cell Z coordinate normalized to [0,1)',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  valence: {
-    '@desc': 'the valence of an atom (sum of bonds, where double bond counts as 2 and triple bond counts as 3',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  vanderwaals: {
-    '@desc': 'van der Waals radius',
-    '@examples': ['vanderwaals >2'],
-    regex: reFloat, map: x => parseFloat(x),
-    level: 'atom-test', property: B.acp('vdw')
-  },
-  vectorScale: {
-    '@desc': 'vibration vector scale',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  volume: {
-    '@desc': 'approximate van der Waals volume for this atom. Note, {*}.volume gives an average; use {*}.volume.sum to get total volume.',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  vXyz: {
-    '@desc': 'vibration vector, or individual components as %vx %vy %vz. For atoms without vibration vectors, {xx}.vXyz is -1; in a label, %[vxyz] is blank.',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  vX: {
-    '@desc': 'vibration vector X coordinate; for atoms without vibration vector, {xx}.vX is NaN (same for vY and vZ)',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  vY: {
-    '@desc': 'vibration vector Y coordinate',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  vZ: {
-    '@desc': 'vibration vector Z coordinate',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  xyz: {
-    '@desc': 'Cartesian XYZ coordinates; select xyz > 1.0 selects atoms more than one Angstrom from the origin.',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-}
+    adpmax: {
+        '@desc': 'the maximum anisotropic displacement parameter for the selected atom',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: reFloat, map: x => parseFloat(x),
+        level: 'atom-test'
+    },
+    adpmin: {
+        '@desc': 'the minimum anisotropic displacement parameter for the selected atom',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: reFloat, map: x => parseFloat(x),
+        level: 'atom-test'
+    },
+    altloc: {
+        '@desc': 'PDB alternate location identifier',
+        '@examples': ['altloc = A'],
+        regex: /[a-zA-Z0-9]/, map: str,
+        level: 'atom-test', property: B.ammp('label_alt_id')
+    },
+    altname: {
+        '@desc': 'an alternative name given to atoms by some file readers (for example, P2N)',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[a-zA-Z0-9]/, map: str,
+        level: 'atom-test'
+    },
+    atomID: {
+        '@desc': 'special atom IDs for PDB atoms assigned by Jmol',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: rePosInt, map: x => parseInt(x),
+        level: 'atom-test'
+    },
+    atomIndex: {
+        '@desc': 'atom 0-based index; a unique number for each atom regardless of the number of models loaded',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: rePosInt, map: x => parseInt(x),
+        level: 'atom-test'
+    },
+    atomName: {
+        '@desc': 'atom name',
+        '@examples': ['atomName = CA'],
+        regex: /[a-zA-Z0-9]+/, map: v => B.atomName(v),
+        level: 'atom-test', property: B.ammp('label_atom_id')
+    },
+    atomno: {
+        '@desc': 'sequential number; you can use "@" instead of "atomno=" -- for example, select @33 or Var x = @33 or @35',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: rePosInt, map: x => parseInt(x),
+        level: 'atom-test'
+    },
+    atomType: {
+        '@desc': 'atom type (mol2, AMBER files) or atom name (other file types)',
+        '@examples': ['atomType = OH'],
+        regex: /[a-zA-Z0-9]+/, map: v => B.atomName(v),
+        level: 'atom-test', property: B.ammp('label_atom_id')
+    },
+    atomX: {
+        '@desc': 'Cartesian X coordinate (or just X)',
+        '@examples': ['x = 4.2'],
+        abbr: ['X'],
+        isNumeric: true,
+        regex: reFloat, map: x => parseFloat(x),
+        level: 'atom-test', property: B.acp('x')
+    },
+    atomY: {
+        '@desc': 'Cartesian Y coordinate (or just Y)',
+        '@examples': ['y < 42'],
+        abbr: ['Y'],
+        isNumeric: true,
+        regex: reFloat, map: x => parseFloat(x),
+        level: 'atom-test', property: B.acp('y')
+    },
+    atomZ: {
+        '@desc': 'Cartesian Z coordinate (or just Z)',
+        '@examples': ['Z > 10'],
+        abbr: ['Z'],
+        isNumeric: true,
+        regex: reFloat, map: x => parseFloat(x),
+        level: 'atom-test', property: B.acp('z')
+    },
+    bondcount: {
+        '@desc': 'covalent bond count',
+        '@examples': ['bondcount = 0'],
+        isNumeric: true,
+        regex: rePosInt, map: x => parseInt(x),
+        level: 'atom-test', property: B.acp('bondCount')
+    },
+    bondingRadius: {
+        '@desc': 'radius used for auto bonding; synonymous with ionic and ionicRadius',
+        '@examples': [''],
+        abbr: ['ionic', 'ionicRadius'],
+        isUnsupported: true,
+        regex: reFloat, map: x => parseFloat(x),
+        level: 'atom-test'
+    },
+    cell: {
+        '@desc': 'crystallographic unit cell, expressed either in lattice integer notation (111-999) or as a coordinate in ijk space, where {1 1 1} is the same as 555. ANDing two cells, for example select cell=555 and cell=556, selects the atoms on the common face. (Note: in the specifc case of CELL, only "=" is allowed as a comparator.)',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    configuration: {
+        '@desc': 'Only in the context {configuration=n}, this option selects the set of atoms with either no ALTLOC specified or those atoms having this index into the array of altlocs within its model. So, for example, if the model has altloc "A" and "B", select configuration=1 is equivalent to select altloc="" or altloc="A", and print {configuration=2} is equivalent to print {altloc="" or altloc="B"}. Configuration 0 is "all atoms in a model having configurations", and an invalid configuration number gives no atoms. (Note: in the specifc case of CONFIGURATION, only "=" is allowed as a comparator.)',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: rePosInt, map: x => parseInt(x),
+        level: 'atom-test'
+    },
+    chain: {
+        '@desc': 'protein chain. For newer CIF files allowing multicharacter chain specifications, use quotations marks: select chain="AA". For these multicharacter desigations, case is not checked unless the CIF file has lower-case chain designations.',
+        '@examples': ['chain = A', 'chain = "AA"'],
+        regex: /[a-zA-Z0-9]+/, map: str,
+        level: 'chain-test', property: B.ammp('auth_asym_id')
+    },
+    chainNo: {
+        '@desc': 'chain number; sequentially counted from 1 for each model; chainNo == 0 means"no chain" or PDB chain identifier indicated as a blank (Jmol 14.0).',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    color: {
+        '@desc': 'the atom color',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    covalentRadius: {
+        '@desc': 'covalent bonding radius, synonymous with covalent. Not used by Jmol, but could be used, for example, in {*}.spacefill={*}.covalentRadius.all.',
+        '@examples': [''],
+        abbr: ['covalent'],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    cs: {
+        '@desc': 'chemical shift calculated using computational results that include magnetic shielding tensors.',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    element: {
+        '@desc': 'element symbol. The value of this parameter depends upon the context. Used with select structure=x, x can be either the quoted element symbol, "H", "He", "Li", etc. or atomic number. In all other contexts, the value is the element symbol. When the atom is a specific isotope, the string will contain the isotope number -- "13C", for example.',
+        '@examples': ['element=Fe'],
+        regex: /[a-zA-Z]+/, map: x => B.es(x),
+        level: 'atom-test', property: B.acp('elementSymbol')
+    },
+    elemno: {
+        '@desc': 'atomic element number',
+        '@examples': ['elemno=8'],
+        regex: /[0-9\s{}-]+/, map: x => parseInt(x),
+        level: 'atom-test', property: B.acp('atomicNumber')
+    },
+    eta: {
+        '@desc': 'Based on Carlos M. Duarte, Leven M. Wadley, and Anna Marie Pyle, RNA structure comparison, motif search and discovery using a reduced representation of RNA conformational space, Nucleic Acids Research, 2003, Vol. 31, No. 16 4755-4761. The parameter eta is the C4\'[i-1]-P[i]-C4\'[i]-P[i+1] dihedral angle; theta is the P[i]-C4\'[i]-P[i+1]-C4\'[i+1] dihedral angle. Both are measured on a 0-360 degree scale because they are commonly near 180 degrees. Using the commands plot PROPERTIES eta theta resno; select visible;wireframe only one can create these authors\' "RNA worm" graph.',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    theta: {
+        '@desc': 'Based on Carlos M. Duarte, Leven M. Wadley, and Anna Marie Pyle, RNA structure comparison, motif search and discovery using a reduced representation of RNA conformational space, Nucleic Acids Research, 2003, Vol. 31, No. 16 4755-4761. The parameter eta is the C4\'[i-1]-P[i]-C4\'[i]-P[i+1] dihedral angle; theta is the P[i]-C4\'[i]-P[i+1]-C4\'[i+1] dihedral angle. Both are measured on a 0-360 degree scale because they are commonly near 180 degrees. Using the commands plot PROPERTIES eta theta resno; select visible;wireframe only one can create these authors\' "RNA worm" graph.',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    file: {
+        '@desc': 'file number containing this atom',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    formalCharge: {
+        '@desc': 'formal charge',
+        '@examples': ['formalCharge=1'],
+        regex: reFloat, map: x => parseFloat(x),
+        level: 'atom-test', property: B.ammp('pdbx_formal_charge')
+    },
+    format: {
+        '@desc': 'format (label) of the atom.',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    fXyz: {
+        '@desc': 'fractional XYZ coordinates',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    fX: {
+        '@desc': 'fractional X coordinate',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    fY: {
+        '@desc': 'fractional Y coordinate',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    fZ: {
+        '@desc': 'fractional Z coordinate',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    fuxyz: {
+        '@desc': 'fractional XYZ coordinates in the unitcell coordinate system',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    fux: {
+        '@desc': 'fractional X coordinate in the unitcell coordinate system',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    fuy: {
+        '@desc': 'fractional Y coordinate in the unitcell coordinate system',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    fuz: {
+        '@desc': 'fractional Z coordinate in the unit cell coordinate system',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    group: {
+        '@desc': '3-letter residue code',
+        '@examples': ['group = ALA'],
+        regex: /[a-zA-Z0-9]{1,3}/, map: str,
+        level: 'residue-test', property: B.ammp('label_comp_id')
+    },
+    group1: {
+        '@desc': 'single-letter residue code (amino acids only)',
+        '@examples': ['group1 = G'],
+        regex: /[a-zA-Z]/, map: str,
+        level: 'residue-test', property: B.ammp('label_comp_id')
+    },
+    groupID: {
+        '@desc': 'group ID number: A unique ID for each amino acid or nucleic acid residue in a PDB file. 0  noGroup 1-5  ALA, ARG, ASN, ASP, CYS 6-10  GLN, GLU, GLY, HIS, ILE 11-15  LEU, LYS, MET, PHE, PRO 16-20  SER, THR, TRP, TYR, VAL 21-23  ASX, GLX, UNK 24-29  A, +A, G, +G, I, +I 30-35  C, +C, T, +T, U, +U Additional unique numbers are assigned arbitrarily by Jmol and cannot be used reproducibly.',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    groupindex: {
+        '@desc': 'overall group index',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    hydrophobicity: {
+        '@desc': 'Aminoacid residue scale of hydrophobicity based on Rose, G. D., Geselowitz, A. R., Lesser, G. J., Lee, R. H., and Zehfus, M. H. (1985). Hydrophobicity of amino acid residues in globular proteins, Science, 229(4716):834-838.',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    identify: {
+        '@desc': 'for a PDB/mmCIF file, a label such as [ILE]7^1:A.CD1%A/3 #47, which includes the group ([ILE]), residue number with optional insertion code (7^1), chain (:A), atom name (CD1), alternate location if present (%A), PDB model number (/3, for NMR models when one file is loaded; /file.model such as /2.3 if more than one file is loaded), and atom number (#47). For non-PDB data, the information is shorter -- for example, H15/2.1 #6, indicating atom name (H15), full file.model number (/2.1), and atom number (#6). If only a single model is loaded, %[identify] does not include the model number.',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    insertion: {
+        '@desc': 'protein residue insertion code',
+        '@examples': ['insertion=A'],
+        regex: /[a-zA-Z0-9]/, map: str,
+        level: 'atom-test', property: B.ammp('pdbx_PDB_ins_code')
+    },
+    label: {
+        '@desc': 'current atom label (same as format)',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    mass: {
+        '@desc': 'atomic mass -- especially useful with appended .max or .sum',
+        '@examples': ['mass > 13'],
+        regex: reFloat, map: x => parseFloat(x),
+        level: 'atom-test', property: B.acp('mass')
+    },
+    model: {
+        '@desc': 'model number',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    modelindex: {
+        '@desc': 'a unique number for each model, starting with 0 and spanning all models in all files',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    modO: {
+        '@desc': 'currently calculated occupancy from modulation (0 to 100; NaN if atom has no occupancy modulation)',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    modXYZ: {
+        '@desc': 'currently calculated displacement modulation (for incommensurately modulated structures). Also modX, modY, modZ for individual components. For atoms without modultion, {xx}.modXYZ is -1 and {xx}.modX is NaN, and in a label %[modXYZ] and %[modX] are blank.',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    molecule: {
+        '@desc': 'molecule number',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    monomer: {
+        '@desc': 'monomer number (group number) in a polymer (usually a chain), starting with 1, or 0 if not part of a biopolymer -- that is, not a connected carbohydrate, amino acid, or nucleic acid (Jmol 14.3.15)',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    ms: {
+        '@desc': 'magnetic shielding calculated from file-loaded tensors.',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    occupancy: {
+        '@desc': 'CIF file site occupancy. In SELECT command comparisons ("select occupancy < 90"), an integer n implies measurement on a 0-100 scale; also, in the context %[occupancy] or %q for a label, the reported number is a percentage. In all other cases, such as when %Q is used in a label or when a decimal number is used in a comparison, the scale is 0.0 - 1.0.',
+        '@examples': ['occupancy < 1'],
+        regex: reFloat, map: x => parseFloat(x),
+        level: 'atom-test', property: B.ammp('occupancy')
+    },
+    partialCharge: {
+        '@desc': 'partial charge',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: reFloat, map: x => parseFloat(x),
+        level: 'atom-test'
+    },
+    phi: {
+        '@desc': 'protein group PHI angle for atom\'s residue',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    polymer: {
+        '@desc': 'sequential polymer number in a model, starting with 1.',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    polymerLength: {
+        '@desc': 'polymer length',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    property_xx: {
+        '@desc': 'a property created using the DATA command',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    psi: {
+        '@desc': 'protein group PSI angle for the atom\'s residue',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    radius: {
+        '@desc': 'currently displayed radius -- In SELECT command comparisons ("select radius=n"), integer n implies Rasmol units 1/250 Angstroms; in all other cases or when a decimal number is used, the units are Angstroms.',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    resno: {
+        '@desc': 'PDB residue number, not including insertion code (see also seqcode, below)',
+        '@examples': ['resno = 100'],
+        regex: /-?[0-9]+/, map: x => parseInt(x),
+        level: 'residue-test', property: B.ammp('auth_seq_id')
+    },
+    selected: {
+        '@desc': '1.0 if atom is selected; 0.0 if not',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    sequence: {
+        '@desc': 'PDB one-character sequence code, as a string of characters, with "?" indicated where single-character codes are not available',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    seqcode: {
+        '@desc': 'PDB residue number, including insertion code (for example, 234^2; "seqcode" option added in Jmol 14.3.16)',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    seqid: {
+        '@desc': '(mmCIF only) the value from _atom_site.label_seq_id; a pointer to _entity_poly_seq.num in the ENTITY_POLY_SEQ category specifying the sequence of monomers in a polymer. Allowance is made for the possibility of microheterogeneity in a sample by allowing a given sequence number to be correlated with more than one monomer id. (Jmol 14.2.3)',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    shape: {
+        '@desc': 'hybridization geometry such as "tetrahedral"',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    site: {
+        '@desc': 'crystallographic site number',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    spacefill: {
+        '@desc': 'currently displayed radius',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    straightness: {
+        '@desc': 'quaternion-derived straightness (second derivative of the quaternion describing the orientation of the residue. This quantity will have different values depending upon the setting of quaternionFrame as "A" (alpha-carbon/phosphorus atom only), "C" (alpha-carbon/pyrimidine or purine base based), "P" (carbonyl-carbon peptide plane/phosphorus tetrahedron based), or "N" (amide-nitrogen based). The default is alpha-carbon based, which corresponds closely to the following combination of Ramachandran angles involving three consecutive residues i-1, i, and i+1: -psii-1 - phii + psii + phii+1.',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    strucno: {
+        '@desc': 'a unique number for each helix, sheet, or turn in a model, starting with 1.',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    structure: {
+        '@desc': 'The value of this parameter depends upon the context. Used with select structure=x, x can be either the quoted keyword "none", "turn", "sheet", "helix", "dna", "rna", or "carbohydrate" or a respective number 0-6. In the context {*}.structure, the return value is a number; in the context label %[structure], the return is one of the six keywords.',
+        '@examples': ['structure="helix"', 'structure=3'],
+        regex: /none|turn|sheet|helix|dna|rna|carbohydrate|[0-6]/i, map: str,
+        level: 'residue-test', property: 'structure'
+    },
+    substructure: {
+        '@desc': 'like structure, the value of this parameter depends upon the context. Used with select substructure=x, x can be either the quoted keyword "none", "turn", "sheet", "helix", "dna", "rna", "carbohydrate", "helix310", "helixalpha", or "helixpi", or the respective number 0-9. In the context {*}.substructure, the return value is a number; in the context label %[substructure], the return is one of the nine keywords.',
+        '@examples': ['substructure = "alphahelix"', 'substructure =9'],
+        regex: /none|turn|sheet|helix|dna|rna|carbohydrate|helix310|helixalpha|helixpi|[0-9]/i, map: str,
+        level: 'residue-test', property: 'structure'
+    },
+    surfacedistance: {
+        '@desc': 'A value related to the distance of an atom to a nominal molecular surface. 0 indicates at the surface. Positive numbers are minimum distances in Angstroms from the given atom to the surface.',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    symop: {
+        '@desc': 'the first symmetry operation code that generated this atom by Jmol; an integer starting with 1. See also symmetry, below. This operator is only present if the file contains space group information and the file was loaded using the {i, j, k} option so as to generate symmetry-based atoms. To select only the original atoms prior to application of symmetry, you can either use "SYMOP=n", where n is the symmetry operator corresponding to "x,y,z", or you can specify instead simply "NOT symmetry" the way you might specify "NOT hydrogen". Note that atoms in special positions will have multiple operator matches. These atoms can be selected using the keyword SPECIALPOSITION. The special form select SYMOP=nijk selects a specific translation of atoms from the given crystallographic symmetry operation. Comparators <, <=, >, >=, and != can be used and only apply to the ijk part of the designation. The ijk are relative, not absolute. Thus, symop=2555 selects for atoms that have been transformed by symop=2 but not subjected to any further translation. select symop=1555 is identical to select not symmetry. All other ijk are relative to these selections for 555. If the model was loaded using load "filename.cif" {444 666 1}, where the 1 indicates that all symmetry-generated atoms are to be packed within cell 555 and then translated to fill the other 26 specified cells, then select symop=3555 is nearly the same as select symop=3 and cell=555. (The difference being that cell=555 selects for all atoms that are on any edge of the cell, while symop=3555 does not.) However, the situation is different if instead the model was loaded using load "filename.cif" {444 666 0}, where the 0 indicates that symmetry-generated atoms are to be placed exactly where their symmetry operator would put them (x,-y,z being different then from x, 1-y, z). In that case, select symop=3555 is for all atoms that have been generated using symmetry operation 3 but have not had any additional translations applied to the x,y,z expression found in the CIF file. If, for example, symmetry operation 3 is -x,-y,-z, then load "filename.cif" {444 666 0} will place an atom originally at {1/2, 1/2, 1/2} at positions {-1/2, -1/2, -1/2} (symop=3555) and {-3/2, -3/2, -3/2} (symop=3444) and 24 other sites.',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    symmetry: {
+        '@desc': 'as "symmetry" or in a label as lower-case "o" gives list of crystallographic symmetry operators generating this atom with lattice designations,such as 3555; upper-case "%O" in a label gives a list without the lattice designations. See also symop, above.',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    temperature: {
+        '@desc': 'yes  yes  temperature factor (B-factor)',
+        '@examples': ['temperature >= 20'],
+        regex: reFloat, map: x => parseFloat(x),
+        level: 'atom-test', property: B.ammp('B_iso_or_equiv')
+    },
+    unitXyz: {
+        '@desc': 'unit cell XYZ coordinates',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    uX: {
+        '@desc': 'unit cell X coordinate normalized to [0,1)',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    uY: {
+        '@desc': 'unit cell Y coordinate normalized to [0,1)',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    uZ: {
+        '@desc': 'unit cell Z coordinate normalized to [0,1)',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    valence: {
+        '@desc': 'the valence of an atom (sum of bonds, where double bond counts as 2 and triple bond counts as 3',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    vanderwaals: {
+        '@desc': 'van der Waals radius',
+        '@examples': ['vanderwaals >2'],
+        regex: reFloat, map: x => parseFloat(x),
+        level: 'atom-test', property: B.acp('vdw')
+    },
+    vectorScale: {
+        '@desc': 'vibration vector scale',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    volume: {
+        '@desc': 'approximate van der Waals volume for this atom. Note, {*}.volume gives an average; use {*}.volume.sum to get total volume.',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    vXyz: {
+        '@desc': 'vibration vector, or individual components as %vx %vy %vz. For atoms without vibration vectors, {xx}.vXyz is -1; in a label, %[vxyz] is blank.',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    vX: {
+        '@desc': 'vibration vector X coordinate; for atoms without vibration vector, {xx}.vX is NaN (same for vY and vZ)',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    vY: {
+        '@desc': 'vibration vector Y coordinate',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    vZ: {
+        '@desc': 'vibration vector Z coordinate',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    xyz: {
+        '@desc': 'Cartesian XYZ coordinates; select xyz > 1.0 selects atoms more than one Angstrom from the origin.',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+};
 
diff --git a/src/mol-script/transpilers/jmol/symbols.ts b/src/mol-script/transpilers/jmol/symbols.ts
index 9f07f7b41a40f390df10c35a9f71dc8b29d16a80..85617eadc2bfd5e1e31af113a89311f18d50860c 100644
--- a/src/mol-script/transpilers/jmol/symbols.ts
+++ b/src/mol-script/transpilers/jmol/symbols.ts
@@ -1,9 +1,9 @@
-/*                                                                                                                                           
- * Copyright (c) 2017-2021 mol* contributors, licensed under MIT, See LICENSE file for more info.                                           
- * @author Alexander Rose <alexander.rose@weirdbyte.de>                                                                                     
- * @author Panagiotis Tourlas <panagiot_tourlov@hotmail.com>                                                                                 
- *                                                                                                                                           
- * @author Koya Sakuma                                                                                                                       
+/*
+ * Copyright (c) 2017-2021 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * @author Alexander Rose <alexander.rose@weirdbyte.de>
+ * @author Panagiotis Tourlas <panagiot_tourlov@hotmail.com>
+ *
+ * @author Koya Sakuma
  * This module was taken from MolQL and modified in similar manner as pymol and vmd tranpilers.                                             \
 */
 
@@ -11,26 +11,25 @@ import { properties } from './properties';
 import { operators } from './operators';
 import { keywords } from './keywords';
 
-export const Properties: string[] = []
+export const Properties: string[] = [];
 for (const name in properties) {
-    if (properties[name].isUnsupported) continue
-    Properties.push(name)
-    if (properties[name].abbr) Properties.push(...properties[name].abbr!)
+    if (properties[name].isUnsupported) continue;
+    Properties.push(name);
+    if (properties[name].abbr) Properties.push(...properties[name].abbr!);
 }
 
-export const Operators: string[] = []
+export const Operators: string[] = [];
 operators.forEach(o => {
-    if (o.isUnsupported) return
-    Operators.push(o.name)
-    if (o.abbr) Operators.push(...o.abbr)
-})
+    if (o.isUnsupported) return;
+    Operators.push(o.name);
+    if (o.abbr) Operators.push(...o.abbr);
+});
 
-export const Keywords: string[] = []
+export const Keywords: string[] = [];
 for (const name in keywords) {
-    if (!keywords[name].map) continue
-    Keywords.push(name)
-    if (keywords[name].abbr) Keywords.push(...keywords[name].abbr!)
+    if (!keywords[name].map) continue;
+    Keywords.push(name);
+    if (keywords[name].abbr) Keywords.push(...keywords[name].abbr!);
 }
 
-const _all = { Properties, Operators, Keywords }
-export default _all
+export const _all = { Properties, Operators, Keywords };
diff --git a/src/mol-script/transpilers/pymol/keywords.ts b/src/mol-script/transpilers/pymol/keywords.ts
index fc049dfbe1fff5a1b1d866febf5d68fd222708b9..e26990a41dbdf5e5349a01d4cac4fd2390149c28 100644
--- a/src/mol-script/transpilers/pymol/keywords.ts
+++ b/src/mol-script/transpilers/pymol/keywords.ts
@@ -205,28 +205,28 @@ export const keywords: KeywordDict = {
         map: () => B.struct.generator.atomGroups({
             'atom-test': B.core.set.has([
                 B.core.type.set(Backbone.protein.concat(ResDict.protein)),
-		B.ammp('label_atom_id')	
+                B.ammp('label_atom_id')
 	    ])
-	}),
-    },	    
+        }),
+    },
     proteinxxxxxx: {
         '@desc': 'protein................',
-	abbr: ['polymer.protein'],
+        abbr: ['polymer.protein'],
         map: () => B.struct.generator.atomGroups({
             'residue-test': B.core.set.has([
                 B.core.type.set(ResDict.protein),
                 B.ammp('label_comp_id')
             ])
-	})
+        })
     },
     nucleicxxxxx: {
-	'@desc': 'protein................',
-	abbr: ['polymer.nucleic'],
+        '@desc': 'protein................',
+        abbr: ['polymer.nucleic'],
         map: () => B.struct.generator.atomGroups({
             'residue-test': B.core.set.has([
                 B.core.type.set(ResDict.nucleic),
                 B.ammp('label_comp_id')
             ])
         })
-    }				   
+    }
 };
diff --git a/src/mol-script/transpilers/pymol/operators.ts b/src/mol-script/transpilers/pymol/operators.ts
index 74ffa6146f6f7ef2b1f65b24272d871e421ed467..20684b84cb648b4f7c6b1429f53942984eb59402 100644
--- a/src/mol-script/transpilers/pymol/operators.ts
+++ b/src/mol-script/transpilers/pymol/operators.ts
@@ -92,7 +92,7 @@ export const operators: OperatorList = [
         type: h.postfix,
         rule: h
             .postfixOp(/GAP\s+([-+]?[0-9]*\.?[0-9]+)/i, 1)
-            .map((x:any) => parseFloat(x)),
+            .map((x: any) => parseFloat(x)),
         map: (distance: number, target: Expression) => {
             return B.struct.filter.within({
                 '0': B.struct.generator.atomGroups(),
@@ -112,7 +112,7 @@ export const operators: OperatorList = [
         type: h.postfix,
         rule: h
             .postfixOp(/(AROUND|a\.)\s+([-+]?[0-9]*\.?[0-9]+)/i, 2)
-            .map((x:any) => parseFloat(x)),
+            .map((x: any) => parseFloat(x)),
         map: (radius: number, target: Expression) => {
             return B.struct.modifier.exceptBy({
                 '0': B.struct.filter.within({
@@ -133,7 +133,7 @@ export const operators: OperatorList = [
         type: h.postfix,
         rule: h
             .postfixOp(/(EXPAND|x\.)\s+([-+]?[0-9]*\.?[0-9]+)/i, 2)
-            .map((x:any) => parseFloat(x)),
+            .map((x: any) => parseFloat(x)),
         map: (radius: number, selection: Expression) => {
             return B.struct.modifier.includeSurroundings({ 0: selection, radius });
         },
@@ -353,7 +353,7 @@ export const operators: OperatorList = [
         name: 'extend',
         abbr: ['xt.'],
         type: h.postfix,
-        rule: h.postfixOp(/(EXTEND|xt\.)\s+([0-9]+)/i, 2).map((x:any) => parseInt(x)),
+        rule: h.postfixOp(/(EXTEND|xt\.)\s+([0-9]+)/i, 2).map((x: any) => parseInt(x)),
         map: (count: number, selection: Expression) => {
             return h.asAtoms(
                 B.struct.modifier.includeConnected({
diff --git a/src/mol-script/transpilers/pymol/parser.ts b/src/mol-script/transpilers/pymol/parser.ts
index 2b75afbe615c5db67b91829547ed93bc3f01a1b5..830ee0cd431f7fb0172d762ba3956ef423f90e4d 100644
--- a/src/mol-script/transpilers/pymol/parser.ts
+++ b/src/mol-script/transpilers/pymol/parser.ts
@@ -31,7 +31,7 @@ function atomSelectionQuery(x: any) {
     const tests: AtomGroupArgs = {};
     const props: { [k: string]: any[] } = {};
 
-    for (let k in x) {
+    for (const k in x) {
         const ps = properties[k];
         if (!ps) {
             throw new Error(`property '${k}' not supported, value '${x[k]}'`);
@@ -41,7 +41,7 @@ function atomSelectionQuery(x: any) {
         props[ps.level].push(x[k]);
     }
 
-    for (let p in props) {
+    for (const p in props) {
         tests[p] = h.andExpr(props[p]);
     }
 
@@ -49,7 +49,7 @@ function atomSelectionQuery(x: any) {
 }
 
 const lang = P.MonadicParser.createLanguage({
-    Parens: function (r : any) {
+    Parens: function (r: any) {
         return P.MonadicParser.alt(
             r.Parens,
             r.Operator,
@@ -57,7 +57,7 @@ const lang = P.MonadicParser.createLanguage({
         ).wrap(P.MonadicParser.string('('), P.MonadicParser.string(')'));
     },
 
-    Expression: function (r : any) {
+    Expression: function (r: any) {
         return P.MonadicParser.alt(
 	    r.Keywords,
             r.AtomSelectionMacro.map(atomSelectionQuery),
@@ -68,7 +68,7 @@ const lang = P.MonadicParser.createLanguage({
         );
     },
 
-    AtomSelectionMacro: function (r : any) {
+    AtomSelectionMacro: function (r: any) {
         return P.MonadicParser.alt(
             slash.then(P.MonadicParser.alt(
                 P.MonadicParser.seq(
@@ -135,9 +135,9 @@ const lang = P.MonadicParser.createLanguage({
             .sort(h.strLenSortFn).map(h.escapeRegExp).join('|');
         return P.MonadicParser.regexp(new RegExp(`(?!(${w}))[A-Z0-9_]+`, 'i'));
     },
-    Object: (r : any) => {
+    Object: (r: any) => {
         return r.ObjectProperty.notFollowedBy(slash)
-            .map( (x:any)  => { throw new Error(`property 'object' not supported, value '${x}'`); });
+            .map((x: any) => { throw new Error(`property 'object' not supported, value '${x}'`); });
     },
 
     // Selects peptide sequence matching upper-case one-letter
@@ -155,11 +155,11 @@ const lang = P.MonadicParser.createLanguage({
             .map(h.makeError(`operator 'rep' not supported`));
     },
 
-    Operator: function (r : any) {
+    Operator: function (r: any) {
         return h.combineOperators(operators, P.MonadicParser.alt(r.Parens, r.Expression, r.Operator));
     },
 
-    Query: function (r : any) {
+    Query: function (r: any) {
         return P.MonadicParser.alt(
             r.Operator,
             r.Parens,
@@ -169,4 +169,3 @@ const lang = P.MonadicParser.createLanguage({
 });
 
 export const transpiler: Transpiler = str => lang.Query.tryParse(str);
-export default transpiler
diff --git a/src/mol-script/transpilers/pymol/properties.ts b/src/mol-script/transpilers/pymol/properties.ts
index 3cc47832a893b21872dc2829847065530441ef5c..5b2b068ddce190213a17e661df728d67177a8a8c 100644
--- a/src/mol-script/transpilers/pymol/properties.ts
+++ b/src/mol-script/transpilers/pymol/properties.ts
@@ -10,7 +10,7 @@ const B = MolScriptBuilder;
 import { PropertyDict } from '../types';
 
 const reFloat = /[-+]?[0-9]*\.?[0-9]+/;
-//const rePosInt = /[0-9]+/;
+// const rePosInt = /[0-9]+/;
 
 function atomNameListMap(x: string) { return x.split('+').map(B.atomName); }
 function listMap(x: string) { return x.split('+').map(x => x.replace(/^["']|["']$/g, '')); }
@@ -105,14 +105,14 @@ export const properties: PropertyDict = {
     id: {
         '@desc': 'external-index-number a single integer',
         '@examples': ['id 23'],
-	regex: /[0-9+-]+/, map: listOrRangeMap,
+        regex: /[0-9+-]+/, map: listOrRangeMap,
         level: 'atom-test', property: B.ammp('id')
     },
     index: {
         '@desc': 'internal-index-number a single integer',
         '@examples': ['index 11'],
         regex: /[0-9+-]+/, map: listOrRangeMap,
-        level: 'atom-test',property: B.ammp('id')
+        level: 'atom-test', property: B.ammp('id')
     },
     ss: {
         '@desc': 'secondary-structure-type list of single letters. Helical regions should be assigned H and sheet regions S. Loop regions can either be assigned L or be blank.',
diff --git a/src/mol-script/transpilers/rasmol/examples.ts b/src/mol-script/transpilers/rasmol/examples.ts
index 56755748565b46a2744e6dd5ec7321d192038dca..9958050862dbc192c7935f350606bf42e8eaddd6 100644
--- a/src/mol-script/transpilers/rasmol/examples.ts
+++ b/src/mol-script/transpilers/rasmol/examples.ts
@@ -6,7 +6,7 @@
  * @author Koya Sakuma
  */
 
-export default [{
+export const rasmolSelectionsExamples = [{
     name: 'Residue 50 or 135',
     value: '50 or 135'
 }, {
@@ -24,4 +24,4 @@ export default [{
 }, {
     name: 'Pyrimidine residues',
     value: 'pyrimidine'
-}]
+}];
diff --git a/src/mol-script/transpilers/rasmol/keywords.ts b/src/mol-script/transpilers/rasmol/keywords.ts
index 6b692089837e7c087fd14e5b2866a08c2048c7d9..91c3906e62ea5badd4d7c3372bf2e37357b2ca69 100644
--- a/src/mol-script/transpilers/rasmol/keywords.ts
+++ b/src/mol-script/transpilers/rasmol/keywords.ts
@@ -1,5 +1,5 @@
-/**                                                                                                                                        
- * Copyright (c) 2017-2021 mol* contributors, licensed under MIT, See LICENSE file for more info.                                           
+/**
+ * Copyright (c) 2017-2021 mol* contributors, licensed under MIT, See LICENSE file for more info.
  * @author Alexander Rose <alexander.rose@weirdbyte.de>                                                                                      * @author Panagiotis Tourlas <panagiot_tourlov@hotmail.com>                                                                                 *
  * @author Koya Sakuma                                                                                                                       * This module was based on jmol transpiler from MolQL and modified in similar manner as pymol and vmd tranpilers.
 **/
@@ -17,49 +17,49 @@ const Backbone = {
 
 
 function nucleicExpr() {
-  return B.struct.combinator.merge([
-      B.struct.generator.atomGroups({
+    return B.struct.combinator.merge([
+        B.struct.generator.atomGroups({
 	  'residue-test': B.core.set.has([
-              B.set(...['G', 'C', 'A', 'T', 'U', 'I', 'DG', 'DC', 'DA', 'DT', 'DU', 'DI', '+G', '+C', '+A', '+T', '+U', '+I']),
-              B.ammp('label_comp_id')
+                B.set(...['G', 'C', 'A', 'T', 'U', 'I', 'DG', 'DC', 'DA', 'DT', 'DU', 'DI', '+G', '+C', '+A', '+T', '+U', '+I']),
+                B.ammp('label_comp_id')
 	  ])
-      }),
-      B.struct.filter.pick({
+        }),
+        B.struct.filter.pick({
 	  0: B.struct.generator.atomGroups({
-              'group-by': B.ammp('residueKey')
+                'group-by': B.ammp('residueKey')
 	  }),
 	  test: B.core.logic.and([
-              B.core.rel.eq([ B.struct.atomSet.atomCount(), 1 ]),
-              B.core.rel.eq([ B.ammp('label_atom_id'), B.atomName('P') ]),
+                B.core.rel.eq([B.struct.atomSet.atomCount(), 1]),
+                B.core.rel.eq([B.ammp('label_atom_id'), B.atomName('P')]),
 	  ])
-      }),
-      B.struct.filter.pick({
+        }),
+        B.struct.filter.pick({
 	  0: B.struct.generator.atomGroups({
-              'group-by': B.ammp('residueKey')
+                'group-by': B.ammp('residueKey')
 	  }),
 	  test: B.core.logic.or([
-              B.core.set.isSubset([
-		  h.atomNameSet([ "C1'", "C2'", "O3'", "C3'", "C4'", "C5'", "O5'" ]),
+                B.core.set.isSubset([
+		  h.atomNameSet(["C1'", "C2'", "O3'", "C3'", "C4'", "C5'", "O5'"]),
 		  B.ammpSet('label_atom_id')
-              ]),
-              B.core.set.isSubset([
-		  h.atomNameSet([ 'C1*', 'C2*', 'O3*', 'C3*', 'C4*', 'C5*', 'O5*' ]),
+                ]),
+                B.core.set.isSubset([
+		  h.atomNameSet(['C1*', 'C2*', 'O3*', 'C3*', 'C4*', 'C5*', 'O5*']),
 		  B.ammpSet('label_atom_id')
-              ])
+                ])
 	  ])
-      })
-  ])
+        })
+    ]);
 }
 
 
 
 const ResDict = {
     aliphatic: ['ALA', 'GLY', 'ILE', 'LEU', 'VAL'],
-    amino: ['ALA', 'ARG', 'ASN', 'ASP', 'CYS', 'GLN', 'GLU', 'GLY', 'HIS', 'ILE', 'LEU', 'LYS', 'MET', 'PHE', 'PRO', 'SER', 'THR', 'TRP', 'TYR', 'VAL', 'ASX', 'GLX', 'UNK', ],
+    amino: ['ALA', 'ARG', 'ASN', 'ASP', 'CYS', 'GLN', 'GLU', 'GLY', 'HIS', 'ILE', 'LEU', 'LYS', 'MET', 'PHE', 'PRO', 'SER', 'THR', 'TRP', 'TYR', 'VAL', 'ASX', 'GLX', 'UNK'],
     acidic: ['ASP', 'GLU'],
     aromatic: ['HIS', 'PHE', 'TRP', 'TYR'],
     basic: ['ARG', 'HIS', 'LYS'],
-    buried: ['ALA','CYS', 'ILE', 'LEU', 'MET', 'PHE', 'TRP', 'VAL'],
+    buried: ['ALA', 'CYS', 'ILE', 'LEU', 'MET', 'PHE', 'TRP', 'VAL'],
     cg: ['CYT', 'C', 'GUA', 'G'],
     cyclic: ['HIS', 'PHE', 'PRO', 'TRP', 'TYR'],
     hydrophobic: ['ALA', 'GLY', 'ILE', 'LEU', 'MET', 'PHE', 'PRO', 'TRP', 'TYR', 'VAL'],
@@ -73,281 +73,281 @@ const ResDict = {
 
 
 export const keywords: KeywordDict = {
-  // general terms
-  all: {
-      '@desc': 'all atoms; same as *',
-      abbr: ['*'],
-      map: () => B.struct.generator.all()
-  },
+    // general terms
+    all: {
+        '@desc': 'all atoms; same as *',
+        abbr: ['*'],
+        map: () => B.struct.generator.all()
+    },
     none: {
-	'@desc': 'no atoms',
-	map: () => B.struct.generator.empty()
-  },
+        '@desc': 'no atoms',
+        map: () => B.struct.generator.empty()
+    },
     selected: {
-	'@desc': 'atoms that have been selected; defaults to all when a file is first loaded'
+        '@desc': 'atoms that have been selected; defaults to all when a file is first loaded'
     },
     unitcell: {
-	'@desc': 'atoms within the current unitcell, which may be offset. This includes atoms on the faces and at the vertices of the unitcell.'
+        '@desc': 'atoms within the current unitcell, which may be offset. This includes atoms on the faces and at the vertices of the unitcell.'
     },
     ions: {
-	'@desc': '(specifically the PDB designations "PO4" and "SO4")'
+        '@desc': '(specifically the PDB designations "PO4" and "SO4")'
     },
     ligand: {
-	'@desc': '(originally "hetero and not solvent"; changed to "!(protein,nucleic,water,UREA)" for Jmol 12.2)'
+        '@desc': '(originally "hetero and not solvent"; changed to "!(protein,nucleic,water,UREA)" for Jmol 12.2)'
     },
     nucleic: {
-	'@desc': 'any group that (a) has one of the following group names: G, C, A, T, U, I, DG, DC, DA, DT, DU, DI, +G, +C, +A, +T, +U, +I; or (b) can be identified as a group that is only one atom, with name "P"; or (c) has all of the following atoms (prime, \', can replace * here): C1*, C2*, C3*, O3*, C4*, C5*, and O5*.',
-	map: () => nucleicExpr()
+        '@desc': 'any group that (a) has one of the following group names: G, C, A, T, U, I, DG, DC, DA, DT, DU, DI, +G, +C, +A, +T, +U, +I; or (b) can be identified as a group that is only one atom, with name "P"; or (c) has all of the following atoms (prime, \', can replace * here): C1*, C2*, C3*, O3*, C4*, C5*, and O5*.',
+        map: () => nucleicExpr()
     },
     purine: {
-	'@desc': 'any nucleic group that (a) has one of the following group names: A, G, I, DA, DG, DI, +A, +G, or +I; or (b) also has atoms N7, C8, and N9.',
-	map: () => B.struct.modifier.intersectBy({
+        '@desc': 'any nucleic group that (a) has one of the following group names: A, G, I, DA, DG, DI, +A, +G, or +I; or (b) also has atoms N7, C8, and N9.',
+        map: () => B.struct.modifier.intersectBy({
 	    0: nucleicExpr(),
 	    by: B.struct.combinator.merge([
-		B.struct.generator.atomGroups({
+                B.struct.generator.atomGroups({
 		    'residue-test': B.core.set.has([
-			B.set(...['A', 'G', 'I', 'DA', 'DG', 'DI', '+A', '+G', '+I']),
-			B.ammp('label_comp_id')
+                        B.set(...['A', 'G', 'I', 'DA', 'DG', 'DI', '+A', '+G', '+I']),
+                        B.ammp('label_comp_id')
 		    ])
-		}),
-		B.struct.filter.pick({
+                }),
+                B.struct.filter.pick({
 		    0: B.struct.generator.atomGroups({
-			'group-by': B.ammp('residueKey')
+                        'group-by': B.ammp('residueKey')
 		    }),
 		    test: B.core.set.isSubset([
-			h.atomNameSet([ 'N7', 'C8', 'N9' ]),
-			B.ammpSet('label_atom_id')
+                        h.atomNameSet(['N7', 'C8', 'N9']),
+                        B.ammpSet('label_atom_id')
 		    ])
-		})
+                })
 	    ])
-	})
+        })
     },
     pyrimidine: {
-	'@desc': 'any nucleic group that (a) has one of the following group names: C, T, U, DC, DT, DU, +C, +T, +U; or (b) also has atom O2.',
-	map: () => B.struct.modifier.intersectBy({
+        '@desc': 'any nucleic group that (a) has one of the following group names: C, T, U, DC, DT, DU, +C, +T, +U; or (b) also has atom O2.',
+        map: () => B.struct.modifier.intersectBy({
 	    0: nucleicExpr(),
 	    by: B.struct.combinator.merge([
-		B.struct.generator.atomGroups({
+                B.struct.generator.atomGroups({
 		    'residue-test': B.core.set.has([
-			B.set(...['C', 'T', 'U', 'DC', 'DT', 'DU', '+C', '+T', '+U']),
-			B.ammp('label_comp_id')
+                        B.set(...['C', 'T', 'U', 'DC', 'DT', 'DU', '+C', '+T', '+U']),
+                        B.ammp('label_comp_id')
 		    ])
-		}),
-		B.struct.filter.pick({
+                }),
+                B.struct.filter.pick({
 		    0: B.struct.generator.atomGroups({
-			'group-by': B.ammp('residueKey')
+                        'group-by': B.ammp('residueKey')
 		    }),
 		    test: B.core.logic.or([
-			B.core.set.has([
+                        B.core.set.has([
 			    B.ammpSet('label_atom_id'),
 			    B.atomName('O2*')
-			]),
-			B.core.set.has([
+                        ]),
+                        B.core.set.has([
 			    B.ammpSet('label_atom_id'),
 			    B.atomName("O2'")
-			])
+                        ])
 		    ])
-		})
+                })
 	    ])
-	})
+        })
     },
     dna: {
-	'@desc': 'any nucleic group that (a) has one of the following group names: DG, DC, DA, DT, DU, DI, T, +G, +C, +A, +T; or (b) has neither atom O2* or O2\'.',
-	map: () => B.struct.modifier.intersectBy({
+        '@desc': 'any nucleic group that (a) has one of the following group names: DG, DC, DA, DT, DU, DI, T, +G, +C, +A, +T; or (b) has neither atom O2* or O2\'.',
+        map: () => B.struct.modifier.intersectBy({
 	    0: nucleicExpr(),
 	    by: B.struct.combinator.merge([
-		B.struct.generator.atomGroups({
+                B.struct.generator.atomGroups({
 		    'residue-test': B.core.set.has([
-			B.set(...['DG', 'DC', 'DA', 'DT', 'DU', 'DI', 'T', '+G', '+C', '+A', '+T']),
-			B.ammp('label_comp_id')
+                        B.set(...['DG', 'DC', 'DA', 'DT', 'DU', 'DI', 'T', '+G', '+C', '+A', '+T']),
+                        B.ammp('label_comp_id')
 		    ])
-		}),
-		B.struct.filter.pick({
+                }),
+                B.struct.filter.pick({
 		    0: B.struct.generator.atomGroups({
-			'group-by': B.ammp('residueKey')
+                        'group-by': B.ammp('residueKey')
 		    }),
 		    test: B.core.logic.not([
-			B.core.logic.or([
+                        B.core.logic.or([
 			    B.core.set.has([
-				B.ammpSet('label_atom_id'),
-				B.atomName('O2*')
+                                B.ammpSet('label_atom_id'),
+                                B.atomName('O2*')
 			    ]),
 			    B.core.set.has([
-				B.ammpSet('label_atom_id'),
-				B.atomName("O2'")
+                                B.ammpSet('label_atom_id'),
+                                B.atomName("O2'")
 			    ])
-			])
+                        ])
 		    ])
-		})
+                })
 	    ])
-	})
+        })
     },
     rna: {
-	'@desc': 'any nucleic group that (a) has one of the following group names: G, C, A, U, I, +U, +I; or (b) has atom O2* or O2\'.',
-	map: () => B.struct.modifier.intersectBy({
+        '@desc': 'any nucleic group that (a) has one of the following group names: G, C, A, U, I, +U, +I; or (b) has atom O2* or O2\'.',
+        map: () => B.struct.modifier.intersectBy({
 	    0: nucleicExpr(),
 	    by: B.struct.combinator.merge([
-		B.struct.generator.atomGroups({
+                B.struct.generator.atomGroups({
 		    'residue-test': B.core.set.has([
-			B.set(...['G', 'C', 'A', 'U', 'I', '+U', '+I']),
-			B.ammp('label_comp_id')
+                        B.set(...['G', 'C', 'A', 'U', 'I', '+U', '+I']),
+                        B.ammp('label_comp_id')
 		    ])
-		}),
-		B.struct.filter.pick({
+                }),
+                B.struct.filter.pick({
 		    0: B.struct.generator.atomGroups({
-			'group-by': B.ammp('residueKey')
+                        'group-by': B.ammp('residueKey')
 		    }),
 		    test: B.core.logic.or([
-			B.core.set.has([
+                        B.core.set.has([
 			    B.ammpSet('label_atom_id'),
 			    B.atomName('O2*')
-			]),
-			B.core.set.has([
+                        ]),
+                        B.core.set.has([
 			    B.ammpSet('label_atom_id'),
 			    B.atomName("O2'")
-			])
+                        ])
 		    ])
-		})
+                })
 	    ])
-	})
+        })
     },
     protein: {
-	'@desc': 'defined as a group that (a) has one of the following group names: ALA, ARG, ASN, ASP, CYS, GLN, GLU, GLY, HIS, ILE, LEU}, LYS, MET, PHE, PRO, SER, THR, TRP, TYR, VAL, ASX, GLX, or UNK; or (b) contains PDB atom designations [C, O, CA, and N] bonded correctly; or (c) does not contain "O" but contains [C, CA, and N] bonded correctly; or (d) has only one atom, which has name CA and does not have the group name CA (indicating a calcium atom).',
-	map: () => proteinExpr()	
+        '@desc': 'defined as a group that (a) has one of the following group names: ALA, ARG, ASN, ASP, CYS, GLN, GLU, GLY, HIS, ILE, LEU}, LYS, MET, PHE, PRO, SER, THR, TRP, TYR, VAL, ASX, GLX, or UNK; or (b) contains PDB atom designations [C, O, CA, and N] bonded correctly; or (c) does not contain "O" but contains [C, CA, and N] bonded correctly; or (d) has only one atom, which has name CA and does not have the group name CA (indicating a calcium atom).',
+        map: () => proteinExpr()
     },
     acidic: {
-	'@desc': 'ASP GLU',
-      map: () => h.resnameExpr(ResDict.acidic)
-  },
+        '@desc': 'ASP GLU',
+        map: () => h.resnameExpr(ResDict.acidic)
+    },
     acyclic: {
-      '@desc': 'amino and not cyclic',
-      map: () => B.struct.modifier.intersectBy({
-	0: h.resnameExpr(ResDict.amino),
-	by: h.invertExpr(h.resnameExpr(ResDict.cyclic))
-    })
-  },
+        '@desc': 'amino and not cyclic',
+        map: () => B.struct.modifier.intersectBy({
+            0: h.resnameExpr(ResDict.amino),
+            by: h.invertExpr(h.resnameExpr(ResDict.cyclic))
+        })
+    },
     aliphatic: {
-      '@desc': 'ALA GLY ILE LEU VAL',
-      map: () => h.resnameExpr(ResDict.aliphatic)
-  },
+        '@desc': 'ALA GLY ILE LEU VAL',
+        map: () => h.resnameExpr(ResDict.aliphatic)
+    },
     amino: {
-      '@desc': 'all twenty standard amino acids, plus ASX, GLX, UNK',
-      map: () => h.resnameExpr(ResDict.amino)
-  },
+        '@desc': 'all twenty standard amino acids, plus ASX, GLX, UNK',
+        map: () => h.resnameExpr(ResDict.amino)
+    },
     aromatic: {
-      '@desc': 'HIS PHE TRP TYR (see also "isaromatic" for aromatic bonds)',
-      map: () => h.resnameExpr(ResDict.aromatic)
-  },
+        '@desc': 'HIS PHE TRP TYR (see also "isaromatic" for aromatic bonds)',
+        map: () => h.resnameExpr(ResDict.aromatic)
+    },
     basic: {
-      '@desc': 'ARG HIS LYS',
-      map: () => h.resnameExpr(ResDict.basic)
-  },
+        '@desc': 'ARG HIS LYS',
+        map: () => h.resnameExpr(ResDict.basic)
+    },
     buried: {
-      '@desc': 'ALA CYS ILE LEU MET PHE TRP VAL',
-      map: () => h.resnameExpr(ResDict.buried)
-  },
+        '@desc': 'ALA CYS ILE LEU MET PHE TRP VAL',
+        map: () => h.resnameExpr(ResDict.buried)
+    },
     charged: {
-      '@desc': 'same as acidic or basic -- ASP GLU, ARG HIS LYS',
-      map: () => h.resnameExpr(ResDict.acidic.concat(ResDict.basic))
-  },
+        '@desc': 'same as acidic or basic -- ASP GLU, ARG HIS LYS',
+        map: () => h.resnameExpr(ResDict.acidic.concat(ResDict.basic))
+    },
     cyclic: {
-      '@desc': 'HIS PHE PRO TRP TYR',
-      map: () => h.resnameExpr(ResDict.cyclic)
-  },
+        '@desc': 'HIS PHE PRO TRP TYR',
+        map: () => h.resnameExpr(ResDict.cyclic)
+    },
     helix: {
-      '@desc': 'secondary structure-related.',
-      map: () => B.struct.generator.atomGroups({
-	'residue-test': B.core.flags.hasAny([
-          B.struct.type.secondaryStructureFlags(['helix']),
-          B.ammp('secondaryStructureFlags')
-      ])
-    })
-  },
+        '@desc': 'secondary structure-related.',
+        map: () => B.struct.generator.atomGroups({
+            'residue-test': B.core.flags.hasAny([
+                B.struct.type.secondaryStructureFlags(['helix']),
+                B.ammp('secondaryStructureFlags')
+            ])
+        })
+    },
     hetero: {
-      '@desc': 'PDB atoms designated as HETATM',
-      map: () => B.struct.generator.atomGroups({
-	'atom-test': B.ammp('isHet')
-    })
-  },
+        '@desc': 'PDB atoms designated as HETATM',
+        map: () => B.struct.generator.atomGroups({
+            'atom-test': B.ammp('isHet')
+        })
+    },
     hydrophobic: {
-      '@desc': 'ALA GLY ILE LEU MET PHE PRO TRP TYR VAL',
-      map: () => h.resnameExpr(ResDict.hydrophobic)
-  },
+        '@desc': 'ALA GLY ILE LEU MET PHE PRO TRP TYR VAL',
+        map: () => h.resnameExpr(ResDict.hydrophobic)
+    },
     large: {
-      '@desc': 'ARG GLU GLN HIS ILE LEU LYS MET PHE TRP TYR',
-      map: () => h.resnameExpr(ResDict.large)
-  },
+        '@desc': 'ARG GLU GLN HIS ILE LEU LYS MET PHE TRP TYR',
+        map: () => h.resnameExpr(ResDict.large)
+    },
     medium: {
-      '@desc': 'ASN ASP CYS PRO THR VAL',
-      map: () => h.resnameExpr(ResDict.medium)
-  },
+        '@desc': 'ASN ASP CYS PRO THR VAL',
+        map: () => h.resnameExpr(ResDict.medium)
+    },
     negative: {
-      '@desc': 'same as acidic -- ASP GLU',
-      map: () => h.resnameExpr(ResDict.acidic)
-  },
+        '@desc': 'same as acidic -- ASP GLU',
+        map: () => h.resnameExpr(ResDict.acidic)
+    },
     neutral: {
-      '@desc': 'amino and not (acidic or basic)',
-      map: () => B.struct.modifier.intersectBy({
-	0: h.resnameExpr(ResDict.amino),
-	by: h.invertExpr(h.resnameExpr(ResDict.acidic.concat(ResDict.basic)))
-    })
-  },
+        '@desc': 'amino and not (acidic or basic)',
+        map: () => B.struct.modifier.intersectBy({
+            0: h.resnameExpr(ResDict.amino),
+            by: h.invertExpr(h.resnameExpr(ResDict.acidic.concat(ResDict.basic)))
+        })
+    },
     polar: {
-      '@desc': 'amino and not hydrophobic',
-      map: () => B.struct.modifier.intersectBy({
-	0: h.resnameExpr(ResDict.amino),
-	by: h.invertExpr(h.resnameExpr(ResDict.hydrophobic))
-    })
-  },
+        '@desc': 'amino and not hydrophobic',
+        map: () => B.struct.modifier.intersectBy({
+            0: h.resnameExpr(ResDict.amino),
+            by: h.invertExpr(h.resnameExpr(ResDict.hydrophobic))
+        })
+    },
     positive: {
-      '@desc': 'same as basic -- ARG HIS LYS',
-      map: () => h.resnameExpr(ResDict.basic)
-  },
+        '@desc': 'same as basic -- ARG HIS LYS',
+        map: () => h.resnameExpr(ResDict.basic)
+    },
     sheet: {
-      '@desc': 'secondary structure-related',
-      map: () => B.struct.generator.atomGroups({
-	'residue-test': B.core.flags.hasAny([
-          B.struct.type.secondaryStructureFlags(['sheet']),
-          B.ammp('secondaryStructureFlags')
-      ])
-    })
-  },
+        '@desc': 'secondary structure-related',
+        map: () => B.struct.generator.atomGroups({
+            'residue-test': B.core.flags.hasAny([
+                B.struct.type.secondaryStructureFlags(['sheet']),
+                B.ammp('secondaryStructureFlags')
+            ])
+        })
+    },
     small: {
-      '@desc': 'ALA GLY SER',
-      map: () => h.resnameExpr(ResDict.small)
-  },
+        '@desc': 'ALA GLY SER',
+        map: () => h.resnameExpr(ResDict.small)
+    },
     turn: {
-      '@desc': 'secondary structure-related',
-      map: () => B.struct.generator.atomGroups({
-	'residue-test': B.core.flags.hasAny([
-          B.struct.type.secondaryStructureFlags(['turn']),
-          B.ammp('secondaryStructureFlags')
-      ])
-    })
-  },
+        '@desc': 'secondary structure-related',
+        map: () => B.struct.generator.atomGroups({
+            'residue-test': B.core.flags.hasAny([
+                B.struct.type.secondaryStructureFlags(['turn']),
+                B.ammp('secondaryStructureFlags')
+            ])
+        })
+    },
     alpha: {
-      '@desc': '(*.CA)',
-      map: () => B.struct.generator.atomGroups({
-	'atom-test': B.core.rel.eq([
-          B.atomName('CA'),
-          B.ammp('label_atom_id')
-      ])
-    })
-  },
+        '@desc': '(*.CA)',
+        map: () => B.struct.generator.atomGroups({
+            'atom-test': B.core.rel.eq([
+                B.atomName('CA'),
+                B.ammp('label_atom_id')
+            ])
+        })
+    },
     base: {
-      '@desc': '(nucleic bases)'
-  },
+        '@desc': '(nucleic bases)'
+    },
     backbone: {
-      '@desc': '(*.C, *.CA, *.N, and all nucleic other than the bases themselves)',
-      abbr: ['mainchain'],
-      map: () => backboneExpr()
-  },
+        '@desc': '(*.C, *.CA, *.N, and all nucleic other than the bases themselves)',
+        abbr: ['mainchain'],
+        map: () => backboneExpr()
+    },
     sidechain: {
-	'@desc': '((protein or nucleic) and not backbone)'
-  },
+        '@desc': '((protein or nucleic) and not backbone)'
+    },
     solvent: {
-	'@desc': 'PDB "HOH", water, also the connected set of H-O-H in any model',
-	    map: () => h.resnameExpr(ResDict.solvent)	
+        '@desc': 'PDB "HOH", water, also the connected set of H-O-H in any model',
+	    map: () => h.resnameExpr(ResDict.solvent)
     },
 };
 
diff --git a/src/mol-script/transpilers/rasmol/markdown-docs.ts b/src/mol-script/transpilers/rasmol/markdown-docs.ts
index 68f694b8d7ae2d03141de431a27c3d6e6c349754..93e23c577ea0a78a1d3436a9eab45412dbff6dc7 100644
--- a/src/mol-script/transpilers/rasmol/markdown-docs.ts
+++ b/src/mol-script/transpilers/rasmol/markdown-docs.ts
@@ -1,9 +1,9 @@
-/* 
- * Copyright (c) 2017-2021 mol* contributors, licensed under MIT, See LICENSE file for more info.                                           
- * @author Alexander Rose <alexander.rose@weirdbyte.de>                                                                                     
- * @author Panagiotis Tourlas <panagiot_tourlov@hotmail.com> 
- * 
- * @author Koya Sakuma 
+/*
+ * Copyright (c) 2017-2021 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * @author Alexander Rose <alexander.rose@weirdbyte.de>
+ * @author Panagiotis Tourlas <panagiot_tourlov@hotmail.com>
+ *
+ * @author Koya Sakuma
  * This module is based on jmol transpiler from MolQL and modified in similar manner as pymol and vmd tranpilers.                                             */
 
 import { properties } from './properties';
@@ -11,53 +11,53 @@ import { operators } from './operators';
 import { keywords } from './keywords';
 
 
-const docs: string[] = [
+const _docs: string[] = [
     'Jmol',
     '============',
     '--------------------------------',
     ''
 ];
 
-docs.push(`## Properties\n\n`);
-docs.push('--------------------------------\n');
+_docs.push(`## Properties\n\n`);
+_docs.push('--------------------------------\n');
 for (const name in properties) {
-    if (properties[name].isUnsupported) continue
+    if (properties[name].isUnsupported) continue;
 
-    const names = [name]
-    if (properties[name].abbr) names.push(...properties[name].abbr!)
-    docs.push(`\`\`\`\n${names.join(', ')}\n\`\`\`\n`);
+    const names = [name];
+    if (properties[name].abbr) names.push(...properties[name].abbr!);
+    _docs.push(`\`\`\`\n${names.join(', ')}\n\`\`\`\n`);
 
     if (properties[name]['@desc']) {
-        docs.push(`*${properties[name]['@desc']}*\n`);
+        _docs.push(`*${properties[name]['@desc']}*\n`);
     }
 }
 
-docs.push(`## Operators\n\n`);
-docs.push('--------------------------------\n');
+_docs.push(`## Operators\n\n`);
+_docs.push('--------------------------------\n');
 operators.forEach(o => {
-    if (o.isUnsupported) return
+    if (o.isUnsupported) return;
 
-    const names = [o.name]
-    if (o.abbr) names.push(...o.abbr!)
-    docs.push(`\`\`\`\n${names.join(', ')}\n\`\`\`\n`);
+    const names = [o.name];
+    if (o.abbr) names.push(...o.abbr!);
+    _docs.push(`\`\`\`\n${names.join(', ')}\n\`\`\`\n`);
 
     if (o['@desc']) {
-        docs.push(`*${o['@desc']}*\n`);
+        _docs.push(`*${o['@desc']}*\n`);
     }
-})
+});
 
-docs.push(`## Keywords\n\n`);
-docs.push('--------------------------------\n');
+_docs.push(`## Keywords\n\n`);
+_docs.push('--------------------------------\n');
 for (const name in keywords) {
-    if (!keywords[name].map) continue
+    if (!keywords[name].map) continue;
 
-    const names = [name]
-    if (keywords[name].abbr) names.push(...keywords[name].abbr!)
-    docs.push(`\`\`\`\n${names.join(', ')}\n\`\`\`\n`);
+    const names = [name];
+    if (keywords[name].abbr) names.push(...keywords[name].abbr!);
+    _docs.push(`\`\`\`\n${names.join(', ')}\n\`\`\`\n`);
 
     if (keywords[name]['@desc']) {
-        docs.push(`*${keywords[name]['@desc']}*\n`);
+        _docs.push(`*${keywords[name]['@desc']}*\n`);
     }
 }
 
-export default docs.join('\n')
+export const docs = _docs.join('\n');
diff --git a/src/mol-script/transpilers/rasmol/operators.ts b/src/mol-script/transpilers/rasmol/operators.ts
index 455000f382486bbbdb8b240afabc6e70ddcb9b83..0344052e94ac204f39a56b4a36a30c5b15c4aec6 100644
--- a/src/mol-script/transpilers/rasmol/operators.ts
+++ b/src/mol-script/transpilers/rasmol/operators.ts
@@ -1,9 +1,9 @@
-/*       
- * Copyright (c) 2017-2021 mol* contributors, licensed under MIT, See LICENSE file for more info.    
- * @author Alexander Rose <alexander.rose@weirdbyte.de>               
- * @author Panagiotis Tourlas <panagiot_tourlov@hotmail.com>           
- *                                                                    
- * @author Koya Sakuma                                                
+/*
+ * Copyright (c) 2017-2021 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * @author Alexander Rose <alexander.rose@weirdbyte.de>
+ * @author Panagiotis Tourlas <panagiot_tourlov@hotmail.com>
+ *
+ * @author Koya Sakuma
  * This module is based on jmol transpiler from MolQL and modified in similar manner as pymol and vmd tranpilers.                                             \
  */
 
@@ -13,33 +13,33 @@ import * as h from '../helper';
 import { MolScriptBuilder } from '../../../mol-script/language/builder';
 const B = MolScriptBuilder;
 import { OperatorList } from '../types';
-//import { Expression } from '../../language/expression';
+// import { Expression } from '../../language/expression';
 
 
 export const operators: OperatorList = [
-  {
-    '@desc': 'Selects atoms that are not included in s1.',
-    '@examples': ['not ARG'],
-    name: 'not',
-    type: h.prefix,
-    rule: P.MonadicParser.alt(P.MonadicParser.regex(/NOT/i).skip(P.MonadicParser.whitespace), P.MonadicParser.string('!').skip(P.MonadicParser.optWhitespace)),
-    map: (op, selection) => h.invertExpr(selection),
-  },
-  {
-    '@desc': 'Selects atoms included in both s1 and s2.',
-    '@examples': ['ASP and .CA'],
-    name: 'and',
-    type: h.binaryLeft,
-    rule: h.infixOp(/AND|&/i),
-    map: (op, selection, by) => B.struct.modifier.intersectBy({ 0: selection, by })
-  },
-  {
-    '@desc': 'Selects atoms included in either s1 or s2.',
-    '@examples': ['ASP or GLU'],
-    name: 'or',
-    type: h.binaryLeft,
-    rule: h.infixOp(/OR|\|/i),
-    map: (op, s1, s2) => B.struct.combinator.merge([s1, s2])
-  }
-]
+    {
+        '@desc': 'Selects atoms that are not included in s1.',
+        '@examples': ['not ARG'],
+        name: 'not',
+        type: h.prefix,
+        rule: P.MonadicParser.alt(P.MonadicParser.regex(/NOT/i).skip(P.MonadicParser.whitespace), P.MonadicParser.string('!').skip(P.MonadicParser.optWhitespace)),
+        map: (op, selection) => h.invertExpr(selection),
+    },
+    {
+        '@desc': 'Selects atoms included in both s1 and s2.',
+        '@examples': ['ASP and .CA'],
+        name: 'and',
+        type: h.binaryLeft,
+        rule: h.infixOp(/AND|&/i),
+        map: (op, selection, by) => B.struct.modifier.intersectBy({ 0: selection, by })
+    },
+    {
+        '@desc': 'Selects atoms included in either s1 or s2.',
+        '@examples': ['ASP or GLU'],
+        name: 'or',
+        type: h.binaryLeft,
+        rule: h.infixOp(/OR|\|/i),
+        map: (op, s1, s2) => B.struct.combinator.merge([s1, s2])
+    }
+];
 
diff --git a/src/mol-script/transpilers/rasmol/parser.ts b/src/mol-script/transpilers/rasmol/parser.ts
index ff2c56ab8b826f7f32e9921a4e1bfa5fc4067d95..cd2a6c711e6335b583ef2d8ae52d85937f489fdd 100644
--- a/src/mol-script/transpilers/rasmol/parser.ts
+++ b/src/mol-script/transpilers/rasmol/parser.ts
@@ -1,7 +1,7 @@
 /**
- * Copyright (c) 2017-2021 mol* contributors, licensed under MIT, See LICENSE file for more info.                                           
+ * Copyright (c) 2017-2021 mol* contributors, licensed under MIT, See LICENSE file for more info.
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
- * @author Panagiotis Tourlas <panagiot_tourlov@hotmail.com>                                                                     
+ * @author Panagiotis Tourlas <panagiot_tourlov@hotmail.com>
  * @author Koya Sakuma
  * This module is based on jmol tranpiler from MolQL and modified in similar manner as pymol and vmd tranpilers.
  **/
@@ -18,147 +18,147 @@ import { AtomGroupArgs } from '../types';
 import { Transpiler } from '../transpiler';
 import { OperatorList } from '../types';
 
-//const propertiesDict = h.getPropertyRules(properties);
+// const propertiesDict = h.getPropertyRules(properties);
 
-//const slash = P.MonadicParser.string('/');
+// const slash = P.MonadicParser.string('/');
 
 
 // <, <=, =, >=, >, !=, and LIKE
 const valueOperators: OperatorList = [
-  {
-    '@desc': 'value comparisons',
-    '@examples': [],
-    name: '=',
-    abbr: ['=='],
-    type: h.binaryLeft,
-    rule: P.MonadicParser.regexp(/\s*(LIKE|>=|<=|=|!=|>|<)\s*/i, 1),
-    map: (op, e1, e2) => {
-      // console.log(op, e1, e2)
-      let expr
-      if (e1 === 'structure') {
-        expr = B.core.flags.hasAny([B.ammp('secondaryStructureFlags'), structureMap(e2)])
-      } else if (e2 === 'structure') {
-        expr = B.core.flags.hasAny([B.ammp('secondaryStructureFlags'), structureMap(e1)])
-      } else if (e1.head === 'core.type.regex') {
-        expr = B.core.str.match([ e1, B.core.type.str([e2]) ])
-      } else if (e2.head === 'core.type.regex') {
-        expr = B.core.str.match([ e2, B.core.type.str([e1]) ])
-      } else if (op.toUpperCase() === 'LIKE') {
-        if (e1.head) {
-          expr = B.core.str.match([
-            B.core.type.regex([`^${e2}$`, 'i']),
-            B.core.type.str([e1])
-          ])
-        } else {
-          expr = B.core.str.match([
-            B.core.type.regex([`^${e1}$`, 'i']),
-            B.core.type.str([e2])
-          ])
+    {
+        '@desc': 'value comparisons',
+        '@examples': [],
+        name: '=',
+        abbr: ['=='],
+        type: h.binaryLeft,
+        rule: P.MonadicParser.regexp(/\s*(LIKE|>=|<=|=|!=|>|<)\s*/i, 1),
+        map: (op, e1, e2) => {
+            // console.log(op, e1, e2)
+            let expr;
+            if (e1 === 'structure') {
+                expr = B.core.flags.hasAny([B.ammp('secondaryStructureFlags'), structureMap(e2)]);
+            } else if (e2 === 'structure') {
+                expr = B.core.flags.hasAny([B.ammp('secondaryStructureFlags'), structureMap(e1)]);
+            } else if (e1.head === 'core.type.regex') {
+                expr = B.core.str.match([e1, B.core.type.str([e2])]);
+            } else if (e2.head === 'core.type.regex') {
+                expr = B.core.str.match([e2, B.core.type.str([e1])]);
+            } else if (op.toUpperCase() === 'LIKE') {
+                if (e1.head) {
+                    expr = B.core.str.match([
+                        B.core.type.regex([`^${e2}$`, 'i']),
+                        B.core.type.str([e1])
+                    ]);
+                } else {
+                    expr = B.core.str.match([
+                        B.core.type.regex([`^${e1}$`, 'i']),
+                        B.core.type.str([e2])
+                    ]);
+                }
+            }
+            if (!expr) {
+                if (e1.head) e2 = h.wrapValue(e1, e2);
+                if (e2.head) e1 = h.wrapValue(e2, e1);
+                switch (op) {
+                    case '=':
+                        expr = B.core.rel.eq([e1, e2]);
+                        break;
+                    case '!=':
+                        expr = B.core.rel.neq([e1, e2]);
+                        break;
+                    case '>':
+                        expr = B.core.rel.gr([e1, e2]);
+                        break;
+                    case '<':
+                        expr = B.core.rel.lt([e1, e2]);
+                        break;
+                    case '>=':
+                        expr = B.core.rel.gre([e1, e2]);
+                        break;
+                    case '<=':
+                        expr = B.core.rel.lte([e1, e2]);
+                        break;
+                    default: throw new Error(`value operator '${op}' not supported`);
+                }
+            }
+            return B.struct.generator.atomGroups({ 'atom-test': expr });
         }
-      }
-      if (!expr) {
-        if (e1.head) e2 = h.wrapValue(e1, e2)
-        if (e2.head) e1 = h.wrapValue(e2, e1)
-        switch (op) {
-          case '=':
-            expr = B.core.rel.eq([e1, e2])
-            break
-          case '!=':
-            expr = B.core.rel.neq([e1, e2])
-            break
-          case '>':
-            expr = B.core.rel.gr([e1, e2])
-            break
-          case '<':
-            expr = B.core.rel.lt([e1, e2])
-            break
-          case '>=':
-            expr = B.core.rel.gre([e1, e2])
-            break
-          case '<=':
-            expr = B.core.rel.lte([e1, e2])
-            break
-          default: throw new Error(`value operator '${op}' not supported`);
-        }
-      }
-      return B.struct.generator.atomGroups({ 'atom-test': expr })
     }
-  }
-]
+];
 
-function atomExpressionQuery (x: any[]) {
-  const [resno, inscode, chainname, atomname, altloc, ] = x[1]
-  const tests: AtomGroupArgs = {}
+function atomExpressionQuery(x: any[]) {
+    const [resno, inscode, chainname, atomname, altloc] = x[1];
+    const tests: AtomGroupArgs = {};
 
-  if (chainname) {
+    if (chainname) {
     // should be configurable, there is an option in Jmol to use auth or label
-    tests['chain-test'] = B.core.rel.eq([ B.ammp('auth_asym_id'), chainname ])
-  }
+        tests['chain-test'] = B.core.rel.eq([B.ammp('auth_asym_id'), chainname]);
+    }
 
-  const resProps = []
-  if (resno) resProps.push(B.core.rel.eq([ B.ammp('auth_seq_id'), resno ]))
-  if (inscode) resProps.push(B.core.rel.eq([ B.ammp('pdbx_PDB_ins_code'), inscode ]))
-  if (resProps.length) tests['residue-test'] = h.andExpr(resProps)
+    const resProps = [];
+    if (resno) resProps.push(B.core.rel.eq([B.ammp('auth_seq_id'), resno]));
+    if (inscode) resProps.push(B.core.rel.eq([B.ammp('pdbx_PDB_ins_code'), inscode]));
+    if (resProps.length) tests['residue-test'] = h.andExpr(resProps);
 
-  const atomProps = []
-  if (atomname) atomProps.push(B.core.rel.eq([ B.ammp('auth_atom_id'), atomname ]))
-  if (altloc) atomProps.push(B.core.rel.eq([ B.ammp('label_alt_id'), altloc ]))
-  if (atomProps.length) tests['atom-test'] = h.andExpr(atomProps)
+    const atomProps = [];
+    if (atomname) atomProps.push(B.core.rel.eq([B.ammp('auth_atom_id'), atomname]));
+    if (altloc) atomProps.push(B.core.rel.eq([B.ammp('label_alt_id'), altloc]));
+    if (atomProps.length) tests['atom-test'] = h.andExpr(atomProps);
 
-  return B.struct.generator.atomGroups(tests)
+    return B.struct.generator.atomGroups(tests);
 }
 
 const lang = P.MonadicParser.createLanguage({
-  Integer: () => P.MonadicParser.regexp(/-?[0-9]+/).map(Number).desc('integer'),
-
-    Parens: function (r:any) {
-    return P.MonadicParser.alt(
-      r.Parens,
-      r.Operator,
-      r.Expression
-    ).wrap(P.MonadicParser.string('('), P.MonadicParser.string(')'))
-  },
-
-    Expression: function(r:any) {
-	return P.MonadicParser.alt(
+    Integer: () => P.MonadicParser.regexp(/-?[0-9]+/).map(Number).desc('integer'),
+
+    Parens: function (r: any) {
+        return P.MonadicParser.alt(
+            r.Parens,
+            r.Operator,
+            r.Expression
+        ).wrap(P.MonadicParser.string('('), P.MonadicParser.string(')'));
+    },
+
+    Expression: function (r: any) {
+        return P.MonadicParser.alt(
 	    r.NamedAtomProperties,
 	    r.Keywords,
-	    r.Resno.lookahead(P.MonadicParser.regexp(/\s*(?!(LIKE|>=|<=|!=|[:^%/.=><]))/i)).map((x:any) => B.struct.generator.atomGroups({
-		'residue-test': B.core.rel.eq([ B.ammp('auth_seq_id'), x ])
+	    r.Resno.lookahead(P.MonadicParser.regexp(/\s*(?!(LIKE|>=|<=|!=|[:^%/.=><]))/i)).map((x: any) => B.struct.generator.atomGroups({
+                'residue-test': B.core.rel.eq([B.ammp('auth_seq_id'), x])
 	    })),
 	    r.AtomExpression.map(atomExpressionQuery),
-	    
+
 	    r.ValueQuery,
-	    
+
 	    r.Element.map((x: string) => B.struct.generator.atomGroups({
-		'atom-test': B.core.rel.eq([ B.acp('elementSymbol'), B.struct.type.elementSymbol(x) ])
+                'atom-test': B.core.rel.eq([B.acp('elementSymbol'), B.struct.type.elementSymbol(x)])
 	    })),
 	    r.Resname.map((x: string) => B.struct.generator.atomGroups({
-		'residue-test': B.core.rel.eq([ B.ammp('label_comp_id'), x ])
+                'residue-test': B.core.rel.eq([B.ammp('label_comp_id'), x])
 	    })),
-	)
+        );
     },
 
     NamedAtomProperties: function () {
-        return P.MonadicParser.alt(...h.getNamedPropertyRules(properties)); 
+        return P.MonadicParser.alt(...h.getNamedPropertyRules(properties));
     },
 
-Operator: function(r:any) {
-    return h.combineOperators(operators, P.MonadicParser.alt(r.Parens, r.Expression))
-  },
-
-AtomExpression: function(r:any) {
-    return P.MonadicParser.seq(
-	P.MonadicParser.lookahead(r.AtomPrefix),
-	P.MonadicParser.seq(
-            r.Resno.or(P.MonadicParser.of(null)),
-            r.Inscode.or(P.MonadicParser.of(null)),
-            r.Chainname.or(P.MonadicParser.of(null)),
-            r.Atomname.or(P.MonadicParser.of(null)),
-            r.Altloc.or(P.MonadicParser.of(null)),
-            r.Model.or(P.MonadicParser.of(null))),	
-    )
-  },
+    Operator: function (r: any) {
+        return h.combineOperators(operators, P.MonadicParser.alt(r.Parens, r.Expression));
+    },
+
+    AtomExpression: function (r: any) {
+        return P.MonadicParser.seq(
+            P.MonadicParser.lookahead(r.AtomPrefix),
+            P.MonadicParser.seq(
+                r.Resno.or(P.MonadicParser.of(null)),
+                r.Inscode.or(P.MonadicParser.of(null)),
+                r.Chainname.or(P.MonadicParser.of(null)),
+                r.Atomname.or(P.MonadicParser.of(null)),
+                r.Altloc.or(P.MonadicParser.of(null)),
+                r.Model.or(P.MonadicParser.of(null))),
+        );
+    },
 
     AtomPrefix: () => P.MonadicParser.regexp(/[0-9:^%/.]/).desc('atom-prefix'),
     Chainname: () => P.MonadicParser.regexp(/:([A-Za-z]{1,3})/, 1).desc('chainname'),
@@ -166,99 +166,98 @@ AtomExpression: function(r:any) {
     Element: () => P.MonadicParser.regexp(/_([A-Za-z]{1,3})/, 1).desc('element'),
     Atomname: () => P.MonadicParser.regexp(/\.([a-zA-Z0-9]{1,4})/, 1).map(B.atomName).desc('atomname'),
     Resname: () => P.MonadicParser.regexp(/[a-zA-Z0-9]{1,4}/).desc('resname'),
-    Resno: (r:any) => r.Integer.desc('resno'),
-    Resno2: (r:any) => r.split(',').Integer.desc("resno"),
+    Resno: (r: any) => r.Integer.desc('resno'),
+    Resno2: (r: any) => r.split(',').Integer.desc('resno'),
     Altloc: () => P.MonadicParser.regexp(/%([a-zA-Z0-9])/, 1).desc('altloc'),
     Inscode: () => P.MonadicParser.regexp(/\^([a-zA-Z0-9])/, 1).desc('inscode'),
 
 
-//    function listMap(x: string) { return x.split(',').map(x => x.replace(/^["']|["']$/g, '')); }
+    //    function listMap(x: string) { return x.split(',').map(x => x.replace(/^["']|["']$/g, '')); }
+
 
 
+    BracketedResname: function (r: any) {
+        return P.MonadicParser.regexp(/\.([a-zA-Z0-9]{1,4})/, 1)
+	    .desc('bracketed-resname');
+        // [0SD]
+    },
 
-    BracketedResname: function (r:any) {
-	return P.MonadicParser.regexp(/\.([a-zA-Z0-9]{1,4})/, 1)
-	    .desc('bracketed-resname')
-	// [0SD]
+    ResnoRange: function (r: any) {
+        return P.MonadicParser.regexp(/\.([\s]){1,3}/, 1)
+	    .desc('resno-range');
+        // 123-200
+        // -12--3
     },
 
-    ResnoRange: function (r:any) {
-	return P.MonadicParser.regexp(/\.([\s]){1,3}/, 1)
-	    .desc('resno-range')
-	// 123-200
-	// -12--3
+    Keywords: () => P.MonadicParser.alt(...h.getKeywordRules(keywords)),
+
+    Query: function (r: any) {
+        return P.MonadicParser.alt(
+            r.Operator,
+            r.Parens,
+            r.Expression
+        ).trim(P.MonadicParser.optWhitespace);
     },
 
-  Keywords: () => P.MonadicParser.alt(...h.getKeywordRules(keywords)),
-
-Query: function(r:any) {
-    return P.MonadicParser.alt(
-      r.Operator,
-      r.Parens,
-      r.Expression
-    ).trim(P.MonadicParser.optWhitespace)
-  },
-
-  Number: function () {
-    return P.MonadicParser.regexp(/-?(0|[1-9][0-9]*)([.][0-9]+)?([eE][+-]?[0-9]+)?/)
-      .map(Number)
-      .desc('number')
-  },
-
-  String: function () {
-    const w = h.getReservedWords(properties, keywords, operators)
-      .sort(h.strLenSortFn).map(h.escapeRegExp).join('|')
-    return P.MonadicParser.alt(
-      P.MonadicParser.regexp(new RegExp(`(?!(${w}))[A-Z0-9_]+`, 'i')),
-      P.MonadicParser.regexp(/'((?:[^"\\]|\\.)*)'/, 1),
-      P.MonadicParser.regexp(/"((?:[^"\\]|\\.)*)"/, 1).map(x => B.core.type.regex([`^${x}$`, 'i']))
-    )
-  },
-
-Value: function (r:any) {
-    return P.MonadicParser.alt(r.Number, r.String)
-  },
-
-ValueParens: function (r:any) {
-    return P.MonadicParser.alt(
-      r.ValueParens,
-      r.ValueOperator,
-      r.ValueExpressions
-    ).wrap(P.MonadicParser.string('('), P.MonadicParser.string(')'))
-  },
-
-  ValuePropertyNames: function() {
-    return P.MonadicParser.alt(...h.getPropertyNameRules(properties, /LIKE|>=|<=|=|!=|>|<|\)|\s/i))
-  },
-
-ValueOperator: function(r:any) {
-    return h.combineOperators(valueOperators, P.MonadicParser.alt(r.ValueParens, r.ValueExpressions))
-  },
-
-ValueExpressions: function(r:any) {
-    return P.MonadicParser.alt(
-      r.Value,
-      r.ValuePropertyNames
-    )
-  },
-
-ValueQuery: function(r:any) {
-    return P.MonadicParser.alt(
-	r.ValueOperator.map((x:any) => {
-        if (x.head) {
-          if (x.head.startsWith('structure-query.generator')) return x
-        } else {
-          if (typeof x === 'string' && x.length <= 4) {
-            return B.struct.generator.atomGroups({
-              'residue-test': B.core.rel.eq([ B.ammp('label_comp_id'), x ])
+    Number: function () {
+        return P.MonadicParser.regexp(/-?(0|[1-9][0-9]*)([.][0-9]+)?([eE][+-]?[0-9]+)?/)
+            .map(Number)
+            .desc('number');
+    },
+
+    String: function () {
+        const w = h.getReservedWords(properties, keywords, operators)
+            .sort(h.strLenSortFn).map(h.escapeRegExp).join('|');
+        return P.MonadicParser.alt(
+            P.MonadicParser.regexp(new RegExp(`(?!(${w}))[A-Z0-9_]+`, 'i')),
+            P.MonadicParser.regexp(/'((?:[^"\\]|\\.)*)'/, 1),
+            P.MonadicParser.regexp(/"((?:[^"\\]|\\.)*)"/, 1).map(x => B.core.type.regex([`^${x}$`, 'i']))
+        );
+    },
+
+    Value: function (r: any) {
+        return P.MonadicParser.alt(r.Number, r.String);
+    },
+
+    ValueParens: function (r: any) {
+        return P.MonadicParser.alt(
+            r.ValueParens,
+            r.ValueOperator,
+            r.ValueExpressions
+        ).wrap(P.MonadicParser.string('('), P.MonadicParser.string(')'));
+    },
+
+    ValuePropertyNames: function () {
+        return P.MonadicParser.alt(...h.getPropertyNameRules(properties, /LIKE|>=|<=|=|!=|>|<|\)|\s/i));
+    },
+
+    ValueOperator: function (r: any) {
+        return h.combineOperators(valueOperators, P.MonadicParser.alt(r.ValueParens, r.ValueExpressions));
+    },
+
+    ValueExpressions: function (r: any) {
+        return P.MonadicParser.alt(
+            r.Value,
+            r.ValuePropertyNames
+        );
+    },
+
+    ValueQuery: function (r: any) {
+        return P.MonadicParser.alt(
+            r.ValueOperator.map((x: any) => {
+                if (x.head) {
+                    if (x.head.startsWith('structure-query.generator')) return x;
+                } else {
+                    if (typeof x === 'string' && x.length <= 4) {
+                        return B.struct.generator.atomGroups({
+                            'residue-test': B.core.rel.eq([B.ammp('label_comp_id'), x])
+                        });
+                    }
+                }
+                throw new Error(`values must be part of an comparison, value '${x}'`);
             })
-          }
-        }
-        throw new Error(`values must be part of an comparison, value '${x}'`)
-      })
-    )
-  }
-})
-
-const transpiler: Transpiler = str => lang.Query.tryParse(str)
-export default transpiler
+        );
+    }
+});
+
+export const transpiler: Transpiler = str => lang.Query.tryParse(str);
diff --git a/src/mol-script/transpilers/rasmol/properties.ts b/src/mol-script/transpilers/rasmol/properties.ts
index 133840440f33a2ce927201eef7004d5caafbde3c..8164bb724857d480911a8c6e0cafb87dd18d3586 100644
--- a/src/mol-script/transpilers/rasmol/properties.ts
+++ b/src/mol-script/transpilers/rasmol/properties.ts
@@ -1,9 +1,9 @@
-/*                     
- * Copyright (c) 2017-2021 mol* contributors, licensed under MIT, See LICENSE file for more info.   
- * @author Alexander Rose <alexander.rose@weirdbyte.de>                                
- * @author Panagiotis Tourlas <panagiot_tourlov@hotmail.com> 
- *                                   
- * @author Koya Sakuma                                                        
+/*
+ * Copyright (c) 2017-2021 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * @author Alexander Rose <alexander.rose@weirdbyte.de>
+ * @author Panagiotis Tourlas <panagiot_tourlov@hotmail.com>
+ *
+ * @author Koya Sakuma
  * This module was taken from jmol transpiler from MolQL and modified in similar manner as pymol and vmd tranpilers.                                             \
 */
 
@@ -11,632 +11,632 @@ import { MolScriptBuilder } from '../../../mol-script/language/builder';
 const B = MolScriptBuilder;
 import { PropertyDict } from '../types';
 
-const reFloat = /[-+]?[0-9]*\.?[0-9]+/
-const rePosInt = /[0-9]+/
+const reFloat = /[-+]?[0-9]*\.?[0-9]+/;
+const rePosInt = /[0-9]+/;
 
-function str(x: string) { return x }
+function str(x: string) { return x; }
 
 const structureDict: {[key: string]: string} = {
-  none: 'none',
-  turn: 'turn',
-  sheet: 'beta',
-  helix: 'helix',
-  dna: 'dna',
-  rna: 'rna',
+    none: 'none',
+    turn: 'turn',
+    sheet: 'beta',
+    helix: 'helix',
+    dna: 'dna',
+    rna: 'rna',
 
-  0: 'none',
-  1: 'turn',
-  2: 'beta',
-  3: 'helix',
-  4: 'dna',
-  5: 'rna',
-  6: 'carbohydrate',
-  7: '3-10',
-  8: 'alpha',
-  9: 'pi',
-}
+    0: 'none',
+    1: 'turn',
+    2: 'beta',
+    3: 'helix',
+    4: 'dna',
+    5: 'rna',
+    6: 'carbohydrate',
+    7: '3-10',
+    8: 'alpha',
+    9: 'pi',
+};
 export function structureMap(x: any) {
-  if (x.head && x.head === 'core.type.regex') x = x.args[0].replace(/^\^|\$$/g, '')
-  x = structureDict[x.toString().toLowerCase()] || 'none'
-  if (['dna', 'rna', 'carbohydrate'].indexOf(x) !== -1) {
-    throw new Error("values 'dna', 'rna', 'carbohydrate' not yet supported for 'structure' property")
-  } else {
-    return B.struct.type.secondaryStructureFlags([x])
-  }
+    if (x.head && x.head === 'core.type.regex') x = x.args[0].replace(/^\^|\$$/g, '');
+    x = structureDict[x.toString().toLowerCase()] || 'none';
+    if (['dna', 'rna', 'carbohydrate'].indexOf(x) !== -1) {
+        throw new Error("values 'dna', 'rna', 'carbohydrate' not yet supported for 'structure' property");
+    } else {
+        return B.struct.type.secondaryStructureFlags([x]);
+    }
 }
 
 export const properties: PropertyDict = {
     altloc: {
-	'@desc': 'PDB alternate location identifier',
-	'@examples': ['altloc = A'],
-	regex: /[a-zA-Z0-9]/, map: str,
-	level: 'atom-test', property: B.ammp('label_alt_id')
-    },    
+        '@desc': 'PDB alternate location identifier',
+        '@examples': ['altloc = A'],
+        regex: /[a-zA-Z0-9]/, map: str,
+        level: 'atom-test', property: B.ammp('label_alt_id')
+    },
     atomID: {
-	'@desc': 'special atom IDs for PDB atoms assigned by Jmol',
-	'@examples': [''],
-    isUnsupported: true,
-    regex: rePosInt, map: x => parseInt(x),
-    level: 'atom-test'
+        '@desc': 'special atom IDs for PDB atoms assigned by Jmol',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: rePosInt, map: x => parseInt(x),
+        level: 'atom-test'
     },
     atomIndex: {
-	'@desc': 'atom 0-based index; a unique number for each atom regardless of the number of models loaded',
-	'@examples': [''],
-	isUnsupported: true,
-    regex: rePosInt, map: x => parseInt(x),
-    level: 'atom-test'
-  },
-  atomName: {
-    '@desc': 'atom name',
-    '@examples': ['atomName = CA'],
-    regex: /[a-zA-Z0-9]+/, map: v => B.atomName(v),
-    level: 'atom-test', property: B.ammp('label_atom_id')
-  },
-  atomno: {
-    '@desc': 'sequential number; you can use "@" instead of "atomno=" -- for example, select @33 or Var x = @33 or @35',
-    '@examples': [''],
-    isNumeric: true,
-    regex: rePosInt, map: x => parseInt(x),
-    level: 'atom-test', property: B.ammp('id')
-  },
-  atomType: {
-    '@desc': 'atom type (mol2, AMBER files) or atom name (other file types)',
-    '@examples': ['atomType = OH'],
-    regex: /[a-zA-Z0-9]+/, map: v => B.atomName(v),
-    level: 'atom-test', property: B.ammp('label_atom_id')
-  },
-  atomX: {
-    '@desc': 'Cartesian X coordinate (or just X)',
-    '@examples': ['x = 4.2'],
-    abbr: ['X'],
-    isNumeric: true,
-    regex: reFloat, map: x => parseFloat(x),
-    level: 'atom-test', property: B.acp('x')
-  },
-  atomY: {
-    '@desc': 'Cartesian Y coordinate (or just Y)',
-    '@examples': ['y < 42'],
-    abbr: ['Y'],
-    isNumeric: true,
-    regex: reFloat, map: x => parseFloat(x),
-    level: 'atom-test', property: B.acp('y')
-  },
-  atomZ: {
-    '@desc': 'Cartesian Z coordinate (or just Z)',
-    '@examples': ['Z > 10'],
-    abbr: ['Z'],
-    isNumeric: true,
-    regex: reFloat, map: x => parseFloat(x),
-    level: 'atom-test', property: B.acp('z')
-  },
-  bondcount: {
-    '@desc': 'covalent bond count',
-    '@examples': ['bondcount = 0'],
-    isNumeric: true,
-    regex: rePosInt, map: x => parseInt(x),
-    level: 'atom-test', property: B.acp('bondCount')
-  },
-  bondingRadius: {
-    '@desc': 'radius used for auto bonding; synonymous with ionic and ionicRadius',
-    '@examples': [''],
-    abbr: ['ionic', 'ionicRadius'],
-    isUnsupported: true,
-    regex: reFloat, map: x => parseFloat(x),
-    level: 'atom-test'
-  },
-  cell: {
-    '@desc': 'crystallographic unit cell, expressed either in lattice integer notation (111-999) or as a coordinate in ijk space, where {1 1 1} is the same as 555. ANDing two cells, for example select cell=555 and cell=556, selects the atoms on the common face. (Note: in the specifc case of CELL, only "=" is allowed as a comparator.)',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  configuration: {
-    '@desc': 'Only in the context {configuration=n}, this option selects the set of atoms with either no ALTLOC specified or those atoms having this index into the array of altlocs within its model. So, for example, if the model has altloc "A" and "B", select configuration=1 is equivalent to select altloc="" or altloc="A", and print {configuration=2} is equivalent to print {altloc="" or altloc="B"}. Configuration 0 is "all atoms in a model having configurations", and an invalid configuration number gives no atoms. (Note: in the specifc case of CONFIGURATION, only "=" is allowed as a comparator.)',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: rePosInt, map: x => parseInt(x),
-    level: 'atom-test'
-  },
-  chain: {
-    '@desc': 'protein chain. For newer CIF files allowing multicharacter chain specifications, use quotations marks: select chain="AA". For these multicharacter desigations, case is not checked unless the CIF file has lower-case chain designations.',
-    '@examples': ['chain = A', 'chain = "AA"'],
-    regex: /[a-zA-Z0-9]+/, map: str,
-    level: 'chain-test', property: B.ammp('auth_asym_id')
-  },
-  chainNo: {
-    '@desc': 'chain number; sequentially counted from 1 for each model; chainNo == 0 means"no chain" or PDB chain identifier indicated as a blank (Jmol 14.0).',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  color: {
-    '@desc': 'the atom color',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  covalentRadius: {
-    '@desc': 'covalent bonding radius, synonymous with covalent. Not used by Jmol, but could be used, for example, in {*}.spacefill={*}.covalentRadius.all.',
-    '@examples': [''],
-    abbr: ['covalent'],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  cs: {
-    '@desc': 'chemical shift calculated using computational results that include magnetic shielding tensors.',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  element: {
-    '@desc': 'element symbol. The value of this parameter depends upon the context. Used with select structure=x, x can be either the quoted element symbol, "H", "He", "Li", etc. or atomic number. In all other contexts, the value is the element symbol. When the atom is a specific isotope, the string will contain the isotope number -- "13C", for example.',
-    '@examples': ['element=Fe'],
-    regex: /[a-zA-Z]+/, map: x => B.es(x),
-    level: 'atom-test', property: B.acp('elementSymbol')
-  },
-  elemno: {
-      '@desc': 'atomic element number',
-      '@examples': ['elemno=8'],
-      isNumeric: true,
-      regex: /[0-9\s{}-]+/, map: x => parseInt(x),
-      level: 'atom-test', property: B.acp('atomicNumber')
-  },
-  eta: {
-    '@desc': 'Based on Carlos M. Duarte, Leven M. Wadley, and Anna Marie Pyle, RNA structure comparison, motif search and discovery using a reduced representation of RNA conformational space, Nucleic Acids Research, 2003, Vol. 31, No. 16 4755-4761. The parameter eta is the C4\'[i-1]-P[i]-C4\'[i]-P[i+1] dihedral angle; theta is the P[i]-C4\'[i]-P[i+1]-C4\'[i+1] dihedral angle. Both are measured on a 0-360 degree scale because they are commonly near 180 degrees. Using the commands plot PROPERTIES eta theta resno; select visible;wireframe only one can create these authors\' "RNA worm" graph.',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  theta: {
-    '@desc': 'Based on Carlos M. Duarte, Leven M. Wadley, and Anna Marie Pyle, RNA structure comparison, motif search and discovery using a reduced representation of RNA conformational space, Nucleic Acids Research, 2003, Vol. 31, No. 16 4755-4761. The parameter eta is the C4\'[i-1]-P[i]-C4\'[i]-P[i+1] dihedral angle; theta is the P[i]-C4\'[i]-P[i+1]-C4\'[i+1] dihedral angle. Both are measured on a 0-360 degree scale because they are commonly near 180 degrees. Using the commands plot PROPERTIES eta theta resno; select visible;wireframe only one can create these authors\' "RNA worm" graph.',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  file: {
-    '@desc': 'file number containing this atom',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  formalCharge: {
-    '@desc': 'formal charge',
-    '@examples': ['formalCharge=1'],
-    regex: reFloat, map: x => parseFloat(x),
-    level: 'atom-test', property: B.ammp('pdbx_formal_charge')
-  },
-  format: {
-    '@desc': 'format (label) of the atom.',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  fXyz: {
-    '@desc': 'fractional XYZ coordinates',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  fX: {
-    '@desc': 'fractional X coordinate',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  fY: {
-    '@desc': 'fractional Y coordinate',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  fZ: {
-    '@desc': 'fractional Z coordinate',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  fuxyz: {
-    '@desc': 'fractional XYZ coordinates in the unitcell coordinate system',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  fux: {
-    '@desc': 'fractional X coordinate in the unitcell coordinate system',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  fuy: {
-    '@desc': 'fractional Y coordinate in the unitcell coordinate system',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  fuz: {
-    '@desc': 'fractional Z coordinate in the unit cell coordinate system',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  group: {
-    '@desc': '3-letter residue code',
-    '@examples': ['group = ALA'],
-    regex: /[a-zA-Z0-9]{1,3}/, map: str,
-    level: 'residue-test', property: B.ammp('label_comp_id')
-  },
-  group1: {
-    '@desc': 'single-letter residue code (amino acids only)',
-    '@examples': ['group1 = G'],
-    regex: /[a-zA-Z]/, map: str,
-    level: 'residue-test', property: B.ammp('label_comp_id')
-  },
-  groupID: {
-    '@desc': 'group ID number: A unique ID for each amino acid or nucleic acid residue in a PDB file. 0  noGroup 1-5  ALA, ARG, ASN, ASP, CYS 6-10  GLN, GLU, GLY, HIS, ILE 11-15  LEU, LYS, MET, PHE, PRO 16-20  SER, THR, TRP, TYR, VAL 21-23  ASX, GLX, UNK 24-29  A, +A, G, +G, I, +I 30-35  C, +C, T, +T, U, +U Additional unique numbers are assigned arbitrarily by Jmol and cannot be used reproducibly.',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  groupindex: {
-    '@desc': 'overall group index',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  hydrophobicity: {
-    '@desc': 'Aminoacid residue scale of hydrophobicity based on Rose, G. D., Geselowitz, A. R., Lesser, G. J., Lee, R. H., and Zehfus, M. H. (1985). Hydrophobicity of amino acid residues in globular proteins, Science, 229(4716):834-838.',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  identify: {
-    '@desc': 'for a PDB/mmCIF file, a label such as [ILE]7^1:A.CD1%A/3 #47, which includes the group ([ILE]), residue number with optional insertion code (7^1), chain (:A), atom name (CD1), alternate location if present (%A), PDB model number (/3, for NMR models when one file is loaded; /file.model such as /2.3 if more than one file is loaded), and atom number (#47). For non-PDB data, the information is shorter -- for example, H15/2.1 #6, indicating atom name (H15), full file.model number (/2.1), and atom number (#6). If only a single model is loaded, %[identify] does not include the model number.',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  insertion: {
-    '@desc': 'protein residue insertion code',
-    '@examples': ['insertion=A'],
-    regex: /[a-zA-Z0-9]/, map: str,
-    level: 'atom-test', property: B.ammp('pdbx_PDB_ins_code')
-  },
-  label: {
-    '@desc': 'current atom label (same as format)',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  mass: {
-    '@desc': 'atomic mass -- especially useful with appended .max or .sum',
-    '@examples': ['mass > 13'],
-    regex: reFloat, map: x => parseFloat(x),
-    level: 'atom-test', property: B.acp('mass')
-  },
-  model: {
-    '@desc': 'model number',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  modelindex: {
-    '@desc': 'a unique number for each model, starting with 0 and spanning all models in all files',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  modO: {
-    '@desc': 'currently calculated occupancy from modulation (0 to 100; NaN if atom has no occupancy modulation)',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  modXYZ: {
-    '@desc': 'currently calculated displacement modulation (for incommensurately modulated structures). Also modX, modY, modZ for individual components. For atoms without modultion, {xx}.modXYZ is -1 and {xx}.modX is NaN, and in a label %[modXYZ] and %[modX] are blank.',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  molecule: {
-    '@desc': 'molecule number',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  monomer: {
-    '@desc': 'monomer number (group number) in a polymer (usually a chain), starting with 1, or 0 if not part of a biopolymer -- that is, not a connected carbohydrate, amino acid, or nucleic acid (Jmol 14.3.15)',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  ms: {
-    '@desc': 'magnetic shielding calculated from file-loaded tensors.',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  occupancy: {
-    '@desc': 'CIF file site occupancy. In SELECT command comparisons ("select occupancy < 90"), an integer n implies measurement on a 0-100 scale; also, in the context %[occupancy] or %q for a label, the reported number is a percentage. In all other cases, such as when %Q is used in a label or when a decimal number is used in a comparison, the scale is 0.0 - 1.0.',
-    '@examples': ['occupancy < 1'],
-    regex: reFloat, map: x => parseFloat(x),
-    level: 'atom-test', property: B.ammp('occupancy')
-  },
-  partialCharge: {
-    '@desc': 'partial charge',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: reFloat, map: x => parseFloat(x),
-    level: 'atom-test'
-  },
-  phi: {
-    '@desc': 'protein group PHI angle for atom\'s residue',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  polymer: {
-    '@desc': 'sequential polymer number in a model, starting with 1.',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  polymerLength: {
-    '@desc': 'polymer length',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  property_xx: {
-    '@desc': 'a property created using the DATA command',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  psi: {
-    '@desc': 'protein group PSI angle for the atom\'s residue',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  radius: {
-    '@desc': 'currently displayed radius -- In SELECT command comparisons ("select radius=n"), integer n implies Rasmol units 1/250 Angstroms; in all other cases or when a decimal number is used, the units are Angstroms.',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  resno: {
-      '@desc': 'PDB residue number, not including insertion code (see also seqcode, below)',
-      '@examples': ['resno = 100'],
-      isNumeric: true,
-      regex: /-?[0-9]+/, map: x => parseInt(x),
-      level: 'residue-test', property: B.ammp('auth_seq_id')
-  },
-  selected: {
-    '@desc': '1.0 if atom is selected; 0.0 if not',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  sequence: {
-    '@desc': 'PDB one-character sequence code, as a string of characters, with "?" indicated where single-character codes are not available',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  seqcode: {
-    '@desc': 'PDB residue number, including insertion code (for example, 234^2; "seqcode" option added in Jmol 14.3.16)',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  seqid: {
-    '@desc': '(mmCIF only) the value from _atom_site.label_seq_id; a pointer to _entity_poly_seq.num in the ENTITY_POLY_SEQ category specifying the sequence of monomers in a polymer. Allowance is made for the possibility of microheterogeneity in a sample by allowing a given sequence number to be correlated with more than one monomer id. (Jmol 14.2.3)',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  shape: {
-    '@desc': 'hybridization geometry such as "tetrahedral"',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  site: {
-    '@desc': 'crystallographic site number',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  spacefill: {
-    '@desc': 'currently displayed radius',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  straightness: {
-    '@desc': 'quaternion-derived straightness (second derivative of the quaternion describing the orientation of the residue. This quantity will have different values depending upon the setting of quaternionFrame as "A" (alpha-carbon/phosphorus atom only), "C" (alpha-carbon/pyrimidine or purine base based), "P" (carbonyl-carbon peptide plane/phosphorus tetrahedron based), or "N" (amide-nitrogen based). The default is alpha-carbon based, which corresponds closely to the following combination of Ramachandran angles involving three consecutive residues i-1, i, and i+1: -psii-1 - phii + psii + phii+1.',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  strucno: {
-    '@desc': 'a unique number for each helix, sheet, or turn in a model, starting with 1.',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  structure: {
-    '@desc': 'The value of this parameter depends upon the context. Used with select structure=x, x can be either the quoted keyword "none", "turn", "sheet", "helix", "dna", "rna", or "carbohydrate" or a respective number 0-6. In the context {*}.structure, the return value is a number; in the context label %[structure], the return is one of the six keywords.',
-    '@examples': ['structure="helix"', 'structure=3'],
-    regex: /none|turn|sheet|helix|dna|rna|carbohydrate|[0-6]/i, map: str,
-    level: 'residue-test', property: 'structure'
-  },
-  substructure: {
-    '@desc': 'like structure, the value of this parameter depends upon the context. Used with select substructure=x, x can be either the quoted keyword "none", "turn", "sheet", "helix", "dna", "rna", "carbohydrate", "helix310", "helixalpha", or "helixpi", or the respective number 0-9. In the context {*}.substructure, the return value is a number; in the context label %[substructure], the return is one of the nine keywords.',
-    '@examples': ['substructure = "alphahelix"', 'substructure =9'],
-    regex: /none|turn|sheet|helix|dna|rna|carbohydrate|helix310|helixalpha|helixpi|[0-9]/i, map: str,
-    level: 'residue-test', property: 'structure'
-  },
-  surfacedistance: {
-    '@desc': 'A value related to the distance of an atom to a nominal molecular surface. 0 indicates at the surface. Positive numbers are minimum distances in Angstroms from the given atom to the surface.',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  symop: {
-    '@desc': 'the first symmetry operation code that generated this atom by Jmol; an integer starting with 1. See also symmetry, below. This operator is only present if the file contains space group information and the file was loaded using the {i, j, k} option so as to generate symmetry-based atoms. To select only the original atoms prior to application of symmetry, you can either use "SYMOP=n", where n is the symmetry operator corresponding to "x,y,z", or you can specify instead simply "NOT symmetry" the way you might specify "NOT hydrogen". Note that atoms in special positions will have multiple operator matches. These atoms can be selected using the keyword SPECIALPOSITION. The special form select SYMOP=nijk selects a specific translation of atoms from the given crystallographic symmetry operation. Comparators <, <=, >, >=, and != can be used and only apply to the ijk part of the designation. The ijk are relative, not absolute. Thus, symop=2555 selects for atoms that have been transformed by symop=2 but not subjected to any further translation. select symop=1555 is identical to select not symmetry. All other ijk are relative to these selections for 555. If the model was loaded using load "filename.cif" {444 666 1}, where the 1 indicates that all symmetry-generated atoms are to be packed within cell 555 and then translated to fill the other 26 specified cells, then select symop=3555 is nearly the same as select symop=3 and cell=555. (The difference being that cell=555 selects for all atoms that are on any edge of the cell, while symop=3555 does not.) However, the situation is different if instead the model was loaded using load "filename.cif" {444 666 0}, where the 0 indicates that symmetry-generated atoms are to be placed exactly where their symmetry operator would put them (x,-y,z being different then from x, 1-y, z). In that case, select symop=3555 is for all atoms that have been generated using symmetry operation 3 but have not had any additional translations applied to the x,y,z expression found in the CIF file. If, for example, symmetry operation 3 is -x,-y,-z, then load "filename.cif" {444 666 0} will place an atom originally at {1/2, 1/2, 1/2} at positions {-1/2, -1/2, -1/2} (symop=3555) and {-3/2, -3/2, -3/2} (symop=3444) and 24 other sites.',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  symmetry: {
-    '@desc': 'as "symmetry" or in a label as lower-case "o" gives list of crystallographic symmetry operators generating this atom with lattice designations,such as 3555; upper-case "%O" in a label gives a list without the lattice designations. See also symop, above.',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  temperature: {
-    '@desc': 'yes  yes  temperature factor (B-factor)',
-    '@examples': ['temperature >= 20'],
-    regex: reFloat, map: x => parseFloat(x),
-    level: 'atom-test', property: B.ammp('B_iso_or_equiv')
-  },
-  unitXyz: {
-    '@desc': 'unit cell XYZ coordinates',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  uX: {
-    '@desc': 'unit cell X coordinate normalized to [0,1)',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  uY: {
-    '@desc': 'unit cell Y coordinate normalized to [0,1)',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  uZ: {
-    '@desc': 'unit cell Z coordinate normalized to [0,1)',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  valence: {
-    '@desc': 'the valence of an atom (sum of bonds, where double bond counts as 2 and triple bond counts as 3',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  vanderwaals: {
-    '@desc': 'van der Waals radius',
-    '@examples': ['vanderwaals >2'],
-    regex: reFloat, map: x => parseFloat(x),
-    level: 'atom-test', property: B.acp('vdw')
-  },
-  vectorScale: {
-    '@desc': 'vibration vector scale',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  volume: {
-    '@desc': 'approximate van der Waals volume for this atom. Note, {*}.volume gives an average; use {*}.volume.sum to get total volume.',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  vXyz: {
-    '@desc': 'vibration vector, or individual components as %vx %vy %vz. For atoms without vibration vectors, {xx}.vXyz is -1; in a label, %[vxyz] is blank.',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  vX: {
-    '@desc': 'vibration vector X coordinate; for atoms without vibration vector, {xx}.vX is NaN (same for vY and vZ)',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  vY: {
-    '@desc': 'vibration vector Y coordinate',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  vZ: {
-    '@desc': 'vibration vector Z coordinate',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-  xyz: {
-    '@desc': 'Cartesian XYZ coordinates; select xyz > 1.0 selects atoms more than one Angstrom from the origin.',
-    '@examples': [''],
-    isUnsupported: true,
-    regex: /[0-9\s{}-]+/, map: str,
-    level: 'atom-test'
-  },
-}
+        '@desc': 'atom 0-based index; a unique number for each atom regardless of the number of models loaded',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: rePosInt, map: x => parseInt(x),
+        level: 'atom-test'
+    },
+    atomName: {
+        '@desc': 'atom name',
+        '@examples': ['atomName = CA'],
+        regex: /[a-zA-Z0-9]+/, map: v => B.atomName(v),
+        level: 'atom-test', property: B.ammp('label_atom_id')
+    },
+    atomno: {
+        '@desc': 'sequential number; you can use "@" instead of "atomno=" -- for example, select @33 or Var x = @33 or @35',
+        '@examples': [''],
+        isNumeric: true,
+        regex: rePosInt, map: x => parseInt(x),
+        level: 'atom-test', property: B.ammp('id')
+    },
+    atomType: {
+        '@desc': 'atom type (mol2, AMBER files) or atom name (other file types)',
+        '@examples': ['atomType = OH'],
+        regex: /[a-zA-Z0-9]+/, map: v => B.atomName(v),
+        level: 'atom-test', property: B.ammp('label_atom_id')
+    },
+    atomX: {
+        '@desc': 'Cartesian X coordinate (or just X)',
+        '@examples': ['x = 4.2'],
+        abbr: ['X'],
+        isNumeric: true,
+        regex: reFloat, map: x => parseFloat(x),
+        level: 'atom-test', property: B.acp('x')
+    },
+    atomY: {
+        '@desc': 'Cartesian Y coordinate (or just Y)',
+        '@examples': ['y < 42'],
+        abbr: ['Y'],
+        isNumeric: true,
+        regex: reFloat, map: x => parseFloat(x),
+        level: 'atom-test', property: B.acp('y')
+    },
+    atomZ: {
+        '@desc': 'Cartesian Z coordinate (or just Z)',
+        '@examples': ['Z > 10'],
+        abbr: ['Z'],
+        isNumeric: true,
+        regex: reFloat, map: x => parseFloat(x),
+        level: 'atom-test', property: B.acp('z')
+    },
+    bondcount: {
+        '@desc': 'covalent bond count',
+        '@examples': ['bondcount = 0'],
+        isNumeric: true,
+        regex: rePosInt, map: x => parseInt(x),
+        level: 'atom-test', property: B.acp('bondCount')
+    },
+    bondingRadius: {
+        '@desc': 'radius used for auto bonding; synonymous with ionic and ionicRadius',
+        '@examples': [''],
+        abbr: ['ionic', 'ionicRadius'],
+        isUnsupported: true,
+        regex: reFloat, map: x => parseFloat(x),
+        level: 'atom-test'
+    },
+    cell: {
+        '@desc': 'crystallographic unit cell, expressed either in lattice integer notation (111-999) or as a coordinate in ijk space, where {1 1 1} is the same as 555. ANDing two cells, for example select cell=555 and cell=556, selects the atoms on the common face. (Note: in the specifc case of CELL, only "=" is allowed as a comparator.)',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    configuration: {
+        '@desc': 'Only in the context {configuration=n}, this option selects the set of atoms with either no ALTLOC specified or those atoms having this index into the array of altlocs within its model. So, for example, if the model has altloc "A" and "B", select configuration=1 is equivalent to select altloc="" or altloc="A", and print {configuration=2} is equivalent to print {altloc="" or altloc="B"}. Configuration 0 is "all atoms in a model having configurations", and an invalid configuration number gives no atoms. (Note: in the specifc case of CONFIGURATION, only "=" is allowed as a comparator.)',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: rePosInt, map: x => parseInt(x),
+        level: 'atom-test'
+    },
+    chain: {
+        '@desc': 'protein chain. For newer CIF files allowing multicharacter chain specifications, use quotations marks: select chain="AA". For these multicharacter desigations, case is not checked unless the CIF file has lower-case chain designations.',
+        '@examples': ['chain = A', 'chain = "AA"'],
+        regex: /[a-zA-Z0-9]+/, map: str,
+        level: 'chain-test', property: B.ammp('auth_asym_id')
+    },
+    chainNo: {
+        '@desc': 'chain number; sequentially counted from 1 for each model; chainNo == 0 means"no chain" or PDB chain identifier indicated as a blank (Jmol 14.0).',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    color: {
+        '@desc': 'the atom color',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    covalentRadius: {
+        '@desc': 'covalent bonding radius, synonymous with covalent. Not used by Jmol, but could be used, for example, in {*}.spacefill={*}.covalentRadius.all.',
+        '@examples': [''],
+        abbr: ['covalent'],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    cs: {
+        '@desc': 'chemical shift calculated using computational results that include magnetic shielding tensors.',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    element: {
+        '@desc': 'element symbol. The value of this parameter depends upon the context. Used with select structure=x, x can be either the quoted element symbol, "H", "He", "Li", etc. or atomic number. In all other contexts, the value is the element symbol. When the atom is a specific isotope, the string will contain the isotope number -- "13C", for example.',
+        '@examples': ['element=Fe'],
+        regex: /[a-zA-Z]+/, map: x => B.es(x),
+        level: 'atom-test', property: B.acp('elementSymbol')
+    },
+    elemno: {
+        '@desc': 'atomic element number',
+        '@examples': ['elemno=8'],
+        isNumeric: true,
+        regex: /[0-9\s{}-]+/, map: x => parseInt(x),
+        level: 'atom-test', property: B.acp('atomicNumber')
+    },
+    eta: {
+        '@desc': 'Based on Carlos M. Duarte, Leven M. Wadley, and Anna Marie Pyle, RNA structure comparison, motif search and discovery using a reduced representation of RNA conformational space, Nucleic Acids Research, 2003, Vol. 31, No. 16 4755-4761. The parameter eta is the C4\'[i-1]-P[i]-C4\'[i]-P[i+1] dihedral angle; theta is the P[i]-C4\'[i]-P[i+1]-C4\'[i+1] dihedral angle. Both are measured on a 0-360 degree scale because they are commonly near 180 degrees. Using the commands plot PROPERTIES eta theta resno; select visible;wireframe only one can create these authors\' "RNA worm" graph.',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    theta: {
+        '@desc': 'Based on Carlos M. Duarte, Leven M. Wadley, and Anna Marie Pyle, RNA structure comparison, motif search and discovery using a reduced representation of RNA conformational space, Nucleic Acids Research, 2003, Vol. 31, No. 16 4755-4761. The parameter eta is the C4\'[i-1]-P[i]-C4\'[i]-P[i+1] dihedral angle; theta is the P[i]-C4\'[i]-P[i+1]-C4\'[i+1] dihedral angle. Both are measured on a 0-360 degree scale because they are commonly near 180 degrees. Using the commands plot PROPERTIES eta theta resno; select visible;wireframe only one can create these authors\' "RNA worm" graph.',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    file: {
+        '@desc': 'file number containing this atom',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    formalCharge: {
+        '@desc': 'formal charge',
+        '@examples': ['formalCharge=1'],
+        regex: reFloat, map: x => parseFloat(x),
+        level: 'atom-test', property: B.ammp('pdbx_formal_charge')
+    },
+    format: {
+        '@desc': 'format (label) of the atom.',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    fXyz: {
+        '@desc': 'fractional XYZ coordinates',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    fX: {
+        '@desc': 'fractional X coordinate',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    fY: {
+        '@desc': 'fractional Y coordinate',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    fZ: {
+        '@desc': 'fractional Z coordinate',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    fuxyz: {
+        '@desc': 'fractional XYZ coordinates in the unitcell coordinate system',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    fux: {
+        '@desc': 'fractional X coordinate in the unitcell coordinate system',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    fuy: {
+        '@desc': 'fractional Y coordinate in the unitcell coordinate system',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    fuz: {
+        '@desc': 'fractional Z coordinate in the unit cell coordinate system',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    group: {
+        '@desc': '3-letter residue code',
+        '@examples': ['group = ALA'],
+        regex: /[a-zA-Z0-9]{1,3}/, map: str,
+        level: 'residue-test', property: B.ammp('label_comp_id')
+    },
+    group1: {
+        '@desc': 'single-letter residue code (amino acids only)',
+        '@examples': ['group1 = G'],
+        regex: /[a-zA-Z]/, map: str,
+        level: 'residue-test', property: B.ammp('label_comp_id')
+    },
+    groupID: {
+        '@desc': 'group ID number: A unique ID for each amino acid or nucleic acid residue in a PDB file. 0  noGroup 1-5  ALA, ARG, ASN, ASP, CYS 6-10  GLN, GLU, GLY, HIS, ILE 11-15  LEU, LYS, MET, PHE, PRO 16-20  SER, THR, TRP, TYR, VAL 21-23  ASX, GLX, UNK 24-29  A, +A, G, +G, I, +I 30-35  C, +C, T, +T, U, +U Additional unique numbers are assigned arbitrarily by Jmol and cannot be used reproducibly.',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    groupindex: {
+        '@desc': 'overall group index',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    hydrophobicity: {
+        '@desc': 'Aminoacid residue scale of hydrophobicity based on Rose, G. D., Geselowitz, A. R., Lesser, G. J., Lee, R. H., and Zehfus, M. H. (1985). Hydrophobicity of amino acid residues in globular proteins, Science, 229(4716):834-838.',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    identify: {
+        '@desc': 'for a PDB/mmCIF file, a label such as [ILE]7^1:A.CD1%A/3 #47, which includes the group ([ILE]), residue number with optional insertion code (7^1), chain (:A), atom name (CD1), alternate location if present (%A), PDB model number (/3, for NMR models when one file is loaded; /file.model such as /2.3 if more than one file is loaded), and atom number (#47). For non-PDB data, the information is shorter -- for example, H15/2.1 #6, indicating atom name (H15), full file.model number (/2.1), and atom number (#6). If only a single model is loaded, %[identify] does not include the model number.',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    insertion: {
+        '@desc': 'protein residue insertion code',
+        '@examples': ['insertion=A'],
+        regex: /[a-zA-Z0-9]/, map: str,
+        level: 'atom-test', property: B.ammp('pdbx_PDB_ins_code')
+    },
+    label: {
+        '@desc': 'current atom label (same as format)',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    mass: {
+        '@desc': 'atomic mass -- especially useful with appended .max or .sum',
+        '@examples': ['mass > 13'],
+        regex: reFloat, map: x => parseFloat(x),
+        level: 'atom-test', property: B.acp('mass')
+    },
+    model: {
+        '@desc': 'model number',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    modelindex: {
+        '@desc': 'a unique number for each model, starting with 0 and spanning all models in all files',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    modO: {
+        '@desc': 'currently calculated occupancy from modulation (0 to 100; NaN if atom has no occupancy modulation)',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    modXYZ: {
+        '@desc': 'currently calculated displacement modulation (for incommensurately modulated structures). Also modX, modY, modZ for individual components. For atoms without modultion, {xx}.modXYZ is -1 and {xx}.modX is NaN, and in a label %[modXYZ] and %[modX] are blank.',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    molecule: {
+        '@desc': 'molecule number',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    monomer: {
+        '@desc': 'monomer number (group number) in a polymer (usually a chain), starting with 1, or 0 if not part of a biopolymer -- that is, not a connected carbohydrate, amino acid, or nucleic acid (Jmol 14.3.15)',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    ms: {
+        '@desc': 'magnetic shielding calculated from file-loaded tensors.',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    occupancy: {
+        '@desc': 'CIF file site occupancy. In SELECT command comparisons ("select occupancy < 90"), an integer n implies measurement on a 0-100 scale; also, in the context %[occupancy] or %q for a label, the reported number is a percentage. In all other cases, such as when %Q is used in a label or when a decimal number is used in a comparison, the scale is 0.0 - 1.0.',
+        '@examples': ['occupancy < 1'],
+        regex: reFloat, map: x => parseFloat(x),
+        level: 'atom-test', property: B.ammp('occupancy')
+    },
+    partialCharge: {
+        '@desc': 'partial charge',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: reFloat, map: x => parseFloat(x),
+        level: 'atom-test'
+    },
+    phi: {
+        '@desc': 'protein group PHI angle for atom\'s residue',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    polymer: {
+        '@desc': 'sequential polymer number in a model, starting with 1.',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    polymerLength: {
+        '@desc': 'polymer length',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    property_xx: {
+        '@desc': 'a property created using the DATA command',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    psi: {
+        '@desc': 'protein group PSI angle for the atom\'s residue',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    radius: {
+        '@desc': 'currently displayed radius -- In SELECT command comparisons ("select radius=n"), integer n implies Rasmol units 1/250 Angstroms; in all other cases or when a decimal number is used, the units are Angstroms.',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    resno: {
+        '@desc': 'PDB residue number, not including insertion code (see also seqcode, below)',
+        '@examples': ['resno = 100'],
+        isNumeric: true,
+        regex: /-?[0-9]+/, map: x => parseInt(x),
+        level: 'residue-test', property: B.ammp('auth_seq_id')
+    },
+    selected: {
+        '@desc': '1.0 if atom is selected; 0.0 if not',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    sequence: {
+        '@desc': 'PDB one-character sequence code, as a string of characters, with "?" indicated where single-character codes are not available',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    seqcode: {
+        '@desc': 'PDB residue number, including insertion code (for example, 234^2; "seqcode" option added in Jmol 14.3.16)',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    seqid: {
+        '@desc': '(mmCIF only) the value from _atom_site.label_seq_id; a pointer to _entity_poly_seq.num in the ENTITY_POLY_SEQ category specifying the sequence of monomers in a polymer. Allowance is made for the possibility of microheterogeneity in a sample by allowing a given sequence number to be correlated with more than one monomer id. (Jmol 14.2.3)',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    shape: {
+        '@desc': 'hybridization geometry such as "tetrahedral"',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    site: {
+        '@desc': 'crystallographic site number',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    spacefill: {
+        '@desc': 'currently displayed radius',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    straightness: {
+        '@desc': 'quaternion-derived straightness (second derivative of the quaternion describing the orientation of the residue. This quantity will have different values depending upon the setting of quaternionFrame as "A" (alpha-carbon/phosphorus atom only), "C" (alpha-carbon/pyrimidine or purine base based), "P" (carbonyl-carbon peptide plane/phosphorus tetrahedron based), or "N" (amide-nitrogen based). The default is alpha-carbon based, which corresponds closely to the following combination of Ramachandran angles involving three consecutive residues i-1, i, and i+1: -psii-1 - phii + psii + phii+1.',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    strucno: {
+        '@desc': 'a unique number for each helix, sheet, or turn in a model, starting with 1.',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    structure: {
+        '@desc': 'The value of this parameter depends upon the context. Used with select structure=x, x can be either the quoted keyword "none", "turn", "sheet", "helix", "dna", "rna", or "carbohydrate" or a respective number 0-6. In the context {*}.structure, the return value is a number; in the context label %[structure], the return is one of the six keywords.',
+        '@examples': ['structure="helix"', 'structure=3'],
+        regex: /none|turn|sheet|helix|dna|rna|carbohydrate|[0-6]/i, map: str,
+        level: 'residue-test', property: 'structure'
+    },
+    substructure: {
+        '@desc': 'like structure, the value of this parameter depends upon the context. Used with select substructure=x, x can be either the quoted keyword "none", "turn", "sheet", "helix", "dna", "rna", "carbohydrate", "helix310", "helixalpha", or "helixpi", or the respective number 0-9. In the context {*}.substructure, the return value is a number; in the context label %[substructure], the return is one of the nine keywords.',
+        '@examples': ['substructure = "alphahelix"', 'substructure =9'],
+        regex: /none|turn|sheet|helix|dna|rna|carbohydrate|helix310|helixalpha|helixpi|[0-9]/i, map: str,
+        level: 'residue-test', property: 'structure'
+    },
+    surfacedistance: {
+        '@desc': 'A value related to the distance of an atom to a nominal molecular surface. 0 indicates at the surface. Positive numbers are minimum distances in Angstroms from the given atom to the surface.',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    symop: {
+        '@desc': 'the first symmetry operation code that generated this atom by Jmol; an integer starting with 1. See also symmetry, below. This operator is only present if the file contains space group information and the file was loaded using the {i, j, k} option so as to generate symmetry-based atoms. To select only the original atoms prior to application of symmetry, you can either use "SYMOP=n", where n is the symmetry operator corresponding to "x,y,z", or you can specify instead simply "NOT symmetry" the way you might specify "NOT hydrogen". Note that atoms in special positions will have multiple operator matches. These atoms can be selected using the keyword SPECIALPOSITION. The special form select SYMOP=nijk selects a specific translation of atoms from the given crystallographic symmetry operation. Comparators <, <=, >, >=, and != can be used and only apply to the ijk part of the designation. The ijk are relative, not absolute. Thus, symop=2555 selects for atoms that have been transformed by symop=2 but not subjected to any further translation. select symop=1555 is identical to select not symmetry. All other ijk are relative to these selections for 555. If the model was loaded using load "filename.cif" {444 666 1}, where the 1 indicates that all symmetry-generated atoms are to be packed within cell 555 and then translated to fill the other 26 specified cells, then select symop=3555 is nearly the same as select symop=3 and cell=555. (The difference being that cell=555 selects for all atoms that are on any edge of the cell, while symop=3555 does not.) However, the situation is different if instead the model was loaded using load "filename.cif" {444 666 0}, where the 0 indicates that symmetry-generated atoms are to be placed exactly where their symmetry operator would put them (x,-y,z being different then from x, 1-y, z). In that case, select symop=3555 is for all atoms that have been generated using symmetry operation 3 but have not had any additional translations applied to the x,y,z expression found in the CIF file. If, for example, symmetry operation 3 is -x,-y,-z, then load "filename.cif" {444 666 0} will place an atom originally at {1/2, 1/2, 1/2} at positions {-1/2, -1/2, -1/2} (symop=3555) and {-3/2, -3/2, -3/2} (symop=3444) and 24 other sites.',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    symmetry: {
+        '@desc': 'as "symmetry" or in a label as lower-case "o" gives list of crystallographic symmetry operators generating this atom with lattice designations,such as 3555; upper-case "%O" in a label gives a list without the lattice designations. See also symop, above.',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    temperature: {
+        '@desc': 'yes  yes  temperature factor (B-factor)',
+        '@examples': ['temperature >= 20'],
+        regex: reFloat, map: x => parseFloat(x),
+        level: 'atom-test', property: B.ammp('B_iso_or_equiv')
+    },
+    unitXyz: {
+        '@desc': 'unit cell XYZ coordinates',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    uX: {
+        '@desc': 'unit cell X coordinate normalized to [0,1)',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    uY: {
+        '@desc': 'unit cell Y coordinate normalized to [0,1)',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    uZ: {
+        '@desc': 'unit cell Z coordinate normalized to [0,1)',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    valence: {
+        '@desc': 'the valence of an atom (sum of bonds, where double bond counts as 2 and triple bond counts as 3',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    vanderwaals: {
+        '@desc': 'van der Waals radius',
+        '@examples': ['vanderwaals >2'],
+        regex: reFloat, map: x => parseFloat(x),
+        level: 'atom-test', property: B.acp('vdw')
+    },
+    vectorScale: {
+        '@desc': 'vibration vector scale',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    volume: {
+        '@desc': 'approximate van der Waals volume for this atom. Note, {*}.volume gives an average; use {*}.volume.sum to get total volume.',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    vXyz: {
+        '@desc': 'vibration vector, or individual components as %vx %vy %vz. For atoms without vibration vectors, {xx}.vXyz is -1; in a label, %[vxyz] is blank.',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    vX: {
+        '@desc': 'vibration vector X coordinate; for atoms without vibration vector, {xx}.vX is NaN (same for vY and vZ)',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    vY: {
+        '@desc': 'vibration vector Y coordinate',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    vZ: {
+        '@desc': 'vibration vector Z coordinate',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+    xyz: {
+        '@desc': 'Cartesian XYZ coordinates; select xyz > 1.0 selects atoms more than one Angstrom from the origin.',
+        '@examples': [''],
+        isUnsupported: true,
+        regex: /[0-9\s{}-]+/, map: str,
+        level: 'atom-test'
+    },
+};
 
diff --git a/src/mol-script/transpilers/rasmol/symbols.ts b/src/mol-script/transpilers/rasmol/symbols.ts
index bc0d43971acadcc9ce29d794acd7ab3b9cd2f84f..79b9c50feefc7f81a4017b391bd02a642df1976f 100644
--- a/src/mol-script/transpilers/rasmol/symbols.ts
+++ b/src/mol-script/transpilers/rasmol/symbols.ts
@@ -1,9 +1,9 @@
-/*                                                                                                                                           
- * Copyright (c) 2017-2021 mol* contributors, licensed under MIT, See LICENSE file for more info.                                           
- * @author Alexander Rose <alexander.rose@weirdbyte.de>                                                                                     
- * @author Panagiotis Tourlas <panagiot_tourlov@hotmail.com>                                                                                 
- *                                                                                                                                           
- * @author Koya Sakuma                                                                                                                       
+/*
+ * Copyright (c) 2017-2021 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * @author Alexander Rose <alexander.rose@weirdbyte.de>
+ * @author Panagiotis Tourlas <panagiot_tourlov@hotmail.com>
+ *
+ * @author Koya Sakuma
  * This module is based on jmol tranpiler from MolQL and modified in similar manner as pymol and vmd tranpilers.                                             \
 */
 
@@ -11,26 +11,25 @@ import { properties } from './properties';
 import { operators } from './operators';
 import { keywords } from './keywords';
 
-export const Properties: string[] = []
+export const Properties: string[] = [];
 for (const name in properties) {
-    if (properties[name].isUnsupported) continue
-    Properties.push(name)
-    if (properties[name].abbr) Properties.push(...properties[name].abbr!)
+    if (properties[name].isUnsupported) continue;
+    Properties.push(name);
+    if (properties[name].abbr) Properties.push(...properties[name].abbr!);
 }
 
-export const Operators: string[] = []
+export const Operators: string[] = [];
 operators.forEach(o => {
-    if (o.isUnsupported) return
-    Operators.push(o.name)
-    if (o.abbr) Operators.push(...o.abbr)
-})
+    if (o.isUnsupported) return;
+    Operators.push(o.name);
+    if (o.abbr) Operators.push(...o.abbr);
+});
 
-export const Keywords: string[] = []
+export const Keywords: string[] = [];
 for (const name in keywords) {
-    if (!keywords[name].map) continue
-    Keywords.push(name)
-    if (keywords[name].abbr) Keywords.push(...keywords[name].abbr!)
+    if (!keywords[name].map) continue;
+    Keywords.push(name);
+    if (keywords[name].abbr) Keywords.push(...keywords[name].abbr!);
 }
 
-const _all = { Properties, Operators, Keywords }
-export default _all
+export const _all = { Properties, Operators, Keywords };
diff --git a/src/mol-script/transpilers/transpiler.ts b/src/mol-script/transpilers/transpiler.ts
index a119e28cfa771c6f5fce7fc7f4d1b993345d27f5..65abb3cd52ad1cb5ba1cde9f50532cf72ee33083 100644
--- a/src/mol-script/transpilers/transpiler.ts
+++ b/src/mol-script/transpilers/transpiler.ts
@@ -9,4 +9,4 @@ import { Expression } from '../language/expression';
 
 export type Transpiler = (source: string) => Expression
 
-export default Transpiler
+export const Transpiler = (source: string) => Expression;
diff --git a/src/mol-script/transpilers/vmd/operators.ts b/src/mol-script/transpilers/vmd/operators.ts
index 03309d7de105ceacfe45fb91376cb283b786a037..39bf47a3a488b546248acc69fe444f5a4befd6b9 100644
--- a/src/mol-script/transpilers/vmd/operators.ts
+++ b/src/mol-script/transpilers/vmd/operators.ts
@@ -30,7 +30,7 @@ export const operators: OperatorList = [
         '@examples': ['within 5 of name FE'],
         name: 'within',
         type: h.prefix,
-        rule: h.prefixOp(/WITHIN\s+([-+]?[0-9]*\.?[0-9]+)\s+OF/i, 1).map((x:any) => parseFloat(x)),
+        rule: h.prefixOp(/WITHIN\s+([-+]?[0-9]*\.?[0-9]+)\s+OF/i, 1).map((x: any) => parseFloat(x)),
         map: (radius: number, selection: Expression) => {
             return B.struct.modifier.includeSurroundings({ 0: selection, radius });
         }
@@ -40,7 +40,7 @@ export const operators: OperatorList = [
         '@examples': ['exwithin 10 of resname HEM'],
         name: 'exwithin',
         type: h.prefix,
-        rule: h.prefixOp(/EXWITHIN\s+([-+]?[0-9]*\.?[0-9]+)\s+OF/i, 1).map((x:any) => parseFloat(x)),
+        rule: h.prefixOp(/EXWITHIN\s+([-+]?[0-9]*\.?[0-9]+)\s+OF/i, 1).map((x: any) => parseFloat(x)),
         map: (radius: number, target: Expression) => {
             return B.struct.modifier.exceptBy({
                 '0': B.struct.filter.within({
@@ -55,7 +55,7 @@ export const operators: OperatorList = [
         '@examples': ['same resid as name FE'],
         name: 'same',
         type: h.prefix,
-        rule: h.prefixOp(new RegExp(`SAME\\s+(${propNames})\\s+AS`, 'i'), 1).map((x:any) => properties[x].property),
+        rule: h.prefixOp(new RegExp(`SAME\\s+(${propNames})\\s+AS`, 'i'), 1).map((x: any) => properties[x].property),
         map: (property: Expression, source: Expression) => {
             return B.struct.filter.withSameAtomProperties({
                 '0': B.struct.generator.atomGroups(),
diff --git a/src/mol-script/transpilers/vmd/parser.ts b/src/mol-script/transpilers/vmd/parser.ts
index 3fc999e790b783cf5abdcf86edbb1901be98f8ef..1873f848b8155418c4f80d7f3246ab5024fd9867 100644
--- a/src/mol-script/transpilers/vmd/parser.ts
+++ b/src/mol-script/transpilers/vmd/parser.ts
@@ -112,7 +112,7 @@ const valueOperators: OperatorList = [
 ];
 
 const lang = P.MonadicParser.createLanguage({
-    Parens: function (r:any) {
+    Parens: function (r: any) {
         return P.MonadicParser.alt(
             r.Parens,
             r.Operator,
@@ -120,7 +120,7 @@ const lang = P.MonadicParser.createLanguage({
         ).wrap(P.MonadicParser.string('('), P.MonadicParser.string(')'));
     },
 
-    Expression: function (r:any) {
+    Expression: function (r: any) {
         return P.MonadicParser.alt(
             r.RangeListProperty,
 	    r.NamedAtomProperties,
@@ -135,7 +135,7 @@ const lang = P.MonadicParser.createLanguage({
 
     Keywords: () => P.MonadicParser.alt(...h.getKeywordRules(keywords)),
 
-    ValueRange: function (r:any) {
+    ValueRange: function (r: any) {
         return P.MonadicParser.seq(
             r.Value
                 .skip(P.MonadicParser.regexp(/\s+TO\s+/i)),
@@ -143,7 +143,7 @@ const lang = P.MonadicParser.createLanguage({
         ).map(x => ({ range: x }));
     },
 
-    RangeListProperty: function (r:any) {
+    RangeListProperty: function (r: any) {
         return P.MonadicParser.seq(
             P.MonadicParser.alt(...h.getPropertyNameRules(properties, /\s/))
                 .skip(P.MonadicParser.whitespace),
@@ -156,7 +156,7 @@ const lang = P.MonadicParser.createLanguage({
             const listValues: (string | number)[] = [];
             const rangeValues: any[] = [];
 
-            values.forEach((v:any) => {
+            values.forEach((v: any) => {
                 if (v.range) {
                     rangeValues.push(
                         B.core.rel.inRange([property, v.range[0], v.range[1]])
@@ -178,16 +178,16 @@ const lang = P.MonadicParser.createLanguage({
 
 	    //  return B.struct.generator.atomGroups({ [h.testLevel(property)]: test });
 	    //  h.testLevel is not working for unknown reason, so relaced it by hardcoded 'atom-test'
-//	    console.log(h.testLevel(property));
+            //	    console.log(h.testLevel(property));
 	    return B.struct.generator.atomGroups({ 'atom-test': test });
         });
     },
 
-    Operator: function (r:any) {
+    Operator: function (r: any) {
         return h.combineOperators(operators, P.MonadicParser.alt(r.Parens, r.Expression, r.ValueQuery));
     },
 
-    Query: function (r:any) {
+    Query: function (r: any) {
         return P.MonadicParser.alt(
             r.Operator,
             r.Parens,
@@ -207,15 +207,15 @@ const lang = P.MonadicParser.createLanguage({
         return P.MonadicParser.alt(
             P.MonadicParser.regexp(new RegExp(`(?!(${w}))[A-Z0-9_]+`, 'i')),
             P.MonadicParser.regexp(/'((?:[^"\\]|\\.)*)'/, 1),
-            P.MonadicParser.regexp(/"((?:[^"\\]|\\.)*)"/, 1).map((x:any) => B.core.type.regex([`^${x}$`, 'i']))
+            P.MonadicParser.regexp(/"((?:[^"\\]|\\.)*)"/, 1).map((x: any) => B.core.type.regex([`^${x}$`, 'i']))
         ).desc('string');
     },
 
-    Value: function (r:any) {
+    Value: function (r: any) {
         return P.MonadicParser.alt(r.Number, r.String);
     },
 
-    ValueParens: function (r:any) {
+    ValueParens: function (r: any) {
         return P.MonadicParser.alt(
             r.ValueParens,
             r.ValueOperator,
@@ -227,11 +227,11 @@ const lang = P.MonadicParser.createLanguage({
         return P.MonadicParser.alt(...h.getPropertyNameRules(properties, /=~|==|>=|<=|=|!=|>|<|\)|\s|\+|-|\*|\//i));
     },
 
-    ValueOperator: function (r:any) {
+    ValueOperator: function (r: any) {
         return h.combineOperators(valueOperators, P.MonadicParser.alt(r.ValueParens, r.ValueExpressions));
     },
 
-    ValueExpressions: function (r:any) {
+    ValueExpressions: function (r: any) {
         return P.MonadicParser.alt(
             r.ValueFunctions,
             r.Value,
@@ -239,13 +239,13 @@ const lang = P.MonadicParser.createLanguage({
         );
     },
 
-    ValueFunctions: function (r:any) {
+    ValueFunctions: function (r: any) {
         return P.MonadicParser.alt(...h.getFunctionRules(functions, r.ValueOperator));
     },
 
-    ValueQuery: function (r:any) {
+    ValueQuery: function (r: any) {
         return P.MonadicParser.alt(
-            r.ValueOperator.map((x:any) => {
+            r.ValueOperator.map((x: any) => {
                 // if (!x.head || x.head.startsWith('core.math') || x.head.startsWith('structure-query.atom-property')) {
                 if (!x.head || !x.head.startsWith('structure-query.generator')) {
                     throw new Error(`values must be part of an comparison, value '${x}'`);
@@ -258,4 +258,3 @@ const lang = P.MonadicParser.createLanguage({
 });
 
 export const transpiler: Transpiler = str => lang.Query.tryParse(str);
-export default transpiler
diff --git a/src/mol-util/monadic-parser.ts b/src/mol-util/monadic-parser.ts
index 3ea762f5443c81fea4de5ff33abd9f4d43d5b3ea..cbae221a955dafa2777cad4866aa3e4625a8e076 100644
--- a/src/mol-util/monadic-parser.ts
+++ b/src/mol-util/monadic-parser.ts
@@ -8,8 +8,8 @@
  * Copyright (c) 2011-present J. Adkisson (http://jneen.net).
  */
 /**
-*  @author Koya Sakuma 
-*  implementation of seqMap for mol-script/transpiler/helper.ts 
+*  @author Koya Sakuma
+*  implementation of seqMap for mol-script/transpiler/helper.ts
 **/
 
 export class MonadicParser<A> {
@@ -23,7 +23,7 @@ export class MonadicParser<A> {
         return { success: false, index: makeLineColumnIndex(input, result.furthest), expected: result.expected };
     };
 
-    
+
     tryParse(str: string) {
         const result = this.parse(str);
         if (result.success) {
@@ -239,17 +239,17 @@ export namespace MonadicParser {
 
     export type Result<T> = Success<T> | Failure
 
-    
-    export function seqMap( a: MonadicParser<any>,b:MonadicParser<any>,c:any) {
-	var args = [].slice.call(arguments);
-	if (args.length === 0) {
-	    throw new Error("seqMap needs at least one argument");
-	}
-	var mapper = args.pop();
-	assertFunction(mapper);
-	return seq.apply(null, args).map(function(results: any) {
+
+    export function seqMap(a: MonadicParser<any>, b: MonadicParser<any>, c: any) {
+        const args = [].slice.call(arguments);
+        if (args.length === 0) {
+	    throw new Error('seqMap needs at least one argument');
+        }
+        const mapper = args.pop();
+        assertFunction(mapper);
+        return seq.apply(null, args).map(function (results: any) {
 	    return mapper.apply(null, results);
-	});
+        });
     }
 
     export function createLanguage(parsers: any) {
@@ -262,7 +262,7 @@ export namespace MonadicParser {
         return language;
     }
 
-    
+
     export function seq<A>(a: MonadicParser<A>): MonadicParser<[A]>
     export function seq<A, B>(a: MonadicParser<A>, b: MonadicParser<B>): MonadicParser<[A, B]>
     export function seq<A, B, C>(a: MonadicParser<A>, b: MonadicParser<B>, c: MonadicParser<C>): MonadicParser<[A, B, C]>
@@ -342,11 +342,11 @@ export namespace MonadicParser {
         return RegExp('^(?:' + re.source + ')', flags(re));
     }
 
-   
+
     export function regexp(re: RegExp, group = 0) {
         const anchored = anchoredRegexp(re);
         const expected = '' + re;
-        return new MonadicParser<any>( function (input:any, i:any){
+        return new MonadicParser<any>(function (input: any, i: any) {
             const match = anchored.exec(input.slice(i));
             if (match) {
                 if (0 <= group && group <= match.length) {
@@ -368,7 +368,7 @@ export namespace MonadicParser {
     export function fail(expected: string): MonadicParser<any> {
         return new MonadicParser((input, i) => makeFailure(i, expected));
     }
-    
+
     export function lookahead<A>(x: MonadicParser<A> | string | RegExp): MonadicParser<null> {
         if (isParser(x)) {
             return new MonadicParser((input, i) => {
@@ -476,14 +476,14 @@ export namespace MonadicParser {
     export const newline = alt(crlf, lf, cr).desc('newline');
     export const end = alt(newline, eof);
 
-    export function of(A:any){
-	return succeed(A);
+    export function of(A: any) {
+        return succeed(A);
     }
 
-    export function regex(A:any){
-	return regexp(A);
+    export function regex(A: any) {
+        return regexp(A);
     }
-    
+
     MonadicParser.createLanguage = createLanguage;
     MonadicParser.seq = seq;
     MonadicParser.seqMap = seqMap;
@@ -491,7 +491,7 @@ export namespace MonadicParser {
     MonadicParser.regex = regexp;
     MonadicParser.regexp = regexp;
 //    MonadicParser.regexp.lookahead = lookahead;
-    //MonadicParser.RegExp = regexp;
+    // MonadicParser.RegExp = regexp;
 }
 
 function seqPick(idx: number, ...parsers: MonadicParser<any>[]): MonadicParser<any> {
@@ -589,9 +589,9 @@ function isParser(obj: any): obj is MonadicParser<any> {
     return obj instanceof MonadicParser;
 }
 
-function assertFunction(x:any) {
-    if (typeof x !== "function") {
-	throw new Error("not a function: " + x);
+function assertFunction(x: any) {
+    if (typeof x !== 'function') {
+        throw new Error('not a function: ' + x);
     }
 }