Browse Source

Merge remote-tracking branch 'upstream/master'

Sebastian Bittrich 3 years ago
parent
commit
fb2f22f120
47 changed files with 524 additions and 373 deletions
  1. 2 2
      .github/workflows/node.yml
  2. 13 0
      CHANGELOG.md
  3. 84 74
      package-lock.json
  4. 8 6
      package.json
  5. 1 1
      src/apps/docking-viewer/index.ts
  6. 1 1
      src/apps/viewer/app.ts
  7. 1 1
      src/apps/viewer/index.html
  8. 7 5
      src/cli/cifschema/util/cif-dic.ts
  9. 7 3
      src/cli/cifschema/util/generate.ts
  10. 3 3
      src/cli/cifschema/util/schema.ts
  11. 16 12
      src/examples/alpha-orbitals/index.ts
  12. 1 1
      src/examples/basic-wrapper/index.ts
  13. 1 1
      src/examples/lighting/index.ts
  14. 1 1
      src/examples/proteopedia-wrapper/index.ts
  15. 24 1
      src/mol-data/db/_spec/table.spec.ts
  16. 44 18
      src/mol-data/db/column.ts
  17. 2 1
      src/mol-geo/geometry/cylinders/cylinders.ts
  18. 2 1
      src/mol-geo/geometry/mesh/mesh.ts
  19. 2 1
      src/mol-geo/geometry/spheres/spheres.ts
  20. 2 1
      src/mol-geo/geometry/texture-mesh/texture-mesh.ts
  21. 2 2
      src/mol-gl/shader/chunks/wboit-write.glsl.ts
  22. 0 6
      src/mol-gl/shader/direct-volume.frag.ts
  23. 1 2
      src/mol-gl/shader/image.frag.ts
  24. 1 2
      src/mol-gl/shader/lines.frag.ts
  25. 1 2
      src/mol-gl/shader/points.frag.ts
  26. 1 2
      src/mol-gl/shader/text.frag.ts
  27. 23 2
      src/mol-io/reader/cif/schema.ts
  28. 12 11
      src/mol-io/reader/cif/schema/bird.ts
  29. 13 12
      src/mol-io/reader/cif/schema/ccd.ts
  30. 3 3
      src/mol-io/reader/cif/schema/mmcif-extras.ts
  31. 45 40
      src/mol-io/reader/cif/schema/mmcif.ts
  32. 1 1
      src/mol-io/writer/mol/encoder.ts
  33. 5 2
      src/mol-model-formats/structure/basic/entities.ts
  34. 49 49
      src/mol-model-formats/structure/common/component.ts
  35. 11 11
      src/mol-model-formats/structure/pdb/secondary-structure.ts
  36. 1 1
      src/mol-model-formats/structure/property/bonds/chem_comp.ts
  37. 1 1
      src/mol-model-formats/structure/property/bonds/struct_conn.ts
  38. 1 1
      src/mol-model/structure/model/model.ts
  39. 1 1
      src/mol-model/structure/model/properties/common.ts
  40. 4 1
      src/mol-model/structure/model/properties/utils/atomic-derived.ts
  41. 49 46
      src/mol-model/structure/model/types.ts
  42. 1 1
      src/mol-plugin-state/helpers/structure-selection-query.ts
  43. 22 0
      src/mol-plugin-ui/react18.ts
  44. 6 6
      src/mol-plugin-ui/state/common.tsx
  45. 45 31
      src/mol-plugin-ui/task.tsx
  46. 0 1
      src/mol-plugin/behavior/dynamic/volume-streaming/util.ts
  47. 3 2
      src/mol-repr/util.ts

+ 2 - 2
.github/workflows/node.yml

@@ -9,12 +9,12 @@ jobs:
     - uses: actions/checkout@v2
     - uses: actions/setup-node@v2
       with:
-        node-version: 17
+        node-version: 16
     - run: npm ci
     - run: sudo apt-get install xvfb
     - name: Lint
       run: npm run lint
     - name: Test
-      run: xvfb-run --auto-servernum npm run jest
+      run: npm install --no-save "gl@^5.0.0" && xvfb-run --auto-servernum npm run jest
     - name: Build
       run: npm run build

+ 13 - 0
CHANGELOG.md

@@ -6,12 +6,25 @@ Note that since we don't clearly distinguish between a public and private interf
 
 ## [Unreleased]
 
+
+## [v3.6.1] - 2022-04-03
+
+- Fix React18 related UI regressions.
+
+## [v3.6.0] - 2022-04-03
+
 - Check that model and coordinates have same element count when creating a trajectory
 - Fix aromatic rings assignment: do not mix flags and planarity test
 - Improve bonds assignment of coarse grained models: check for IndexPairBonds and exhaustive StructConn
 - Fix unit mapping in bondedAtomicPairs MolScript query
 - Improve pdb parsing: handle non unique atom and chain names (fixes #156)
 - Fix volume streaming for entries with multiple contour lists
+- Add ``allowTransparentBackfaces`` parameter to support double-sided rendering of transparent geometries
+- Fix handling of case insensitive mmCIF enumeration fields (including entity.type)
+- Fix ``disable-wboit`` Viewer GET param
+- Add support for React 18.
+  - Used by importing ``createPluginUI`` from ``mol-plugin-ui/react18``;
+  - In Mol* 4.0, React 18 will become the default option.
 
 ## [v3.5.0] - 2022-03-25
 

+ 84 - 74
package-lock.json

@@ -1,12 +1,12 @@
 {
   "name": "molstar",
-  "version": "3.5.0",
+  "version": "3.6.1",
   "lockfileVersion": 2,
   "requires": true,
   "packages": {
     "": {
       "name": "molstar",
-      "version": "3.5.0",
+      "version": "3.6.1",
       "license": "MIT",
       "dependencies": {
         "@types/argparse": "^2.0.10",
@@ -15,8 +15,6 @@
         "@types/express": "^4.17.13",
         "@types/node": "^16.11.26",
         "@types/node-fetch": "^2.6.1",
-        "@types/react": "^17.0.40",
-        "@types/react-dom": "^17.0.13",
         "@types/swagger-ui-dist": "3.30.1",
         "argparse": "^2.0.1",
         "body-parser": "^1.19.2",
@@ -54,6 +52,8 @@
         "@types/cors": "^2.8.12",
         "@types/gl": "^4.1.0",
         "@types/jest": "^27.4.1",
+        "@types/react": "^17.0.43",
+        "@types/react-dom": "^17.0.14",
         "@typescript-eslint/eslint-plugin": "^5.14.0",
         "@typescript-eslint/parser": "^5.14.0",
         "benchmark": "^2.1.4",
@@ -71,19 +71,21 @@
         "mini-css-extract-plugin": "^2.6.0",
         "path-browserify": "^1.0.1",
         "raw-loader": "^4.0.2",
+        "react": "^18.0.0",
+        "react-dom": "^18.0.0",
         "sass": "^1.49.9",
         "sass-loader": "^12.6.0",
         "simple-git": "^3.3.0",
         "stream-browserify": "^3.0.0",
         "style-loader": "^3.3.1",
         "ts-jest": "^27.1.3",
-        "typescript": "^4.6.2",
+        "typescript": "^4.6.3",
         "webpack": "^5.70.0",
         "webpack-cli": "^4.9.2"
       },
       "peerDependencies": {
-        "react": "^17.0.2 || ^16.14.0",
-        "react-dom": "^17.0.2 || ^16.14.0"
+        "react": "^18.0.0 || ^17.0.2 || ^16.14.0",
+        "react-dom": "^18.0.0 || ^17.0.2 || ^16.14.0"
       }
     },
     "node_modules/@babel/code-frame": {
@@ -2563,7 +2565,8 @@
     "node_modules/@types/prop-types": {
       "version": "15.7.4",
       "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.4.tgz",
-      "integrity": "sha512-rZ5drC/jWjrArrS8BR6SIr4cWpW09RNTYt9AMZo3Jwwif+iacXAqgVjm0B0Bv/S1jhDXKHqRVNCbACkJ89RAnQ=="
+      "integrity": "sha512-rZ5drC/jWjrArrS8BR6SIr4cWpW09RNTYt9AMZo3Jwwif+iacXAqgVjm0B0Bv/S1jhDXKHqRVNCbACkJ89RAnQ==",
+      "dev": true
     },
     "node_modules/@types/qs": {
       "version": "6.9.7",
@@ -2576,9 +2579,10 @@
       "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw=="
     },
     "node_modules/@types/react": {
-      "version": "17.0.40",
-      "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.40.tgz",
-      "integrity": "sha512-UrXhD/JyLH+W70nNSufXqMZNuUD2cXHu6UjCllC6pmOQgBX4SGXOH8fjRka0O0Ee0HrFxapDD8Bwn81Kmiz6jQ==",
+      "version": "17.0.43",
+      "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.43.tgz",
+      "integrity": "sha512-8Q+LNpdxf057brvPu1lMtC5Vn7J119xrP1aq4qiaefNioQUYANF/CYeK4NsKorSZyUGJ66g0IM+4bbjwx45o2A==",
+      "dev": true,
       "dependencies": {
         "@types/prop-types": "*",
         "@types/scheduler": "*",
@@ -2586,9 +2590,10 @@
       }
     },
     "node_modules/@types/react-dom": {
-      "version": "17.0.13",
-      "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-17.0.13.tgz",
-      "integrity": "sha512-wEP+B8hzvy6ORDv1QBhcQia4j6ea4SFIBttHYpXKPFZRviBvknq0FRh3VrIxeXUmsPkwuXVZrVGG7KUVONmXCQ==",
+      "version": "17.0.14",
+      "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-17.0.14.tgz",
+      "integrity": "sha512-H03xwEP1oXmSfl3iobtmQ/2dHF5aBHr8aUMwyGZya6OW45G+xtdzmq6HkncefiBt5JU8DVyaWl/nWZbjZCnzAQ==",
+      "dev": true,
       "dependencies": {
         "@types/react": "*"
       }
@@ -2596,7 +2601,8 @@
     "node_modules/@types/scheduler": {
       "version": "0.16.2",
       "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz",
-      "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew=="
+      "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==",
+      "dev": true
     },
     "node_modules/@types/serve-static": {
       "version": "1.13.10",
@@ -4746,9 +4752,10 @@
       "dev": true
     },
     "node_modules/csstype": {
-      "version": "3.0.10",
-      "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.10.tgz",
-      "integrity": "sha512-2u44ZG2OcNUO9HDp/Jl8C07x6pU/eTR3ncV91SiK3dhG9TWvRVsCoJw14Ckx5DgWkzGA3waZWO3d7pgqpUI/XA=="
+      "version": "3.0.11",
+      "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.11.tgz",
+      "integrity": "sha512-sa6P2wJ+CAbgyy4KFssIb/JNMLxFvKF1pCYCSXS8ZMuqZnMsrxqI2E5sPyoTpxoPU/gVZMzr2zjOfg8GIZOMsw==",
+      "dev": true
     },
     "node_modules/data-urls": {
       "version": "2.0.0",
@@ -8088,7 +8095,8 @@
     "node_modules/js-tokens": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
-      "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
+      "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
+      "dev": true
     },
     "node_modules/js-yaml": {
       "version": "4.1.0",
@@ -9031,6 +9039,7 @@
       "version": "1.4.0",
       "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
       "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
+      "dev": true,
       "dependencies": {
         "js-tokens": "^3.0.0 || ^4.0.0"
       },
@@ -10457,30 +10466,28 @@
       }
     },
     "node_modules/react": {
-      "version": "17.0.2",
-      "resolved": "https://registry.npmjs.org/react/-/react-17.0.2.tgz",
-      "integrity": "sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==",
-      "peer": true,
+      "version": "18.0.0",
+      "resolved": "https://registry.npmjs.org/react/-/react-18.0.0.tgz",
+      "integrity": "sha512-x+VL6wbT4JRVPm7EGxXhZ8w8LTROaxPXOqhlGyVSrv0sB1jkyFGgXxJ8LVoPRLvPR6/CIZGFmfzqUa2NYeMr2A==",
+      "dev": true,
       "dependencies": {
-        "loose-envify": "^1.1.0",
-        "object-assign": "^4.1.1"
+        "loose-envify": "^1.1.0"
       },
       "engines": {
         "node": ">=0.10.0"
       }
     },
     "node_modules/react-dom": {
-      "version": "17.0.2",
-      "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz",
-      "integrity": "sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==",
-      "peer": true,
+      "version": "18.0.0",
+      "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.0.0.tgz",
+      "integrity": "sha512-XqX7uzmFo0pUceWFCt7Gff6IyIMzFUn7QMZrbrQfGxtaxXZIcGQzoNpRLE3fQLnS4XzLLPMZX2T9TRcSrasicw==",
+      "dev": true,
       "dependencies": {
         "loose-envify": "^1.1.0",
-        "object-assign": "^4.1.1",
-        "scheduler": "^0.20.2"
+        "scheduler": "^0.21.0"
       },
       "peerDependencies": {
-        "react": "17.0.2"
+        "react": "^18.0.0"
       }
     },
     "node_modules/react-is": {
@@ -10862,13 +10869,12 @@
       }
     },
     "node_modules/scheduler": {
-      "version": "0.20.2",
-      "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz",
-      "integrity": "sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==",
-      "peer": true,
+      "version": "0.21.0",
+      "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.21.0.tgz",
+      "integrity": "sha512-1r87x5fz9MXqswA2ERLo0EbOAU74DpIUO090gIasYTqlVoJeMcl+Z1Rg7WHz+qtPujhS/hGIt9kxZOYBV3faRQ==",
+      "dev": true,
       "dependencies": {
-        "loose-envify": "^1.1.0",
-        "object-assign": "^4.1.1"
+        "loose-envify": "^1.1.0"
       }
     },
     "node_modules/schema-utils": {
@@ -11919,9 +11925,9 @@
       }
     },
     "node_modules/typescript": {
-      "version": "4.6.2",
-      "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.2.tgz",
-      "integrity": "sha512-HM/hFigTBHZhLXshn9sN37H085+hQGeJHJ/X7LpBWLID/fbc2acUMfU+lGD98X81sKP+pFa9f0DZmCwB9GnbAg==",
+      "version": "4.6.3",
+      "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.3.tgz",
+      "integrity": "sha512-yNIatDa5iaofVozS/uQJEl3JRWLKKGJKh6Yaiv0GLGSuhpFJe7P3SbHZ8/yjAHRQwKRoA6YZqlfjXWmVzoVSMw==",
       "dev": true,
       "bin": {
         "tsc": "bin/tsc",
@@ -14586,7 +14592,8 @@
     "@types/prop-types": {
       "version": "15.7.4",
       "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.4.tgz",
-      "integrity": "sha512-rZ5drC/jWjrArrS8BR6SIr4cWpW09RNTYt9AMZo3Jwwif+iacXAqgVjm0B0Bv/S1jhDXKHqRVNCbACkJ89RAnQ=="
+      "integrity": "sha512-rZ5drC/jWjrArrS8BR6SIr4cWpW09RNTYt9AMZo3Jwwif+iacXAqgVjm0B0Bv/S1jhDXKHqRVNCbACkJ89RAnQ==",
+      "dev": true
     },
     "@types/qs": {
       "version": "6.9.7",
@@ -14599,9 +14606,10 @@
       "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw=="
     },
     "@types/react": {
-      "version": "17.0.40",
-      "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.40.tgz",
-      "integrity": "sha512-UrXhD/JyLH+W70nNSufXqMZNuUD2cXHu6UjCllC6pmOQgBX4SGXOH8fjRka0O0Ee0HrFxapDD8Bwn81Kmiz6jQ==",
+      "version": "17.0.43",
+      "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.43.tgz",
+      "integrity": "sha512-8Q+LNpdxf057brvPu1lMtC5Vn7J119xrP1aq4qiaefNioQUYANF/CYeK4NsKorSZyUGJ66g0IM+4bbjwx45o2A==",
+      "dev": true,
       "requires": {
         "@types/prop-types": "*",
         "@types/scheduler": "*",
@@ -14609,9 +14617,10 @@
       }
     },
     "@types/react-dom": {
-      "version": "17.0.13",
-      "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-17.0.13.tgz",
-      "integrity": "sha512-wEP+B8hzvy6ORDv1QBhcQia4j6ea4SFIBttHYpXKPFZRviBvknq0FRh3VrIxeXUmsPkwuXVZrVGG7KUVONmXCQ==",
+      "version": "17.0.14",
+      "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-17.0.14.tgz",
+      "integrity": "sha512-H03xwEP1oXmSfl3iobtmQ/2dHF5aBHr8aUMwyGZya6OW45G+xtdzmq6HkncefiBt5JU8DVyaWl/nWZbjZCnzAQ==",
+      "dev": true,
       "requires": {
         "@types/react": "*"
       }
@@ -14619,7 +14628,8 @@
     "@types/scheduler": {
       "version": "0.16.2",
       "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz",
-      "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew=="
+      "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==",
+      "dev": true
     },
     "@types/serve-static": {
       "version": "1.13.10",
@@ -16312,9 +16322,10 @@
       }
     },
     "csstype": {
-      "version": "3.0.10",
-      "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.10.tgz",
-      "integrity": "sha512-2u44ZG2OcNUO9HDp/Jl8C07x6pU/eTR3ncV91SiK3dhG9TWvRVsCoJw14Ckx5DgWkzGA3waZWO3d7pgqpUI/XA=="
+      "version": "3.0.11",
+      "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.11.tgz",
+      "integrity": "sha512-sa6P2wJ+CAbgyy4KFssIb/JNMLxFvKF1pCYCSXS8ZMuqZnMsrxqI2E5sPyoTpxoPU/gVZMzr2zjOfg8GIZOMsw==",
+      "dev": true
     },
     "data-urls": {
       "version": "2.0.0",
@@ -18842,7 +18853,8 @@
     "js-tokens": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
-      "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
+      "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
+      "dev": true
     },
     "js-yaml": {
       "version": "4.1.0",
@@ -19589,6 +19601,7 @@
       "version": "1.4.0",
       "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
       "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
+      "dev": true,
       "requires": {
         "js-tokens": "^3.0.0 || ^4.0.0"
       }
@@ -20648,24 +20661,22 @@
       }
     },
     "react": {
-      "version": "17.0.2",
-      "resolved": "https://registry.npmjs.org/react/-/react-17.0.2.tgz",
-      "integrity": "sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==",
-      "peer": true,
+      "version": "18.0.0",
+      "resolved": "https://registry.npmjs.org/react/-/react-18.0.0.tgz",
+      "integrity": "sha512-x+VL6wbT4JRVPm7EGxXhZ8w8LTROaxPXOqhlGyVSrv0sB1jkyFGgXxJ8LVoPRLvPR6/CIZGFmfzqUa2NYeMr2A==",
+      "dev": true,
       "requires": {
-        "loose-envify": "^1.1.0",
-        "object-assign": "^4.1.1"
+        "loose-envify": "^1.1.0"
       }
     },
     "react-dom": {
-      "version": "17.0.2",
-      "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz",
-      "integrity": "sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==",
-      "peer": true,
+      "version": "18.0.0",
+      "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.0.0.tgz",
+      "integrity": "sha512-XqX7uzmFo0pUceWFCt7Gff6IyIMzFUn7QMZrbrQfGxtaxXZIcGQzoNpRLE3fQLnS4XzLLPMZX2T9TRcSrasicw==",
+      "dev": true,
       "requires": {
         "loose-envify": "^1.1.0",
-        "object-assign": "^4.1.1",
-        "scheduler": "^0.20.2"
+        "scheduler": "^0.21.0"
       }
     },
     "react-is": {
@@ -20932,13 +20943,12 @@
       }
     },
     "scheduler": {
-      "version": "0.20.2",
-      "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz",
-      "integrity": "sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==",
-      "peer": true,
+      "version": "0.21.0",
+      "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.21.0.tgz",
+      "integrity": "sha512-1r87x5fz9MXqswA2ERLo0EbOAU74DpIUO090gIasYTqlVoJeMcl+Z1Rg7WHz+qtPujhS/hGIt9kxZOYBV3faRQ==",
+      "dev": true,
       "requires": {
-        "loose-envify": "^1.1.0",
-        "object-assign": "^4.1.1"
+        "loose-envify": "^1.1.0"
       }
     },
     "schema-utils": {
@@ -21718,9 +21728,9 @@
       }
     },
     "typescript": {
-      "version": "4.6.2",
-      "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.2.tgz",
-      "integrity": "sha512-HM/hFigTBHZhLXshn9sN37H085+hQGeJHJ/X7LpBWLID/fbc2acUMfU+lGD98X81sKP+pFa9f0DZmCwB9GnbAg==",
+      "version": "4.6.3",
+      "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.3.tgz",
+      "integrity": "sha512-yNIatDa5iaofVozS/uQJEl3JRWLKKGJKh6Yaiv0GLGSuhpFJe7P3SbHZ8/yjAHRQwKRoA6YZqlfjXWmVzoVSMw==",
       "dev": true
     },
     "ua-parser-js": {

+ 8 - 6
package.json

@@ -1,6 +1,6 @@
 {
   "name": "molstar",
-  "version": "3.5.0",
+  "version": "3.6.1",
   "description": "A comprehensive macromolecular library.",
   "homepage": "https://github.com/molstar/molstar#readme",
   "repository": {
@@ -101,6 +101,8 @@
     "@types/cors": "^2.8.12",
     "@types/gl": "^4.1.0",
     "@types/jest": "^27.4.1",
+    "@types/react": "^17.0.43",
+    "@types/react-dom": "^17.0.14",
     "@typescript-eslint/eslint-plugin": "^5.14.0",
     "@typescript-eslint/parser": "^5.14.0",
     "benchmark": "^2.1.4",
@@ -118,13 +120,15 @@
     "mini-css-extract-plugin": "^2.6.0",
     "path-browserify": "^1.0.1",
     "raw-loader": "^4.0.2",
+    "react": "^18.0.0",
+    "react-dom": "^18.0.0",
     "sass": "^1.49.9",
     "sass-loader": "^12.6.0",
     "simple-git": "^3.3.0",
     "stream-browserify": "^3.0.0",
     "style-loader": "^3.3.1",
     "ts-jest": "^27.1.3",
-    "typescript": "^4.6.2",
+    "typescript": "^4.6.3",
     "webpack": "^5.70.0",
     "webpack-cli": "^4.9.2"
   },
@@ -135,8 +139,6 @@
     "@types/express": "^4.17.13",
     "@types/node": "^16.11.26",
     "@types/node-fetch": "^2.6.1",
-    "@types/react": "^17.0.40",
-    "@types/react-dom": "^17.0.13",
     "@types/swagger-ui-dist": "3.30.1",
     "argparse": "^2.0.1",
     "body-parser": "^1.19.2",
@@ -154,7 +156,7 @@
     "xhr2": "^0.2.1"
   },
   "peerDependencies": {
-    "react": "^17.0.2 || ^16.14.0",
-    "react-dom": "^17.0.2 || ^16.14.0"
+    "react": "^18.0.0 || ^17.0.2 || ^16.14.0",
+    "react-dom": "^18.0.0 || ^17.0.2 || ^16.14.0"
   }
 }

+ 1 - 1
src/apps/docking-viewer/index.ts

@@ -8,7 +8,7 @@
 import { Structure } from '../../mol-model/structure';
 import { BuiltInTrajectoryFormat } from '../../mol-plugin-state/formats/trajectory';
 import { PluginStateObject as PSO, PluginStateTransform } from '../../mol-plugin-state/objects';
-import { createPluginUI } from '../../mol-plugin-ui';
+import { createPluginUI } from '../../mol-plugin-ui/react18';
 import { PluginUIContext } from '../../mol-plugin-ui/context';
 import { PluginLayoutControlsDisplay } from '../../mol-plugin/layout';
 import { DefaultPluginUISpec, PluginUISpec } from '../../mol-plugin-ui/spec';

+ 1 - 1
src/apps/viewer/app.ts

@@ -32,7 +32,7 @@ import { createVolumeRepresentationParams } from '../../mol-plugin-state/helpers
 import { PluginStateObject } from '../../mol-plugin-state/objects';
 import { StateTransforms } from '../../mol-plugin-state/transforms';
 import { TrajectoryFromModelAndCoordinates } from '../../mol-plugin-state/transforms/model';
-import { createPluginUI } from '../../mol-plugin-ui';
+import { createPluginUI } from '../../mol-plugin-ui/react18';
 import { PluginUIContext } from '../../mol-plugin-ui/context';
 import { DefaultPluginUISpec, PluginUISpec } from '../../mol-plugin-ui/spec';
 import { PluginCommands } from '../../mol-plugin/commands';

+ 1 - 1
src/apps/viewer/index.html

@@ -71,7 +71,7 @@
                 pixelScale: parseFloat(pixelScale) || 1,
                 pickScale: parseFloat(pickScale) || 0.25,
                 pickPadding: isNaN(parseFloat(pickPadding)) ? 1 : parseFloat(pickPadding),
-                enableWboit: disableWboit ? true : void 0, // use default value if disable-wboit is not set
+                enableWboit: disableWboit ? false : void 0, // use default value if disable-wboit is not set
                 preferWebgl1: preferWebgl1,
             }).then(viewer => {
                 var snapshotId = getParam('snapshot-id', '[^&]+').trim();

+ 7 - 5
src/cli/cifschema/util/cif-dic.ts

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2017-2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * Copyright (c) 2017-2022 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
  */
@@ -13,15 +13,17 @@ export function getFieldType(type: string, description: string, values?: string[
     switch (type) {
         // mmCIF
         case 'code':
-        case 'ucode':
         case 'line':
-        case 'uline':
         case 'text':
         case 'char':
-        case 'uchar3':
-        case 'uchar1':
         case 'boolean':
             return values && values.length ? EnumCol(values, 'str', description) : StrCol(description);
+        case 'ucode':
+        case 'uline':
+        case 'uchar3':
+        case 'uchar1':
+            // only force lower-case for enums
+            return values && values.length ? EnumCol(values.map(x => x.toLowerCase()), 'lstr', description) : StrCol(description);
         case 'aliasname':
         case 'name':
         case 'idname':

+ 7 - 3
src/cli/cifschema/util/generate.ts

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2017-2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * Copyright (c) 2017-2022 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
  */
@@ -10,7 +10,7 @@ import { FieldPath } from '../../../mol-io/reader/cif/schema';
 
 function header(name: string, info: string, moldataImportPath: string) {
     return `/**
- * Copyright (c) 2017-2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * Copyright (c) 2017-2022 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
  * Code-generated '${name}' schema file. ${info}
  *
@@ -35,13 +35,17 @@ function getTypeShorthands(schema: Database, fields?: Filter) {
         const { columns } = schema.tables[table];
         Object.keys(columns).forEach(columnName => {
             if (fields && !fields[table][columnName]) return;
-            types.add(schema.tables[table].columns[columnName].type);
+            const col = schema.tables[table].columns[columnName];
+            if (col.type === 'enum') types.add(col.subType);
+            types.add(col.type);
         });
     });
     const shorthands: string[] = [];
     types.forEach(type => {
         switch (type) {
             case 'str': shorthands.push('const str = Schema.str;'); break;
+            case 'ustr': shorthands.push('const ustr = Schema.ustr;'); break;
+            case 'lstr': shorthands.push('const lstr = Schema.lstr;'); break;
             case 'int': shorthands.push('const int = Schema.int;'); break;
             case 'float': shorthands.push('const float = Schema.float;'); break;
             case 'coord': shorthands.push('const coord = Schema.coord;'); break;

+ 3 - 3
src/cli/cifschema/util/schema.ts

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2017-2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * Copyright (c) 2017-2022 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
  */
@@ -29,8 +29,8 @@ export function FloatCol(description: string): FloatCol { return { type: 'float'
 export type CoordCol = { type: 'coord' } & BaseCol
 export function CoordCol(description: string): CoordCol { return { type: 'coord', description }; }
 
-export type EnumCol = { type: 'enum', subType: 'int' | 'str', values: string[] } & BaseCol
-export function EnumCol(values: string[], subType: 'int' | 'str', description: string): EnumCol {
+export type EnumCol = { type: 'enum', subType: 'int' | 'str' | 'ustr' | 'lstr', values: string[] } & BaseCol
+export function EnumCol(values: string[], subType: 'int' | 'str' | 'ustr' | 'lstr', description: string): EnumCol {
     return { type: 'enum', description, values, subType };
 }
 

+ 16 - 12
src/examples/alpha-orbitals/index.ts

@@ -11,7 +11,7 @@ import { SphericalBasisOrder } from '../../extensions/alpha-orbitals/spherical-f
 import { BasisAndOrbitals, CreateOrbitalDensityVolume, CreateOrbitalRepresentation3D, CreateOrbitalVolume, StaticBasisAndOrbitals } from '../../extensions/alpha-orbitals/transforms';
 import { canComputeGrid3dOnGPU } from '../../mol-gl/compute/grid3d';
 import { PluginStateObject } from '../../mol-plugin-state/objects';
-import { createPluginUI } from '../../mol-plugin-ui';
+import { createPluginUI } from '../../mol-plugin-ui/react18';
 import { PluginUIContext } from '../../mol-plugin-ui/context';
 import { DefaultPluginUISpec } from '../../mol-plugin-ui/spec';
 import { PluginCommands } from '../../mol-plugin/commands';
@@ -80,20 +80,24 @@ export class AlphaOrbitalsExample {
 
         this.plugin.managers.interactivity.setProps({ granularity: 'element' });
 
-        if (!canComputeGrid3dOnGPU(this.plugin.canvas3d?.webgl)) {
-            PluginCommands.Toast.Show(this.plugin, {
-                title: 'Error',
-                message: `Browser/device does not support required WebGL extension (OES_texture_float).`
+        this.plugin.behaviors.canvas3d.initialized.subscribe(init => {
+            if (!init) return;
+
+            if (!canComputeGrid3dOnGPU(this.plugin.canvas3d?.webgl)) {
+                PluginCommands.Toast.Show(this.plugin, {
+                    title: 'Error',
+                    message: `Browser/device does not support required WebGL extension (OES_texture_float).`
+                });
+                return;
+            }
+
+            this.load({
+                moleculeSdf: DemoMoleculeSDF,
+                ...DemoOrbitals
             });
-            return;
-        }
 
-        this.load({
-            moleculeSdf: DemoMoleculeSDF,
-            ...DemoOrbitals
+            mountControls(this, document.getElementById('controls')!);
         });
-
-        mountControls(this, document.getElementById('controls')!);
     }
 
     readonly params = new BehaviorSubject<ParamDefinition.For<Params>>({} as any);

+ 1 - 1
src/examples/basic-wrapper/index.ts

@@ -9,7 +9,7 @@ import { EmptyLoci } from '../../mol-model/loci';
 import { StructureSelection } from '../../mol-model/structure';
 import { AnimateModelIndex } from '../../mol-plugin-state/animation/built-in/model-index';
 import { BuiltInTrajectoryFormat } from '../../mol-plugin-state/formats/trajectory';
-import { createPluginUI } from '../../mol-plugin-ui';
+import { createPluginUI } from '../../mol-plugin-ui/react18';
 import { PluginUIContext } from '../../mol-plugin-ui/context';
 import { DefaultPluginUISpec } from '../../mol-plugin-ui/spec';
 import { PluginCommands } from '../../mol-plugin/commands';

+ 1 - 1
src/examples/lighting/index.ts

@@ -6,7 +6,7 @@
 
 import { Canvas3DProps } from '../../mol-canvas3d/canvas3d';
 import { BuiltInTrajectoryFormat } from '../../mol-plugin-state/formats/trajectory';
-import { createPluginUI } from '../../mol-plugin-ui';
+import { createPluginUI } from '../../mol-plugin-ui/react18';
 import { PluginUIContext } from '../../mol-plugin-ui/context';
 import { DefaultPluginUISpec } from '../../mol-plugin-ui/spec';
 import { PluginCommands } from '../../mol-plugin/commands';

+ 1 - 1
src/examples/proteopedia-wrapper/index.ts

@@ -10,7 +10,7 @@ import { AnimateModelIndex } from '../../mol-plugin-state/animation/built-in/mod
 import { createStructureRepresentationParams } from '../../mol-plugin-state/helpers/structure-representation-params';
 import { PluginStateObject, PluginStateObject as PSO } from '../../mol-plugin-state/objects';
 import { StateTransforms } from '../../mol-plugin-state/transforms';
-import { createPluginUI } from '../../mol-plugin-ui';
+import { createPluginUI } from '../../mol-plugin-ui/react18';
 import { PluginUIContext } from '../../mol-plugin-ui/context';
 import { DefaultPluginUISpec } from '../../mol-plugin-ui/spec';
 import { CreateVolumeStreamingInfo, InitVolumeStreaming } from '../../mol-plugin/behavior/dynamic/volume-streaming/transformers';

+ 24 - 1
src/mol-data/db/_spec/table.spec.ts

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2017-2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * Copyright (c) 2017-2022 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
  * @author David Sehnal <david.sehnal@gmail.com>
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
@@ -61,6 +61,29 @@ describe('column', () => {
     });
 });
 
+describe('string column', () => {
+    const xs = ['A', 'b', null, undefined];
+    const xsArr = xs.map(x => x ?? '');
+    const xsLC = xs.map(x => (x ?? '').toLowerCase());
+    const arr = Column.ofArray({ array: xs as any, schema: Column.Schema.str });
+    const arrLC = Column.ofArray({ array: xs as any, schema: Column.Schema.Str({ transform: 'lowercase' }) });
+    const aliasedLC = Column.ofArray({ array: xs as any, schema: Column.Schema.Aliased<'a' | 'b'>(Column.Schema.lstr) });
+
+    it('value', () => {
+        for (let i = 0; i < xs.length; i++) {
+            expect(arr.value(i)).toBe(xs[i] ?? '');
+            expect(arrLC.value(i)).toBe(xsLC[i] ?? '');
+            expect(aliasedLC.value(i)).toBe(xsLC[i]);
+        }
+    });
+
+    it('array', () => {
+        expect(arr.toArray()).toEqual(xsArr);
+        expect(arrLC.toArray()).toEqual(xsLC);
+        expect(aliasedLC.toArray()).toEqual(xsLC);
+    });
+});
+
 describe('table', () => {
     const schema = {
         x: Column.Schema.int,

+ 44 - 18
src/mol-data/db/column.ts

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2017-2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * Copyright (c) 2017-2022 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
  * @author David Sehnal <david.sehnal@gmail.com>
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
@@ -25,38 +25,39 @@ interface Column<T> {
 namespace Column {
     export type ArrayCtor<T> = { new(size: number): ArrayLike<T> }
 
-    export type Schema<T = any> = Schema.Str | Schema.Int | Schema.Float | Schema.Coordinate | Schema.Aliased<T> | Schema.Tensor | Schema.List<number|string>
+    export type Schema<T = any> = Schema.Str | Schema.Int | Schema.Float | Schema.Coordinate | Schema.Aliased<T> | Schema.Tensor | Schema.List<number | string>
 
     export namespace Schema {
         // T also serves as a default value for undefined columns
 
         type Base<T extends string> = { valueType: T }
-        export type Str = { '@type': 'str', T: string } & Base<'str'>
+        export type Str = { '@type': 'str', T: string, transform?: 'uppercase' | 'lowercase' } & Base<'str'>
         export type Int = { '@type': 'int', T: number } & Base<'int'>
         export type Float = { '@type': 'float', T: number } & Base<'float'>
         export type Coordinate = { '@type': 'coord', T: number } & Base<'float'>
 
         export type Tensor = { '@type': 'tensor', T: Tensors.Data, space: Tensors.Space, baseType: Int | Float } & Base<'tensor'>
-        export type Aliased<T> = { '@type': 'aliased', T: T } & Base<T extends string ? 'str' : 'int'>
-        export type List<T extends number|string> = { '@type': 'list', T: T[], separator: string, itemParse: (x: string) => T } & Base<'list'>
+        export type Aliased<T> = { '@type': 'aliased', T: T, transform?: T extends string ? 'uppercase' | 'lowercase' : never } & Base<T extends string ? 'str' : 'int'>
+        export type List<T extends number | string> = { '@type': 'list', T: T[], separator: string, itemParse: (x: string) => T } & Base<'list'>
 
         export const str: Str = { '@type': 'str', T: '', valueType: 'str' };
+        export const ustr: Str = { '@type': 'str', T: '', valueType: 'str', transform: 'uppercase' };
+        export const lstr: Str = { '@type': 'str', T: '', valueType: 'str', transform: 'lowercase' };
         export const int: Int = { '@type': 'int', T: 0, valueType: 'int' };
         export const coord: Coordinate = { '@type': 'coord', T: 0, valueType: 'float' };
         export const float: Float = { '@type': 'float', T: 0, valueType: 'float' };
 
-        export function Str(defaultValue = ''): Str { return { '@type': 'str', T: defaultValue, valueType: 'str' }; };
+        export function Str(options?: { defaultValue?: string, transform?: 'uppercase' | 'lowercase' }): Str { return { '@type': 'str', T: options?.defaultValue ?? '', transform: options?.transform, valueType: 'str' }; };
         export function Int(defaultValue = 0): Int { return { '@type': 'int', T: defaultValue, valueType: 'int' }; };
         export function Float(defaultValue = 0): Float { return { '@type': 'float', T: defaultValue, valueType: 'float' }; };
         export function Tensor(space: Tensors.Space, baseType: Int | Float = float): Tensor { return { '@type': 'tensor', T: space.create(), space, valueType: 'tensor', baseType }; }
         export function Vector(dim: number, baseType: Int | Float = float): Tensor { return Tensor(Tensors.Vector(dim, baseType['@type'] === 'int' ? Int32Array : Float64Array), baseType); }
         export function Matrix(rows: number, cols: number, baseType: Int | Float = float): Tensor { return Tensor(Tensors.ColumnMajorMatrix(rows, cols, baseType['@type'] === 'int' ? Int32Array : Float64Array), baseType); }
 
-        export function Aliased<T>(t: Str | Int, defaultValue?: T): Aliased<T> {
-            if (typeof defaultValue !== 'undefined') return { ...t, T: defaultValue } as any as Aliased<T>;
+        export function Aliased<T>(t: Str | Int): Aliased<T> {
             return t as any as Aliased<T>;
         }
-        export function List<T extends number|string>(separator: string, itemParse: (x: string) => T, defaultValue: T[] = []): List<T> {
+        export function List<T extends number | string>(separator: string, itemParse: (x: string) => T, defaultValue: T[] = []): List<T> {
             return { '@type': 'list', T: defaultValue, separator, itemParse, valueType: 'list' };
         }
     }
@@ -287,8 +288,13 @@ function lambdaColumn<T extends Column.Schema>({ value, valueKind, areValuesEqua
 
 function arrayColumn<T extends Column.Schema>({ array, schema, valueKind }: Column.ArraySpec<T>): Column<T['T']> {
     const rowCount = array.length;
+    const defaultValue = schema.T;
     const value: Column<T['T']>['value'] = schema.valueType === 'str'
-        ? row => { const v = array[row]; return typeof v === 'string' ? v : '' + v; }
+        ? (schema as Column.Schema.Str).transform === 'lowercase'
+            ? row => { const v = array[row]; return typeof v === 'string' ? v.toLowerCase() : `${v ?? defaultValue}`.toLowerCase(); }
+            : (schema as Column.Schema.Str).transform === 'uppercase'
+                ? row => { const v = array[row]; return typeof v === 'string' ? v.toUpperCase() : `${v ?? defaultValue}`.toUpperCase(); }
+                : row => { const v = array[row]; return typeof v === 'string' ? v : `${v ?? defaultValue}`; }
         : row => array[row];
 
     const isTyped = ColumnHelpers.isTypedArray(array);
@@ -300,15 +306,35 @@ function arrayColumn<T extends Column.Schema>({ array, schema, valueKind }: Colu
         value,
         valueKind: valueKind ? valueKind : row => Column.ValueKind.Present,
         toArray: schema.valueType === 'str'
-            ? params => {
-                const { start, end } = ColumnHelpers.getArrayBounds(rowCount, params);
-                const ret = new (params && typeof params.array !== 'undefined' ? params.array : (array as any).constructor)(end - start) as any;
-                for (let i = 0, _i = end - start; i < _i; i++) {
-                    const v = array[start + i];
-                    ret[i] = typeof v === 'string' ? v : '' + v;
+            ? (schema as Column.Schema.Str).transform === 'lowercase'
+                ? params => {
+                    const { start, end } = ColumnHelpers.getArrayBounds(rowCount, params);
+                    const ret = new (params && typeof params.array !== 'undefined' ? params.array : (array as any).constructor)(end - start) as any;
+                    for (let i = 0, _i = end - start; i < _i; i++) {
+                        const v = array[start + i];
+                        ret[i] = typeof v === 'string' ? v.toLowerCase() : `${v ?? defaultValue}`.toLowerCase();
+                    }
+                    return ret;
                 }
-                return ret;
-            }
+                : (schema as Column.Schema.Str).transform === 'uppercase'
+                    ? params => {
+                        const { start, end } = ColumnHelpers.getArrayBounds(rowCount, params);
+                        const ret = new (params && typeof params.array !== 'undefined' ? params.array : (array as any).constructor)(end - start) as any;
+                        for (let i = 0, _i = end - start; i < _i; i++) {
+                            const v = array[start + i];
+                            ret[i] = typeof v === 'string' ? v.toUpperCase() : `${v ?? defaultValue}`.toUpperCase();
+                        }
+                        return ret;
+                    }
+                    : params => {
+                        const { start, end } = ColumnHelpers.getArrayBounds(rowCount, params);
+                        const ret = new (params && typeof params.array !== 'undefined' ? params.array : (array as any).constructor)(end - start) as any;
+                        for (let i = 0, _i = end - start; i < _i; i++) {
+                            const v = array[start + i];
+                            ret[i] = typeof v === 'string' ? v : `${v ?? defaultValue}`;
+                        }
+                        return ret;
+                    }
             : isTyped
                 ? params => ColumnHelpers.typedArrayWindow(array, params) as any as ReadonlyArray<T>
                 : params => {

+ 2 - 1
src/mol-geo/geometry/cylinders/cylinders.ts

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * Copyright (c) 2020-2022 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
  */
@@ -157,6 +157,7 @@ export namespace Cylinders {
         doubleSided: PD.Boolean(false, BaseGeometry.CustomQualityParamInfo),
         ignoreLight: PD.Boolean(false, BaseGeometry.ShadingCategory),
         xrayShaded: PD.Boolean(false, BaseGeometry.ShadingCategory),
+        allowTransparentBackfaces: PD.Boolean(false, BaseGeometry.ShadingCategory),
         bumpFrequency: PD.Numeric(0, { min: 0, max: 10, step: 0.1 }, BaseGeometry.ShadingCategory),
         bumpAmplitude: PD.Numeric(1, { min: 0, max: 5, step: 0.1 }, BaseGeometry.ShadingCategory),
     };

+ 2 - 1
src/mol-geo/geometry/mesh/mesh.ts

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2018-2021 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * Copyright (c) 2018-2022 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
  * @author David Sehnal <david.sehnal@gmail.com>
@@ -625,6 +625,7 @@ export namespace Mesh {
         flatShaded: PD.Boolean(false, BaseGeometry.ShadingCategory),
         ignoreLight: PD.Boolean(false, BaseGeometry.ShadingCategory),
         xrayShaded: PD.Boolean(false, BaseGeometry.ShadingCategory),
+        allowTransparentBackfaces: PD.Boolean(false, BaseGeometry.ShadingCategory),
         bumpFrequency: PD.Numeric(0, { min: 0, max: 10, step: 0.1 }, BaseGeometry.ShadingCategory),
         bumpAmplitude: PD.Numeric(1, { min: 0, max: 5, step: 0.1 }, BaseGeometry.ShadingCategory),
     };

+ 2 - 1
src/mol-geo/geometry/spheres/spheres.ts

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2019-2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * Copyright (c) 2019-2022 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
  */
@@ -129,6 +129,7 @@ export namespace Spheres {
         doubleSided: PD.Boolean(false, BaseGeometry.CustomQualityParamInfo),
         ignoreLight: PD.Boolean(false, BaseGeometry.ShadingCategory),
         xrayShaded: PD.Boolean(false, BaseGeometry.ShadingCategory),
+        allowTransparentBackfaces: PD.Boolean(false, BaseGeometry.ShadingCategory),
         bumpFrequency: PD.Numeric(0, { min: 0, max: 10, step: 0.1 }, BaseGeometry.ShadingCategory),
         bumpAmplitude: PD.Numeric(1, { min: 0, max: 5, step: 0.1 }, BaseGeometry.ShadingCategory),
     };

+ 2 - 1
src/mol-geo/geometry/texture-mesh/texture-mesh.ts

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2019-2021 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * Copyright (c) 2019-2022 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
  */
@@ -113,6 +113,7 @@ export namespace TextureMesh {
         flatShaded: PD.Boolean(false, BaseGeometry.ShadingCategory),
         ignoreLight: PD.Boolean(false, BaseGeometry.ShadingCategory),
         xrayShaded: PD.Boolean(false, BaseGeometry.ShadingCategory),
+        allowTransparentBackfaces: PD.Boolean(false, BaseGeometry.ShadingCategory),
         bumpFrequency: PD.Numeric(0, { min: 0, max: 10, step: 0.1 }, BaseGeometry.ShadingCategory),
         bumpAmplitude: PD.Numeric(1, { min: 0, max: 5, step: 0.1 }, BaseGeometry.ShadingCategory),
     };

+ 2 - 2
src/mol-gl/shader/chunks/wboit-write.glsl.ts

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2019-2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * Copyright (c) 2019-2022 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
  * @author Áron Samuel Kovács <aron.kovacs@mail.muni.cz>
@@ -13,7 +13,7 @@ export const wboit_write = `
         }
     } else if (uRenderWboit) {
         // the 'fragmentDepth > 0.99' check is to handle precision issues with packed depth
-        if (preFogAlpha != 1.0 && !interior && (fragmentDepth < getDepth(gl_FragCoord.xy / uDrawingBufferSize) || fragmentDepth > 0.99)) {
+        if (preFogAlpha != 1.0 && (fragmentDepth < getDepth(gl_FragCoord.xy / uDrawingBufferSize) || fragmentDepth > 0.99)) {
             float alpha = gl_FragColor.a;
             float wboitWeight = alpha * clamp(pow(1.0 - fragmentDepth, 2.0), 0.01, 1.0);
             gl_FragColor = vec4(gl_FragColor.rgb * alpha * wboitWeight, alpha);

+ 0 - 6
src/mol-gl/shader/direct-volume.frag.ts

@@ -72,12 +72,7 @@ uniform float uPickingAlphaThreshold;
 uniform bool uTransparentBackground;
 uniform float uXrayEdgeFalloff;
 
-uniform float uInteriorDarkening;
-uniform bool uInteriorColorFlag;
-uniform vec3 uInteriorColor;
-
 uniform bool uRenderWboit;
-uniform bool uDoubleSided;
 
 uniform float uNear;
 uniform float uFar;
@@ -357,7 +352,6 @@ void main() {
 
     float fragmentDepth = calcDepth((uModelView * vec4(start, 1.0)).xyz);
     float preFogAlpha = clamp(preFogAlphaBlended, 0.0, 1.0);
-    bool interior = false;
     #include wboit_write
 }
 `;

+ 1 - 2
src/mol-gl/shader/image.frag.ts

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2020-2021 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * Copyright (c) 2020-2022 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
  */
@@ -99,7 +99,6 @@ void main() {
     if (imageData.a > 0.9) imageData.a = 1.0;
 
     float fragmentDepth = gl_FragCoord.z;
-    bool interior = false;
 
     #if defined(dRenderVariant_pick)
         if (imageData.a < 0.3)

+ 1 - 2
src/mol-gl/shader/lines.frag.ts

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2018-2021 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * Copyright (c) 2018-2022 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
  */
@@ -16,7 +16,6 @@ precision highp int;
 void main(){
     #include clip_pixel
 
-    bool interior = false;
     float fragmentDepth = gl_FragCoord.z;
     #include assign_material_color
 

+ 1 - 2
src/mol-gl/shader/points.frag.ts

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2018-2021 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * Copyright (c) 2018-2022 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
  */
@@ -20,7 +20,6 @@ void main(){
     #include clip_pixel
 
     float fragmentDepth = gl_FragCoord.z;
-    bool interior = false;
     #include assign_material_color
 
     #if defined(dPointStyle_circle)

+ 1 - 2
src/mol-gl/shader/text.frag.ts

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2019-2021 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * Copyright (c) 2019-2022 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
  */
@@ -33,7 +33,6 @@ void main(){
     #include clip_pixel
 
     float fragmentDepth = gl_FragCoord.z;
-    bool interior = false;
     #include assign_material_color
 
     if (vTexCoord.x > 1.0) {

+ 23 - 2
src/mol-io/reader/cif/schema.ts

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2017-2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * Copyright (c) 2017-2022 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
  * @author David Sehnal <david.sehnal@gmail.com>
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
@@ -45,7 +45,7 @@ type ColumnCtor = (field: Data.CifField, category: Data.CifCategory, key: string
 
 function getColumnCtor(t: Column.Schema): ColumnCtor {
     switch (t.valueType) {
-        case 'str': return (f, c, k) => createColumn(t, f, f.str, f.toStringArray);
+        case 'str': return (f, c, k) => createStringColumn(t, f, f.str, f.toStringArray);
         case 'int': return (f, c, k) => createColumn(t, f, f.int, f.toIntArray);
         case 'float': return (f, c, k) => createColumn(t, f, f.float, f.toFloatArray);
         case 'list': throw new Error('Use createListColumn instead.');
@@ -53,6 +53,27 @@ function getColumnCtor(t: Column.Schema): ColumnCtor {
     }
 }
 
+function createStringColumn<T extends string>(schema: Column.Schema.Str | Column.Schema.Aliased<T>, field: Data.CifField, value: (row: number) => T, toArray: Column<T>['toArray']): Column<T> {
+    return {
+        schema,
+        __array: field.__array,
+        isDefined: field.isDefined,
+        rowCount: field.rowCount,
+        value: schema.transform === 'lowercase'
+            ? row => value(row).toLowerCase() as T
+            : schema.transform === 'uppercase'
+                ? row => value(row).toUpperCase() as T
+                : value,
+        valueKind: field.valueKind,
+        areValuesEqual: field.areValuesEqual,
+        toArray: schema.transform === 'lowercase'
+            ? p => Array.from(toArray(p)).map(x => x.toLowerCase() as T)
+            : schema.transform === 'uppercase'
+                ? p => Array.from(toArray(p)).map(x => x.toUpperCase() as T)
+                : toArray,
+    };
+}
+
 function createColumn<T>(schema: Column.Schema, field: Data.CifField, value: (row: number) => T, toArray: Column<T>['toArray']): Column<T> {
     return {
         schema,

+ 12 - 11
src/mol-io/reader/cif/schema/bird.ts

@@ -1,7 +1,7 @@
 /**
- * Copyright (c) 2017-2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * Copyright (c) 2017-2022 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
- * Code-generated 'BIRD' schema file. Dictionary versions: mmCIF 5.356, IHM 1.17, MA 1.3.5.
+ * Code-generated 'BIRD' schema file. Dictionary versions: mmCIF 5.357, IHM 1.17, MA 1.3.6.
  *
  * @author molstar/ciftools package
  */
@@ -12,6 +12,7 @@ import Schema = Column.Schema;
 
 const str = Schema.str;
 const float = Schema.float;
+const lstr = Schema.lstr;
 const Aliased = Schema.Aliased;
 const int = Schema.int;
 
@@ -58,7 +59,7 @@ export const BIRD_Schema = {
         /**
          * Defines the structural classification of the entity.
          */
-        type: Aliased<'Amino acid' | 'Aminoglycoside' | 'Anthracycline' | 'Anthraquinone' | 'Ansamycin' | 'Chalkophore' | 'Chromophore' | 'Glycopeptide' | 'Cyclic depsipeptide' | 'Cyclic lipopeptide' | 'Cyclic peptide' | 'Heterocyclic' | 'Imino sugar' | 'Keto acid' | 'Lipoglycopeptide' | 'Lipopeptide' | 'Macrolide' | 'Non-polymer' | 'Nucleoside' | 'Oligopeptide' | 'Oligosaccharide' | 'Peptaibol' | 'Peptide-like' | 'Polycyclic' | 'Polypeptide' | 'Polysaccharide' | 'Quinolone' | 'Thiolactone' | 'Thiopeptide' | 'Siderophore' | 'Unknown' | 'Chalkophore, Polypeptide'>(str),
+        type: Aliased<'amino acid' | 'aminoglycoside' | 'anthracycline' | 'anthraquinone' | 'ansamycin' | 'chalkophore' | 'chromophore' | 'glycopeptide' | 'cyclic depsipeptide' | 'cyclic lipopeptide' | 'cyclic peptide' | 'heterocyclic' | 'imino sugar' | 'keto acid' | 'lipoglycopeptide' | 'lipopeptide' | 'macrolide' | 'non-polymer' | 'nucleoside' | 'oligopeptide' | 'oligosaccharide' | 'peptaibol' | 'peptide-like' | 'polycyclic' | 'polypeptide' | 'polysaccharide' | 'quinolone' | 'thiolactone' | 'thiopeptide' | 'siderophore' | 'unknown' | 'chalkophore, polypeptide'>(lstr),
         /**
          * Evidence for the assignment of _pdbx_reference_molecule.type
          */
@@ -66,7 +67,7 @@ export const BIRD_Schema = {
         /**
          * Broadly defines the function of the entity.
          */
-        class: Aliased<'Antagonist' | 'Antibiotic' | 'Anticancer' | 'Anticoagulant' | 'Antifungal' | 'Antigen' | 'Antiinflammatory' | 'Antimicrobial' | 'Antineoplastic' | 'Antiparasitic' | 'Antiretroviral' | 'Anthelmintic' | 'Antithrombotic' | 'Antitumor' | 'Antiviral' | 'CASPASE inhibitor' | 'Chaperone binding' | 'Enzyme inhibitor' | 'Drug delivery' | 'Glycan component' | 'Growth factor' | 'Immunosuppressant' | 'Inducer' | 'Inhibitor' | 'Lantibiotic' | 'Metabolism' | 'Metal transport' | 'Nutrient' | 'Oxidation-reduction' | 'Protein binding' | 'Receptor' | 'Substrate analog' | 'Synthetic opioid' | 'Thrombin inhibitor' | 'Transition state mimetic' | 'Transport activator' | 'Trypsin inhibitor' | 'Toxin' | 'Unknown' | 'Water retention' | 'Anticoagulant, Antithrombotic' | 'Antibiotic, Antimicrobial' | 'Antibiotic, Anthelmintic' | 'Antibiotic, Antineoplastic' | 'Antimicrobial, Antiretroviral' | 'Antimicrobial, Antitumor' | 'Antimicrobial, Antiparasitic, Antibiotic' | 'Thrombin inhibitor, Trypsin inhibitor'>(str),
+        class: Aliased<'antagonist' | 'antibiotic' | 'anticancer' | 'anticoagulant' | 'antifungal' | 'antigen' | 'antiinflammatory' | 'antimicrobial' | 'antineoplastic' | 'antiparasitic' | 'antiretroviral' | 'anthelmintic' | 'antithrombotic' | 'antitumor' | 'antiviral' | 'caspase inhibitor' | 'chaperone binding' | 'enzyme inhibitor' | 'drug delivery' | 'glycan component' | 'growth factor' | 'immunosuppressant' | 'inducer' | 'inhibitor' | 'lantibiotic' | 'metabolism' | 'metal transport' | 'nutrient' | 'oxidation-reduction' | 'protein binding' | 'receptor' | 'substrate analog' | 'synthetic opioid' | 'thrombin inhibitor' | 'transition state mimetic' | 'transport activator' | 'trypsin inhibitor' | 'toxin' | 'unknown' | 'water retention' | 'anticoagulant, antithrombotic' | 'antibiotic, antimicrobial' | 'antibiotic, anthelmintic' | 'antibiotic, antineoplastic' | 'antimicrobial, antiretroviral' | 'antimicrobial, antitumor' | 'antimicrobial, antiparasitic, antibiotic' | 'thrombin inhibitor, trypsin inhibitor'>(lstr),
         /**
          * Evidence for the assignment of _pdbx_reference_molecule.class
          */
@@ -78,7 +79,7 @@ export const BIRD_Schema = {
         /**
          * Defines how this entity is represented in PDB data files.
          */
-        represent_as: Aliased<'polymer' | 'single molecule' | 'branched'>(str),
+        represent_as: Aliased<'polymer' | 'single molecule' | 'branched'>(lstr),
         /**
          * For entities represented as single molecules, the identifier
          * corresponding to the chemical definition for the molecule.
@@ -99,7 +100,7 @@ export const BIRD_Schema = {
         /**
          * Defines the current PDB release status for this molecule definition.
          */
-        release_status: Aliased<'REL' | 'HOLD' | 'OBS' | 'WAIT'>(str),
+        release_status: Aliased<'rel' | 'hold' | 'obs' | 'wait'>(lstr),
         /**
          * Assigns the identifier for the reference molecule which have been replaced
          * by this reference molecule.
@@ -129,7 +130,7 @@ export const BIRD_Schema = {
         /**
          * Defines the polymer characteristic of the entity.
          */
-        type: Aliased<'polymer' | 'polymer-like' | 'non-polymer' | 'branched'>(str),
+        type: Aliased<'polymer' | 'polymer-like' | 'non-polymer' | 'branched'>(lstr),
         /**
          * Additional details about this entity.
          */
@@ -249,7 +250,7 @@ export const BIRD_Schema = {
         /**
          * The bond order target for the chemical linkage.
          */
-        value_order: Aliased<'sing' | 'doub' | 'trip' | 'quad' | 'arom' | 'poly' | 'delo' | 'pi'>(str),
+        value_order: Aliased<'sing' | 'doub' | 'trip' | 'quad' | 'arom' | 'poly' | 'delo' | 'pi'>(lstr),
         /**
          * The entity component identifier for the first of two entities containing the linkage.
          */
@@ -335,7 +336,7 @@ export const BIRD_Schema = {
         /**
          * The bond order target for the non-standard linkage.
          */
-        value_order: Aliased<'sing' | 'doub' | 'trip' | 'quad' | 'arom' | 'poly' | 'delo' | 'pi'>(str),
+        value_order: Aliased<'sing' | 'doub' | 'trip' | 'quad' | 'arom' | 'poly' | 'delo' | 'pi'>(lstr),
     },
     /**
      * Data items in the PDBX_REFERENCE_ENTITY_POLY category record details about
@@ -400,11 +401,11 @@ export const BIRD_Schema = {
         /**
          * A flag to indicate that this monomer is observed in the instance example.
          */
-        observed: Aliased<'Y' | 'N'>(str),
+        observed: Aliased<'y' | 'n'>(lstr),
         /**
          * A flag to indicate that sequence heterogeneity at this monomer position.
          */
-        hetero: Aliased<'Y' | 'N'>(str),
+        hetero: Aliased<'y' | 'n'>(lstr),
     },
     /**
      * Additional features associated with the reference entity.

+ 13 - 12
src/mol-io/reader/cif/schema/ccd.ts

@@ -1,7 +1,7 @@
 /**
- * Copyright (c) 2017-2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * Copyright (c) 2017-2022 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
- * Code-generated 'CCD' schema file. Dictionary versions: mmCIF 5.356, IHM 1.17, MA 1.3.5.
+ * Code-generated 'CCD' schema file. Dictionary versions: mmCIF 5.357, IHM 1.17, MA 1.3.6.
  *
  * @author molstar/ciftools package
  */
@@ -13,6 +13,7 @@ import Schema = Column.Schema;
 const str = Schema.str;
 const float = Schema.float;
 const List = Schema.List;
+const lstr = Schema.lstr;
 const Aliased = Schema.Aliased;
 const int = Schema.int;
 const coord = Schema.coord;
@@ -103,7 +104,7 @@ export const CCD_Schema = {
          * linking monomers, monomers with some type of N-terminal (or 5')
          * cap and monomers with some type of C-terminal (or 3') cap.
          */
-        type: Aliased<'D-peptide linking' | 'L-peptide linking' | 'D-peptide NH3 amino terminus' | 'L-peptide NH3 amino terminus' | 'D-peptide COOH carboxy terminus' | 'L-peptide COOH carboxy terminus' | 'DNA linking' | 'RNA linking' | 'L-RNA linking' | 'L-DNA linking' | 'DNA OH 5 prime terminus' | 'RNA OH 5 prime terminus' | 'DNA OH 3 prime terminus' | 'RNA OH 3 prime terminus' | 'D-saccharide, beta linking' | 'D-saccharide, alpha linking' | 'L-saccharide, beta linking' | 'L-saccharide, alpha linking' | 'L-saccharide' | 'D-saccharide' | 'saccharide' | 'non-polymer' | 'peptide linking' | 'peptide-like' | 'L-gamma-peptide, C-delta linking' | 'D-gamma-peptide, C-delta linking' | 'L-beta-peptide, C-gamma linking' | 'D-beta-peptide, C-gamma linking' | 'other'>(str),
+        type: Aliased<'d-peptide linking' | 'l-peptide linking' | 'd-peptide nh3 amino terminus' | 'l-peptide nh3 amino terminus' | 'd-peptide cooh carboxy terminus' | 'l-peptide cooh carboxy terminus' | 'dna linking' | 'rna linking' | 'l-rna linking' | 'l-dna linking' | 'dna oh 5 prime terminus' | 'rna oh 5 prime terminus' | 'dna oh 3 prime terminus' | 'rna oh 3 prime terminus' | 'd-saccharide, beta linking' | 'd-saccharide, alpha linking' | 'l-saccharide, beta linking' | 'l-saccharide, alpha linking' | 'l-saccharide' | 'd-saccharide' | 'saccharide' | 'non-polymer' | 'peptide linking' | 'peptide-like' | 'l-gamma-peptide, c-delta linking' | 'd-gamma-peptide, c-delta linking' | 'l-beta-peptide, c-gamma linking' | 'd-beta-peptide, c-gamma linking' | 'other'>(lstr),
         /**
          * Synonym list for the component.
          */
@@ -154,11 +155,11 @@ export const CCD_Schema = {
         /**
          * This data item identifies if ideal coordinates are missing in this definition.
          */
-        pdbx_ideal_coordinates_missing_flag: Aliased<'Y' | 'N'>(str),
+        pdbx_ideal_coordinates_missing_flag: Aliased<'y' | 'n'>(lstr),
         /**
          * This data item identifies if model coordinates are missing in this definition.
          */
-        pdbx_model_coordinates_missing_flag: Aliased<'Y' | 'N'>(str),
+        pdbx_model_coordinates_missing_flag: Aliased<'y' | 'n'>(lstr),
         /**
          * Date component was added to database.
          */
@@ -279,15 +280,15 @@ export const CCD_Schema = {
         /**
          * The chiral configuration of the atom that is a chiral center.
          */
-        pdbx_stereo_config: Aliased<'R' | 'S' | 'N'>(str),
+        pdbx_stereo_config: Aliased<'r' | 's' | 'n'>(lstr),
         /**
          * A flag indicating an aromatic atom.
          */
-        pdbx_aromatic_flag: Aliased<'Y' | 'N'>(str),
+        pdbx_aromatic_flag: Aliased<'y' | 'n'>(lstr),
         /**
          * A flag indicating a leaving atom.
          */
-        pdbx_leaving_atom_flag: Aliased<'Y' | 'N'>(str),
+        pdbx_leaving_atom_flag: Aliased<'y' | 'n'>(lstr),
     },
     /**
      * Data items in the CHEM_COMP_BOND category record details about
@@ -320,7 +321,7 @@ export const CCD_Schema = {
          * bond associated with the specified atoms, expressed as a bond
          * order.
          */
-        value_order: Aliased<'sing' | 'doub' | 'trip' | 'quad' | 'arom' | 'poly' | 'delo' | 'pi'>(str),
+        value_order: Aliased<'sing' | 'doub' | 'trip' | 'quad' | 'arom' | 'poly' | 'delo' | 'pi'>(lstr),
         /**
          * Ordinal index for the component bond list.
          */
@@ -328,11 +329,11 @@ export const CCD_Schema = {
         /**
          * Stereochemical configuration across a double bond.
          */
-        pdbx_stereo_config: Aliased<'E' | 'Z' | 'N'>(str),
+        pdbx_stereo_config: Aliased<'e' | 'z' | 'n'>(lstr),
         /**
          * A flag indicating an aromatic bond.
          */
-        pdbx_aromatic_flag: Aliased<'Y' | 'N'>(str),
+        pdbx_aromatic_flag: Aliased<'y' | 'n'>(lstr),
     },
     /**
      * Data items in the CHEM_COMP_DESCRIPTOR category provide
@@ -352,7 +353,7 @@ export const CCD_Schema = {
         /**
          * This data item contains the descriptor type.
          */
-        type: Aliased<'SMILES_CANNONICAL' | 'SMILES_CANONICAL' | 'SMILES' | 'InChI' | 'InChI_MAIN' | 'InChI_MAIN_FORMULA' | 'InChI_MAIN_CONNECT' | 'InChI_MAIN_HATOM' | 'InChI_CHARGE' | 'InChI_STEREO' | 'InChI_ISOTOPE' | 'InChI_FIXEDH' | 'InChI_RECONNECT' | 'InChIKey'>(str),
+        type: Aliased<'smiles_cannonical' | 'smiles_canonical' | 'smiles' | 'inchi' | 'inchi_main' | 'inchi_main_formula' | 'inchi_main_connect' | 'inchi_main_hatom' | 'inchi_charge' | 'inchi_stereo' | 'inchi_isotope' | 'inchi_fixedh' | 'inchi_reconnect' | 'inchikey'>(lstr),
         /**
          * This data item contains the name of the program
          * or library used to compute the descriptor.

+ 3 - 3
src/mol-io/reader/cif/schema/mmcif-extras.ts

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2018-2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * Copyright (c) 2018-2022 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
  * @author David Sehnal <david.sehnal@gmail.com>
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
@@ -25,9 +25,9 @@ export const mmCIF_chemCompBond_schema = {
     molstar_protonation_variant: Column.Schema.Str()
 };
 
-/** Has `type` extended with 'Ion' and 'Lipid' */
+/** Has `type` extended with 'ION' and 'LIPID' */
 export const mmCIF_chemComp_schema = {
     ...mmCIF_Schema.chem_comp,
-    type: Column.Schema.Aliased<mmCIF_Schema['chem_comp']['type']['T'] | 'Ion' | 'Lipid'>(Column.Schema.str)
+    type: Column.Schema.Aliased<mmCIF_Schema['chem_comp']['type']['T'] | 'ion' | 'lipid'>(Column.Schema.str)
 };
 export type mmCIF_chemComp_schema = typeof mmCIF_chemComp_schema;

+ 45 - 40
src/mol-io/reader/cif/schema/mmcif.ts

@@ -1,7 +1,7 @@
 /**
- * Copyright (c) 2017-2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * Copyright (c) 2017-2022 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
- * Code-generated 'mmCIF' schema file. Dictionary versions: mmCIF 5.356, IHM 1.17, MA 1.3.5.
+ * Code-generated 'mmCIF' schema file. Dictionary versions: mmCIF 5.357, IHM 1.17, MA 1.3.6.
  *
  * @author molstar/ciftools package
  */
@@ -17,6 +17,7 @@ const coord = Schema.coord;
 const Aliased = Schema.Aliased;
 const Matrix = Schema.Matrix;
 const Vector = Schema.Vector;
+const lstr = Schema.lstr;
 const List = Schema.List;
 
 export const mmCIF_Schema = {
@@ -512,7 +513,7 @@ export const mmCIF_Schema = {
          * _chem_comp.mon_nstd_parent, _chem_comp.mon_nstd_class and
          * _chem_comp.mon_nstd_details data items.
          */
-        mon_nstd_flag: Aliased<'no' | 'n' | 'yes' | 'y'>(str),
+        mon_nstd_flag: Aliased<'no' | 'n' | 'yes' | 'y'>(lstr),
         /**
          * The full name of the component.
          */
@@ -523,7 +524,7 @@ export const mmCIF_Schema = {
          * linking monomers, monomers with some type of N-terminal (or 5')
          * cap and monomers with some type of C-terminal (or 3') cap.
          */
-        type: Aliased<'D-peptide linking' | 'L-peptide linking' | 'D-peptide NH3 amino terminus' | 'L-peptide NH3 amino terminus' | 'D-peptide COOH carboxy terminus' | 'L-peptide COOH carboxy terminus' | 'DNA linking' | 'RNA linking' | 'L-RNA linking' | 'L-DNA linking' | 'DNA OH 5 prime terminus' | 'RNA OH 5 prime terminus' | 'DNA OH 3 prime terminus' | 'RNA OH 3 prime terminus' | 'D-saccharide, beta linking' | 'D-saccharide, alpha linking' | 'L-saccharide, beta linking' | 'L-saccharide, alpha linking' | 'L-saccharide' | 'D-saccharide' | 'saccharide' | 'non-polymer' | 'peptide linking' | 'peptide-like' | 'L-gamma-peptide, C-delta linking' | 'D-gamma-peptide, C-delta linking' | 'L-beta-peptide, C-gamma linking' | 'D-beta-peptide, C-gamma linking' | 'other'>(str),
+        type: Aliased<'d-peptide linking' | 'l-peptide linking' | 'd-peptide nh3 amino terminus' | 'l-peptide nh3 amino terminus' | 'd-peptide cooh carboxy terminus' | 'l-peptide cooh carboxy terminus' | 'dna linking' | 'rna linking' | 'l-rna linking' | 'l-dna linking' | 'dna oh 5 prime terminus' | 'rna oh 5 prime terminus' | 'dna oh 3 prime terminus' | 'rna oh 3 prime terminus' | 'd-saccharide, beta linking' | 'd-saccharide, alpha linking' | 'l-saccharide, beta linking' | 'l-saccharide, alpha linking' | 'l-saccharide' | 'd-saccharide' | 'saccharide' | 'non-polymer' | 'peptide linking' | 'peptide-like' | 'l-gamma-peptide, c-delta linking' | 'd-gamma-peptide, c-delta linking' | 'l-beta-peptide, c-gamma linking' | 'd-beta-peptide, c-gamma linking' | 'other'>(lstr),
         /**
          * Synonym list for the component.
          */
@@ -560,7 +561,7 @@ export const mmCIF_Schema = {
          * bond associated with the specified atoms, expressed as a bond
          * order.
          */
-        value_order: Aliased<'sing' | 'doub' | 'trip' | 'quad' | 'arom' | 'poly' | 'delo' | 'pi'>(str),
+        value_order: Aliased<'sing' | 'doub' | 'trip' | 'quad' | 'arom' | 'poly' | 'delo' | 'pi'>(lstr),
         /**
          * Ordinal index for the component bond list.
          */
@@ -568,11 +569,11 @@ export const mmCIF_Schema = {
         /**
          * Stereochemical configuration across a double bond.
          */
-        pdbx_stereo_config: Aliased<'E' | 'Z' | 'N'>(str),
+        pdbx_stereo_config: Aliased<'e' | 'z' | 'n'>(lstr),
         /**
          * A flag indicating an aromatic bond.
          */
-        pdbx_aromatic_flag: Aliased<'Y' | 'N'>(str),
+        pdbx_aromatic_flag: Aliased<'y' | 'n'>(lstr),
     },
     /**
      * Data items in the CITATION category record details about the
@@ -704,7 +705,7 @@ export const mmCIF_Schema = {
         /**
          * An abbreviation that identifies the database.
          */
-        database_id: Aliased<'AlphaFoldDB' | 'CAS' | 'CSD' | 'EMDB' | 'ICSD' | 'ModelArchive' | 'MDF' | 'MODBASE' | 'NDB' | 'NBS' | 'PDB' | 'PDF' | 'RCSB' | 'SWISS-MODEL_REPOSITORY' | 'EBI' | 'PDBE' | 'BMRB' | 'WWPDB' | 'PDB_ACC'>(str),
+        database_id: Aliased<'alphafolddb' | 'cas' | 'csd' | 'emdb' | 'icsd' | 'modelarchive' | 'mdf' | 'modbase' | 'ndb' | 'nbs' | 'pdb' | 'pdf' | 'rcsb' | 'swiss-model_repository' | 'ebi' | 'pdbe' | 'bmrb' | 'wwpdb' | 'pdb_acc'>(lstr),
         /**
          * The code assigned by the database identified in
          * _database_2.database_id.
@@ -767,7 +768,7 @@ export const mmCIF_Schema = {
          * manipulated sources are expected to have further information in
          * the ENTITY_SRC_GEN category.
          */
-        src_method: Aliased<'nat' | 'man' | 'syn'>(str),
+        src_method: Aliased<'nat' | 'man' | 'syn'>(lstr),
         /**
          * Defines the type of the entity.
          *
@@ -780,7 +781,7 @@ export const mmCIF_Schema = {
          * Water entities are not expected to have corresponding
          * entries in the ENTITY category.
          */
-        type: Aliased<'polymer' | 'non-polymer' | 'macrolide' | 'water' | 'branched'>(str),
+        type: Aliased<'polymer' | 'non-polymer' | 'macrolide' | 'water' | 'branched'>(lstr),
         /**
          * A description of the entity.
          *
@@ -820,12 +821,12 @@ export const mmCIF_Schema = {
          * one monomer-to-monomer link different from that implied by
          * _entity_poly.type.
          */
-        nstd_linkage: Aliased<'no' | 'n' | 'yes' | 'y'>(str),
+        nstd_linkage: Aliased<'no' | 'n' | 'yes' | 'y'>(lstr),
         /**
          * A flag to indicate whether the polymer contains at least
          * one monomer that is not considered standard.
          */
-        nstd_monomer: Aliased<'no' | 'n' | 'yes' | 'y'>(str),
+        nstd_monomer: Aliased<'no' | 'n' | 'yes' | 'y'>(lstr),
         /**
          * The type of the polymer.
          */
@@ -894,6 +895,10 @@ export const mmCIF_Schema = {
          * parent is not specified. Deoxynucleotides are
          * represented by their canonical one-letter codes of A,
          * C, G, or T.
+         *
+         * For modifications with several parent amino acids,
+         * all corresponding parent amino acid codes will be listed
+         * (ex. chromophores).
          */
         pdbx_seq_one_letter_code_can: str,
         /**
@@ -919,7 +924,7 @@ export const mmCIF_Schema = {
          * A flag to indicate whether this monomer in the polymer is
          * heterogeneous in sequence.
          */
-        hetero: Aliased<'no' | 'n' | 'yes' | 'y'>(str),
+        hetero: Aliased<'no' | 'n' | 'yes' | 'y'>(lstr),
         /**
          * This data item is a pointer to _chem_comp.id in the CHEM_COMP
          * category.
@@ -996,7 +1001,7 @@ export const mmCIF_Schema = {
          * The classification of the software according to the most
          * common types.
          */
-        type: Aliased<'program' | 'library' | 'package' | 'filter' | 'jiffy' | 'other'>(str),
+        type: Aliased<'program' | 'library' | 'package' | 'filter' | 'jiffy' | 'other'>(lstr),
         /**
          * The version of the software.
          */
@@ -1119,7 +1124,7 @@ export const mmCIF_Schema = {
          * This data item is a pointer to _struct_conf_type.id in the
          * STRUCT_CONF_TYPE category.
          */
-        conf_type_id: Aliased<'BEND' | 'HELX_P' | 'HELX_OT_P' | 'HELX_RH_P' | 'HELX_RH_OT_P' | 'HELX_RH_AL_P' | 'HELX_RH_GA_P' | 'HELX_RH_OM_P' | 'HELX_RH_PI_P' | 'HELX_RH_27_P' | 'HELX_RH_3T_P' | 'HELX_RH_PP_P' | 'HELX_LH_P' | 'HELX_LH_OT_P' | 'HELX_LH_AL_P' | 'HELX_LH_GA_P' | 'HELX_LH_OM_P' | 'HELX_LH_PI_P' | 'HELX_LH_27_P' | 'HELX_LH_3T_P' | 'HELX_LH_PP_P' | 'HELX_N' | 'HELX_OT_N' | 'HELX_RH_N' | 'HELX_RH_OT_N' | 'HELX_RH_A_N' | 'HELX_RH_B_N' | 'HELX_RH_Z_N' | 'HELX_LH_N' | 'HELX_LH_OT_N' | 'HELX_LH_A_N' | 'HELX_LH_B_N' | 'HELX_LH_Z_N' | 'TURN_P' | 'TURN_OT_P' | 'TURN_TY1_P' | 'TURN_TY1P_P' | 'TURN_TY2_P' | 'TURN_TY2P_P' | 'TURN_TY3_P' | 'TURN_TY3P_P' | 'STRN' | 'OTHER'>(str),
+        conf_type_id: Aliased<'bend' | 'helx_p' | 'helx_ot_p' | 'helx_rh_p' | 'helx_rh_ot_p' | 'helx_rh_al_p' | 'helx_rh_ga_p' | 'helx_rh_om_p' | 'helx_rh_pi_p' | 'helx_rh_27_p' | 'helx_rh_3t_p' | 'helx_rh_pp_p' | 'helx_lh_p' | 'helx_lh_ot_p' | 'helx_lh_al_p' | 'helx_lh_ga_p' | 'helx_lh_om_p' | 'helx_lh_pi_p' | 'helx_lh_27_p' | 'helx_lh_3t_p' | 'helx_lh_pp_p' | 'helx_n' | 'helx_ot_n' | 'helx_rh_n' | 'helx_rh_ot_n' | 'helx_rh_a_n' | 'helx_rh_b_n' | 'helx_rh_z_n' | 'helx_lh_n' | 'helx_lh_ot_n' | 'helx_lh_a_n' | 'helx_lh_b_n' | 'helx_lh_z_n' | 'turn_p' | 'turn_ot_p' | 'turn_ty1_p' | 'turn_ty1p_p' | 'turn_ty2_p' | 'turn_ty2p_p' | 'turn_ty3_p' | 'turn_ty3p_p' | 'strn' | 'other'>(lstr),
         /**
          * A description of special aspects of the conformation assignment.
          */
@@ -1219,7 +1224,7 @@ export const mmCIF_Schema = {
          * This data item is a pointer to _struct_conn_type.id in the
          * STRUCT_CONN_TYPE category.
          */
-        conn_type_id: Aliased<'covale' | 'disulf' | 'metalc' | 'hydrog'>(str),
+        conn_type_id: Aliased<'covale' | 'disulf' | 'metalc' | 'hydrog'>(lstr),
         /**
          * A description of special aspects of the connection.
          */
@@ -1439,7 +1444,7 @@ export const mmCIF_Schema = {
          * The chemical bond order associated with the specified atoms in
          * this contact.
          */
-        pdbx_value_order: Aliased<'sing' | 'doub' | 'trip' | 'quad'>(str),
+        pdbx_value_order: Aliased<'sing' | 'doub' | 'trip' | 'quad'>(lstr),
     },
     /**
      * Data items in the STRUCT_CONN_TYPE category record details
@@ -1454,7 +1459,7 @@ export const mmCIF_Schema = {
         /**
          * The chemical or structural type of the interaction.
          */
-        id: Aliased<'covale' | 'disulf' | 'hydrog' | 'metalc' | 'mismat' | 'saltbr' | 'modres' | 'covale_base' | 'covale_sugar' | 'covale_phosphate'>(str),
+        id: Aliased<'covale' | 'disulf' | 'hydrog' | 'metalc' | 'mismat' | 'saltbr' | 'modres' | 'covale_base' | 'covale_sugar' | 'covale_phosphate'>(lstr),
         /**
          * A reference that specifies the criteria used to define the
          * interaction.
@@ -1808,7 +1813,7 @@ export const mmCIF_Schema = {
         /**
          * The cell settings for this space-group symmetry.
          */
-        cell_setting: Aliased<'triclinic' | 'monoclinic' | 'orthorhombic' | 'tetragonal' | 'rhombohedral' | 'trigonal' | 'hexagonal' | 'cubic'>(str),
+        cell_setting: Aliased<'triclinic' | 'monoclinic' | 'orthorhombic' | 'tetragonal' | 'rhombohedral' | 'trigonal' | 'hexagonal' | 'cubic'>(lstr),
         /**
          * Space-group number from International Tables for Crystallography
          * Vol. A (2002).
@@ -1868,7 +1873,7 @@ export const mmCIF_Schema = {
          * This code indicates whether the entry belongs to
          * Structural Genomics Project.
          */
-        SG_entry: Aliased<'Y' | 'N'>(str),
+        SG_entry: Aliased<'y' | 'n'>(lstr),
         /**
          * The site where the file was deposited.
          */
@@ -1892,7 +1897,7 @@ export const mmCIF_Schema = {
          * A value of 'N' indicates that the no PDB format data file is
          * corresponding to this entry is available in the PDB archive.
          */
-        pdb_format_compatible: Aliased<'Y' | 'N'>(str),
+        pdb_format_compatible: Aliased<'y' | 'n'>(lstr),
     },
     /**
      * The PDBX_NONPOLY_SCHEME category provides residue level nomenclature
@@ -2045,7 +2050,7 @@ export const mmCIF_Schema = {
          * The value of polymer flag indicates whether the unobserved or
          * zero occupancy residue is part of a polymer chain or not
          */
-        polymer_flag: Aliased<'Y' | 'N'>(str),
+        polymer_flag: Aliased<'y' | 'n'>(lstr),
         /**
          * The value of occupancy flag indicates whether the residue
          * is unobserved (= 1) or the coordinates have an occupancy of zero (=0)
@@ -2298,7 +2303,7 @@ export const mmCIF_Schema = {
         /**
          * Defines the polymer characteristic of the entity.
          */
-        type: Aliased<'polymer' | 'polymer-like' | 'non-polymer' | 'branched'>(str),
+        type: Aliased<'polymer' | 'polymer-like' | 'non-polymer' | 'branched'>(lstr),
         /**
          * Additional details about this entity.
          */
@@ -2393,7 +2398,7 @@ export const mmCIF_Schema = {
         /**
          * The bond order target for the chemical linkage.
          */
-        value_order: Aliased<'sing' | 'doub' | 'trip' | 'quad' | 'arom' | 'poly' | 'delo' | 'pi'>(str),
+        value_order: Aliased<'sing' | 'doub' | 'trip' | 'quad' | 'arom' | 'poly' | 'delo' | 'pi'>(lstr),
         /**
          * The entity component identifier for the first of two entities containing the linkage.
          */
@@ -2479,7 +2484,7 @@ export const mmCIF_Schema = {
         /**
          * The bond order target for the non-standard linkage.
          */
-        value_order: Aliased<'sing' | 'doub' | 'trip' | 'quad' | 'arom' | 'poly' | 'delo' | 'pi'>(str),
+        value_order: Aliased<'sing' | 'doub' | 'trip' | 'quad' | 'arom' | 'poly' | 'delo' | 'pi'>(lstr),
     },
     /**
      * Data items in the PDBX_MOLECULE category identify reference molecules
@@ -2514,11 +2519,11 @@ export const mmCIF_Schema = {
         /**
          * Broadly defines the function of the molecule.
          */
-        class: Aliased<'Antagonist' | 'Antibiotic' | 'Anticancer' | 'Anticoagulant' | 'Antifungal' | 'Antigen' | 'Antiinflammatory' | 'Antimicrobial' | 'Antineoplastic' | 'Antiparasitic' | 'Antiretroviral' | 'Anthelmintic' | 'Antithrombotic' | 'Antitumor' | 'Antiviral' | 'CASPASE inhibitor' | 'Chaperone binding' | 'Enzyme inhibitor' | 'Drug delivery' | 'Glycan component' | 'Growth factor' | 'Immunosuppressant' | 'Inducer' | 'Inhibitor' | 'Lantibiotic' | 'Metabolism' | 'Metal transport' | 'Nutrient' | 'Oxidation-reduction' | 'Protein binding' | 'Receptor' | 'Substrate analog' | 'Synthetic opioid' | 'Thrombin inhibitor' | 'Transition state mimetic' | 'Transport activator' | 'Trypsin inhibitor' | 'Toxin' | 'Unknown' | 'Water retention' | 'Anticoagulant, Antithrombotic' | 'Antibiotic, Antimicrobial' | 'Antibiotic, Anthelmintic' | 'Antibiotic, Antineoplastic' | 'Antimicrobial, Antiretroviral' | 'Antimicrobial, Antitumor' | 'Antimicrobial, Antiparasitic, Antibiotic' | 'Thrombin inhibitor, Trypsin inhibitor'>(str),
+        class: Aliased<'antagonist' | 'antibiotic' | 'anticancer' | 'anticoagulant' | 'antifungal' | 'antigen' | 'antiinflammatory' | 'antimicrobial' | 'antineoplastic' | 'antiparasitic' | 'antiretroviral' | 'anthelmintic' | 'antithrombotic' | 'antitumor' | 'antiviral' | 'caspase inhibitor' | 'chaperone binding' | 'enzyme inhibitor' | 'drug delivery' | 'glycan component' | 'growth factor' | 'immunosuppressant' | 'inducer' | 'inhibitor' | 'lantibiotic' | 'metabolism' | 'metal transport' | 'nutrient' | 'oxidation-reduction' | 'protein binding' | 'receptor' | 'substrate analog' | 'synthetic opioid' | 'thrombin inhibitor' | 'transition state mimetic' | 'transport activator' | 'trypsin inhibitor' | 'toxin' | 'unknown' | 'water retention' | 'anticoagulant, antithrombotic' | 'antibiotic, antimicrobial' | 'antibiotic, anthelmintic' | 'antibiotic, antineoplastic' | 'antimicrobial, antiretroviral' | 'antimicrobial, antitumor' | 'antimicrobial, antiparasitic, antibiotic' | 'thrombin inhibitor, trypsin inhibitor'>(lstr),
         /**
          * Defines the structural classification of the molecule.
          */
-        type: Aliased<'Amino acid' | 'Aminoglycoside' | 'Anthracycline' | 'Anthraquinone' | 'Ansamycin' | 'Chalkophore' | 'Chromophore' | 'Glycopeptide' | 'Cyclic depsipeptide' | 'Cyclic lipopeptide' | 'Cyclic peptide' | 'Heterocyclic' | 'Imino sugar' | 'Keto acid' | 'Lipoglycopeptide' | 'Lipopeptide' | 'Macrolide' | 'Non-polymer' | 'Nucleoside' | 'Oligopeptide' | 'Oligosaccharide' | 'Peptaibol' | 'Peptide-like' | 'Polycyclic' | 'Polypeptide' | 'Polysaccharide' | 'Quinolone' | 'Thiolactone' | 'Thiopeptide' | 'Siderophore' | 'Unknown' | 'Chalkophore, Polypeptide'>(str),
+        type: Aliased<'amino acid' | 'aminoglycoside' | 'anthracycline' | 'anthraquinone' | 'ansamycin' | 'chalkophore' | 'chromophore' | 'glycopeptide' | 'cyclic depsipeptide' | 'cyclic lipopeptide' | 'cyclic peptide' | 'heterocyclic' | 'imino sugar' | 'keto acid' | 'lipoglycopeptide' | 'lipopeptide' | 'macrolide' | 'non-polymer' | 'nucleoside' | 'oligopeptide' | 'oligosaccharide' | 'peptaibol' | 'peptide-like' | 'polycyclic' | 'polypeptide' | 'polysaccharide' | 'quinolone' | 'thiolactone' | 'thiopeptide' | 'siderophore' | 'unknown' | 'chalkophore, polypeptide'>(lstr),
         /**
          * A name of the molecule.
          */
@@ -2665,7 +2670,7 @@ export const mmCIF_Schema = {
         /**
          * This data item contains the descriptor type.
          */
-        type: Aliased<'LINUCS' | 'Glycam Condensed Sequence' | 'Glycam Condensed Core Sequence' | 'WURCS'>(str),
+        type: Aliased<'linucs' | 'glycam condensed sequence' | 'glycam condensed core sequence' | 'wurcs'>(lstr),
         /**
          * This data item contains the name of the program
          * or library used to compute the descriptor.
@@ -2740,7 +2745,7 @@ export const mmCIF_Schema = {
          * A flag to indicate whether this monomer in the entity is
          * heterogeneous in sequence.
          */
-        hetero: Aliased<'no' | 'n' | 'yes' | 'y'>(str),
+        hetero: Aliased<'no' | 'n' | 'yes' | 'y'>(lstr),
         /**
          * This data item is a pointer to _chem_comp.id in the CHEM_COMP
          * category.
@@ -2812,7 +2817,7 @@ export const mmCIF_Schema = {
         /**
          * The chiral configuration of the first atom making the linkage.
          */
-        atom_stereo_config_1: Aliased<'R' | 'S' | 'N'>(str),
+        atom_stereo_config_1: Aliased<'r' | 's' | 'n'>(lstr),
         /**
          * The atom identifier/name for the second atom making the linkage.
          */
@@ -2824,11 +2829,11 @@ export const mmCIF_Schema = {
         /**
          * The chiral configuration of the second atom making the linkage.
          */
-        atom_stereo_config_2: Aliased<'R' | 'S' | 'N'>(str),
+        atom_stereo_config_2: Aliased<'r' | 's' | 'n'>(lstr),
         /**
          * The bond order target for the chemical linkage.
          */
-        value_order: Aliased<'sing' | 'doub' | 'trip' | 'quad' | 'arom' | 'poly' | 'delo' | 'pi'>(str),
+        value_order: Aliased<'sing' | 'doub' | 'trip' | 'quad' | 'arom' | 'poly' | 'delo' | 'pi'>(lstr),
     },
     /**
      * Data items in the PDBX_ENTITY_BRANCH category specify the list
@@ -2859,7 +2864,7 @@ export const mmCIF_Schema = {
          * A flag to indicate whether this monomer in the entity is
          * heterogeneous in sequence.
          */
-        hetero: Aliased<'no' | 'n' | 'yes' | 'y'>(str),
+        hetero: Aliased<'no' | 'n' | 'yes' | 'y'>(lstr),
         /**
          * Pointer to _atom_site.label_asym_id.
          */
@@ -3332,15 +3337,15 @@ export const mmCIF_Schema = {
         /**
          * A flag to indicate if the modeling is multi scale.
          */
-        multi_scale_flag: Aliased<'YES' | 'NO'>(str),
+        multi_scale_flag: Aliased<'yes' | 'no'>(lstr),
         /**
          * A flag to indicate if the modeling is multi state.
          */
-        multi_state_flag: Aliased<'YES' | 'NO'>(str),
+        multi_state_flag: Aliased<'yes' | 'no'>(lstr),
         /**
          * A flag to indicate if the modeling involves an ensemble ordered by time or other order.
          */
-        ordered_flag: Aliased<'YES' | 'NO'>(str),
+        ordered_flag: Aliased<'yes' | 'no'>(lstr),
         /**
          * The file id corresponding to the script used in the modeling protocol step.
          * This data item is a pointer to _ihm_external_files.id in the IHM_EXTERNAL_FILES category.
@@ -3629,7 +3634,7 @@ export const mmCIF_Schema = {
          * A flag that indicates whether the dataset is archived in
          * an IHM related database or elsewhere.
          */
-        database_hosted: Aliased<'YES' | 'NO'>(str),
+        database_hosted: Aliased<'yes' | 'no'>(lstr),
     },
     /**
      * Category to define groups or collections of input datasets.
@@ -4236,7 +4241,7 @@ export const mmCIF_Schema = {
          * whether the whole image is used or only a portion of it is used (by masking
          * or by other means) as restraint in the modeling.
          */
-        image_segment_flag: Aliased<'YES' | 'NO'>(str),
+        image_segment_flag: Aliased<'yes' | 'no'>(lstr),
         /**
          * Number of 2D projections of the model used in the fitting.
          */
@@ -4389,7 +4394,7 @@ export const mmCIF_Schema = {
          * whether the whole SAS profile is used or only a portion of it is used
          * (by masking or by other means) as restraint in the modeling.
          */
-        profile_segment_flag: Aliased<'YES' | 'NO'>(str),
+        profile_segment_flag: Aliased<'yes' | 'no'>(lstr),
         /**
          * The type of atoms in the model fit to the SAS data.
          */
@@ -4983,7 +4988,7 @@ export const mmCIF_Schema = {
         /**
          * The type of QA metric.
          */
-        type: Aliased<'zscore' | 'energy' | 'distance' | 'normalized score' | 'pLDDT' | 'PAE' | 'contact probability' | 'other'>(str),
+        type: Aliased<'zscore' | 'energy' | 'distance' | 'normalized score' | 'pLDDT' | 'pLDDT in [0,1]' | 'pLDDT all-atom' | 'pLDDT all-atom in [0,1]' | 'PAE' | 'pTM' | 'ipTM' | 'contact probability' | 'other'>(str),
         /**
          * The mode of calculation of the QA metric.
          */

+ 1 - 1
src/mol-io/writer/mol/encoder.ts

@@ -55,7 +55,7 @@ export class MolEncoder extends LigandEncoder {
             StringBuilder.writeSafe(ctab, '  0');
             StringBuilder.writeIntegerPadLeft(ctab, this.mapCharge(charge), 3);
             StringBuilder.writeSafe(ctab, '  0  0  0  0  0  0  0  0  0  0\n');
-            if (stereo_config !== 'N') chiral = true;
+            if (stereo_config !== 'n') chiral = true;
 
             // no data for metal ions
             if (!bondMap?.map) return;

+ 5 - 2
src/mol-model-formats/structure/basic/entities.ts

@@ -10,6 +10,9 @@ import { Entities, EntitySubtype } from '../../../mol-model/structure/model/prop
 import { getEntityType, getEntitySubtype } from '../../../mol-model/structure/model/types';
 import { ElementIndex, EntityIndex, Model } from '../../../mol-model/structure/model';
 import { BasicData, BasicSchema, Entity } from './schema';
+import { mmCIF_chemComp_schema } from '../../../mol-io/reader/cif/schema/mmcif-extras';
+
+type ChemCompType = mmCIF_chemComp_schema['type']['T'];
 
 export function getEntityData(data: BasicData): Entities {
     let entityData: Entity;
@@ -96,7 +99,7 @@ export function getEntityData(data: BasicData): Entities {
     }
 
     if (assignSubtype) {
-        const chemCompType = new Map<string, string>();
+        const chemCompType = new Map<string, ChemCompType>();
         if (data.chem_comp) {
             const { id, type } = data.chem_comp;
             for (let i = 0, il = data.chem_comp._rowCount; i < il; i++) {
@@ -110,7 +113,7 @@ export function getEntityData(data: BasicData): Entities {
                 const entityId = label_entity_id.value(i);
                 if (!entityIds.has(entityId)) {
                     const compId = label_comp_id.value(i);
-                    const compType = chemCompType.get(compId) || '';
+                    const compType = chemCompType.get(compId) || 'other';
                     subtypes[getEntityIndex(entityId)] = getEntitySubtype(compId, compType);
                     entityIds.add(entityId);
                 }

+ 49 - 49
src/mol-model-formats/structure/common/component.ts

@@ -37,48 +37,48 @@ const NonPolymerNames = new Set([
 const StandardComponents = (function () {
     const map = new Map<string, Component>();
     const components: Component[] = [
-        { id: 'HIS', name: 'HISTIDINE', type: 'L-peptide linking' },
-        { id: 'ARG', name: 'ARGININE', type: 'L-peptide linking' },
-        { id: 'LYS', name: 'LYSINE', type: 'L-peptide linking' },
-        { id: 'ILE', name: 'ISOLEUCINE', type: 'L-peptide linking' },
-        { id: 'PHE', name: 'PHENYLALANINE', type: 'L-peptide linking' },
-        { id: 'LEU', name: 'LEUCINE', type: 'L-peptide linking' },
-        { id: 'TRP', name: 'TRYPTOPHAN', type: 'L-peptide linking' },
-        { id: 'ALA', name: 'ALANINE', type: 'L-peptide linking' },
-        { id: 'MET', name: 'METHIONINE', type: 'L-peptide linking' },
-        { id: 'CYS', name: 'CYSTEINE', type: 'L-peptide linking' },
-        { id: 'ASN', name: 'ASPARAGINE', type: 'L-peptide linking' },
-        { id: 'VAL', name: 'VALINE', type: 'L-peptide linking' },
+        { id: 'HIS', name: 'HISTIDINE', type: 'l-peptide linking' },
+        { id: 'ARG', name: 'ARGININE', type: 'l-peptide linking' },
+        { id: 'LYS', name: 'LYSINE', type: 'l-peptide linking' },
+        { id: 'ILE', name: 'ISOLEUCINE', type: 'l-peptide linking' },
+        { id: 'PHE', name: 'PHENYLALANINE', type: 'l-peptide linking' },
+        { id: 'LEU', name: 'LEUCINE', type: 'l-peptide linking' },
+        { id: 'TRP', name: 'TRYPTOPHAN', type: 'l-peptide linking' },
+        { id: 'ALA', name: 'ALANINE', type: 'l-peptide linking' },
+        { id: 'MET', name: 'METHIONINE', type: 'l-peptide linking' },
+        { id: 'CYS', name: 'CYSTEINE', type: 'l-peptide linking' },
+        { id: 'ASN', name: 'ASPARAGINE', type: 'l-peptide linking' },
+        { id: 'VAL', name: 'VALINE', type: 'l-peptide linking' },
         { id: 'GLY', name: 'GLYCINE', type: 'peptide linking' },
-        { id: 'SER', name: 'SERINE', type: 'L-peptide linking' },
-        { id: 'GLN', name: 'GLUTAMINE', type: 'L-peptide linking' },
-        { id: 'TYR', name: 'TYROSINE', type: 'L-peptide linking' },
-        { id: 'ASP', name: 'ASPARTIC ACID', type: 'L-peptide linking' },
-        { id: 'GLU', name: 'GLUTAMIC ACID', type: 'L-peptide linking' },
-        { id: 'THR', name: 'THREONINE', type: 'L-peptide linking' },
-        { id: 'PRO', name: 'PROLINE', type: 'L-peptide linking' },
-        { id: 'SEC', name: 'SELENOCYSTEINE', type: 'L-peptide linking' },
-        { id: 'PYL', name: 'PYRROLYSINE', type: 'L-peptide linking' },
-
-        { id: 'MSE', name: 'SELENOMETHIONINE', type: 'L-peptide linking' },
-        { id: 'SEP', name: 'PHOSPHOSERINE', type: 'L-peptide linking' },
-        { id: 'TPO', name: 'PHOSPHOTHREONINE', type: 'L-peptide linking' },
-        { id: 'PTR', name: 'O-PHOSPHOTYROSINE', type: 'L-peptide linking' },
-        { id: 'PCA', name: 'PYROGLUTAMIC ACID', type: 'L-peptide linking' },
-
-        { id: 'A', name: 'ADENOSINE-5\'-MONOPHOSPHATE', type: 'RNA linking' },
-        { id: 'C', name: 'CYTIDINE-5\'-MONOPHOSPHATE', type: 'RNA linking' },
-        { id: 'T', name: 'THYMIDINE-5\'-MONOPHOSPHATE', type: 'RNA linking' },
-        { id: 'G', name: 'GUANOSINE-5\'-MONOPHOSPHATE', type: 'RNA linking' },
-        { id: 'I', name: 'INOSINIC ACID', type: 'RNA linking' },
-        { id: 'U', name: 'URIDINE-5\'-MONOPHOSPHATE', type: 'RNA linking' },
-
-        { id: 'DA', name: '2\'-DEOXYADENOSINE-5\'-MONOPHOSPHATE', type: 'DNA linking' },
-        { id: 'DC', name: '2\'-DEOXYCYTIDINE-5\'-MONOPHOSPHATE', type: 'DNA linking' },
-        { id: 'DT', name: 'THYMIDINE-5\'-MONOPHOSPHATE', type: 'DNA linking' },
-        { id: 'DG', name: '2\'-DEOXYGUANOSINE-5\'-MONOPHOSPHATE', type: 'DNA linking' },
-        { id: 'DI', name: '2\'-DEOXYINOSINE-5\'-MONOPHOSPHATE', type: 'DNA linking' },
-        { id: 'DU', name: '2\'-DEOXYURIDINE-5\'-MONOPHOSPHATE', type: 'DNA linking' },
+        { id: 'SER', name: 'SERINE', type: 'l-peptide linking' },
+        { id: 'GLN', name: 'GLUTAMINE', type: 'l-peptide linking' },
+        { id: 'TYR', name: 'TYROSINE', type: 'l-peptide linking' },
+        { id: 'ASP', name: 'ASPARTIC ACID', type: 'l-peptide linking' },
+        { id: 'GLU', name: 'GLUTAMIC ACID', type: 'l-peptide linking' },
+        { id: 'THR', name: 'THREONINE', type: 'l-peptide linking' },
+        { id: 'PRO', name: 'PROLINE', type: 'l-peptide linking' },
+        { id: 'SEC', name: 'SELENOCYSTEINE', type: 'l-peptide linking' },
+        { id: 'PYL', name: 'PYRROLYSINE', type: 'l-peptide linking' },
+
+        { id: 'MSE', name: 'SELENOMETHIONINE', type: 'l-peptide linking' },
+        { id: 'SEP', name: 'PHOSPHOSERINE', type: 'l-peptide linking' },
+        { id: 'TPO', name: 'PHOSPHOTHREONINE', type: 'l-peptide linking' },
+        { id: 'PTR', name: 'O-PHOSPHOTYROSINE', type: 'l-peptide linking' },
+        { id: 'PCA', name: 'PYROGLUTAMIC ACID', type: 'l-peptide linking' },
+
+        { id: 'A', name: 'ADENOSINE-5\'-MONOPHOSPHATE', type: 'rna linking' },
+        { id: 'C', name: 'CYTIDINE-5\'-MONOPHOSPHATE', type: 'rna linking' },
+        { id: 'T', name: 'THYMIDINE-5\'-MONOPHOSPHATE', type: 'rna linking' },
+        { id: 'G', name: 'GUANOSINE-5\'-MONOPHOSPHATE', type: 'rna linking' },
+        { id: 'I', name: 'INOSINIC ACID', type: 'rna linking' },
+        { id: 'U', name: 'URIDINE-5\'-MONOPHOSPHATE', type: 'rna linking' },
+
+        { id: 'DA', name: '2\'-DEOXYADENOSINE-5\'-MONOPHOSPHATE', type: 'dna linking' },
+        { id: 'DC', name: '2\'-DEOXYCYTIDINE-5\'-MONOPHOSPHATE', type: 'dna linking' },
+        { id: 'DT', name: 'THYMIDINE-5\'-MONOPHOSPHATE', type: 'dna linking' },
+        { id: 'DG', name: '2\'-DEOXYGUANOSINE-5\'-MONOPHOSPHATE', type: 'dna linking' },
+        { id: 'DI', name: '2\'-DEOXYINOSINE-5\'-MONOPHOSPHATE', type: 'dna linking' },
+        { id: 'DU', name: '2\'-DEOXYURIDINE-5\'-MONOPHOSPHATE', type: 'dna linking' },
     ];
     components.forEach(c => map.set(c.id, c));
     return map;
@@ -87,12 +87,12 @@ const StandardComponents = (function () {
 const CharmmIonComponents = (function () {
     const map = new Map<string, Component>();
     const components: Component[] = [
-        { id: 'ZN2', name: 'ZINC ION', type: 'Ion' },
-        { id: 'SOD', name: 'SODIUM ION', type: 'Ion' },
-        { id: 'CES', name: 'CESIUM ION', type: 'Ion' },
-        { id: 'CLA', name: 'CHLORIDE ION', type: 'Ion' },
-        { id: 'CAL', name: 'CALCIUM ION', type: 'Ion' },
-        { id: 'POT', name: 'POTASSIUM ION', type: 'Ion' },
+        { id: 'ZN2', name: 'ZINC ION', type: 'ion' },
+        { id: 'SOD', name: 'SODIUM ION', type: 'ion' },
+        { id: 'CES', name: 'CESIUM ION', type: 'ion' },
+        { id: 'CLA', name: 'CHLORIDE ION', type: 'ion' },
+        { id: 'CAL', name: 'CALCIUM ION', type: 'ion' },
+        { id: 'POT', name: 'POTASSIUM ION', type: 'ion' },
     ];
     components.forEach(c => map.set(c.id, c));
     return map;
@@ -140,9 +140,9 @@ export class ComponentBuilder {
         if (this.hasAtomIds(atomIds, ProteinAtomIdsList)) {
             return 'peptide linking';
         } else if (this.hasAtomIds(atomIds, RnaAtomIdsList)) {
-            return 'RNA linking';
+            return 'rna linking';
         } else if (this.hasAtomIds(atomIds, DnaAtomIdsList)) {
-            return 'DNA linking';
+            return 'dna linking';
         } else {
             return 'other';
         }

+ 11 - 11
src/mol-model-formats/structure/pdb/secondary-structure.ts

@@ -23,19 +23,19 @@ const HelixTypes: {[k: string]: mmCIF_Schema['struct_conf']['conf_type_id']['T']
     // Left-handed gamma                           8
     // 2 - 7 ribbon/helix                          9
     // Polyproline                                10
-    1: 'HELX_RH_AL_P',
-    2: 'HELX_RH_OM_P',
-    3: 'HELX_RH_PI_P',
-    4: 'HELX_RH_GA_P',
-    5: 'HELX_RH_3T_P',
-    6: 'HELX_LH_AL_P',
-    7: 'HELX_LH_OM_P',
-    8: 'HELX_LH_GA_P',
-    9: 'HELX_RH_27_P', // TODO or left-handed???
-    10: 'HELX_RH_PP_P', // TODO or left-handed???
+    1: 'helx_rh_al_p',
+    2: 'helx_rh_om_p',
+    3: 'helx_rh_pi_p',
+    4: 'helx_rh_ga_p',
+    5: 'helx_rh_3t_p',
+    6: 'helx_lh_al_p',
+    7: 'helx_lh_om_p',
+    8: 'helx_lh_ga_p',
+    9: 'helx_rh_27_p', // TODO or left-handed???
+    10: 'helx_rh_pp_p', // TODO or left-handed???
 };
 function getStructConfTypeId(type: string): mmCIF_Schema['struct_conf']['conf_type_id']['T'] {
-    return HelixTypes[type] || 'HELX_P';
+    return HelixTypes[type] || 'helx_p';
 }
 
 interface PdbHelix {

+ 1 - 1
src/mol-model-formats/structure/property/bonds/chem_comp.ts

@@ -73,7 +73,7 @@ export namespace ComponentBond {
             const nameA = atom_id_1.value(i)!;
             const nameB = atom_id_2.value(i)!;
             const order = value_order.value(i)!;
-            const aromatic = pdbx_aromatic_flag.value(i) === 'Y';
+            const aromatic = pdbx_aromatic_flag.value(i) === 'y';
 
             if (entry.id !== id) {
                 entry = addEntry(id);

+ 1 - 1
src/mol-model-formats/structure/property/bonds/struct_conn.ts

@@ -138,7 +138,7 @@ export namespace StructConn {
             if (partnerA === undefined || partnerB === undefined) continue;
 
             const type = conn_type_id.value(i);
-            const orderType = (pdbx_value_order.value(i) || '').toLowerCase();
+            const orderType = (pdbx_value_order.value(i) || '');
             let flags = BondType.Flag.None;
             let order = 1;
 

+ 1 - 1
src/mol-model/structure/model/model.ts

@@ -303,7 +303,7 @@ export namespace Model {
         if (!MmcifFormat.is(model.sourceData)) return false;
         const { db } = model.sourceData.data;
         for (let i = 0, il = db.database_2.database_id.rowCount; i < il; ++i) {
-            if (db.database_2.database_id.value(i) === 'PDB') return true;
+            if (db.database_2.database_id.value(i) === 'pdb') return true;
         }
         return false;
     }

+ 1 - 1
src/mol-model/structure/model/properties/common.ts

@@ -17,7 +17,7 @@ export type EntitySubtype = (
     'lipid' |
     'peptide-like'
 )
-export const EntitySubtype = Column.Schema.Aliased<EntitySubtype>(Column.Schema.Str(''));
+export const EntitySubtype = Column.Schema.Aliased<EntitySubtype>(Column.Schema.Str());
 
 export interface Entities {
     data: mmCIF_Database['entity'],

+ 4 - 1
src/mol-model/structure/model/properties/utils/atomic-derived.ts

@@ -11,6 +11,9 @@ import { MoleculeType, getMoleculeType, getComponentType, PolymerType, getPolyme
 import { getAtomIdForAtomRole } from '../../../../../mol-model/structure/util';
 import { ChemicalComponentMap } from '../common';
 import { isProductionMode } from '../../../../../mol-util/debug';
+import { mmCIF_chemComp_schema } from '../../../../../mol-io/reader/cif/schema/mmcif-extras';
+
+type ChemCompType = mmCIF_chemComp_schema['type']['T'];
 
 export function getAtomicDerivedData(data: AtomicData, segments: AtomicSegments, index: AtomicIndex, chemicalComponentMap: ChemicalComponentMap): AtomicDerivedData {
     const { label_comp_id, type_symbol, _rowCount: atomCount } = data.atoms;
@@ -42,7 +45,7 @@ export function getAtomicDerivedData(data: AtomicData, segments: AtomicSegments,
             molType = moleculeTypeMap.get(compId)!;
             polyType = polymerTypeMap.get(compId)!;
         } else {
-            let type: string;
+            let type: ChemCompType;
             if (chemCompMap.has(compId)) {
                 type = chemCompMap.get(compId)!.type;
             } else {

+ 49 - 46
src/mol-model/structure/model/types.ts

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2017-2021 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * Copyright (c) 2017-2022 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
  * @author David Sehnal <david.sehnal@gmail.com>
@@ -162,39 +162,41 @@ export const NucleicBackboneAtoms = new Set([
     'O2*', 'O3*', 'O4*', 'O5*', 'C1*', 'C2*', 'C3*', 'C4*', 'C5*'
 ]);
 
+type ChemCompType = mmCIF_chemComp_schema['type']['T'];
+
 /** Chemical component type names for D-linked protein */
-export const DProteinComponentTypeNames = new Set([
-    'D-PEPTIDE LINKING', 'D-PEPTIDE NH3 AMINO TERMINUS',
-    'D-PEPTIDE COOH CARBOXY TERMINUS', 'D-GAMMA-PEPTIDE, C-DELTA LINKING',
-    'D-BETA-PEPTIDE, C-GAMMA LINKING'
+export const DProteinComponentTypeNames = new Set<ChemCompType>([
+    'd-peptide linking', 'd-peptide nh3 amino terminus',
+    'd-peptide cooh carboxy terminus', 'd-gamma-peptide, c-delta linking',
+    'd-beta-peptide, c-gamma linking'
 ]);
 
 /** Chemical component type names for L-linked protein */
-export const LProteinComponentTypeNames = new Set([
-    'L-PEPTIDE LINKING', 'L-PEPTIDE NH3 AMINO TERMINUS',
-    'L-PEPTIDE COOH CARBOXY TERMINUS', 'L-GAMMA-PEPTIDE, C-DELTA LINKING',
-    'L-BETA-PEPTIDE, C-GAMMA LINKING'
+export const LProteinComponentTypeNames = new Set<ChemCompType>([
+    'l-peptide linking', 'l-peptide nh3 amino terminus',
+    'l-peptide cooh carboxy terminus', 'l-gamma-peptide, c-delta linking',
+    'l-beta-peptide, c-gamma linking'
 ]);
 
 /** Chemical component type names for gamma protein, overlaps with D/L-linked */
-export const GammaProteinComponentTypeNames = new Set([
-    'D-GAMMA-PEPTIDE, C-DELTA LINKING', 'L-GAMMA-PEPTIDE, C-DELTA LINKING'
+export const GammaProteinComponentTypeNames = new Set<ChemCompType>([
+    'd-gamma-peptide, c-delta linking', 'l-gamma-peptide, c-delta linking'
 ]);
 
 /** Chemical component type names for beta protein, overlaps with D/L-linked */
-export const BetaProteinComponentTypeNames = new Set([
-    'D-BETA-PEPTIDE, C-GAMMA LINKING', 'L-BETA-PEPTIDE, C-GAMMA LINKING'
+export const BetaProteinComponentTypeNames = new Set<ChemCompType>([
+    'd-beta-peptide, c-gamma linking', 'l-beta-peptide, c-gamma linking'
 ]);
 
 /** Chemical component type names for protein termini, overlaps with D/L-linked */
-export const ProteinTerminusComponentTypeNames = new Set([
-    'D-PEPTIDE NH3 AMINO TERMINUS', 'D-PEPTIDE COOH CARBOXY TERMINUS',
-    'L-PEPTIDE NH3 AMINO TERMINUS', 'L-PEPTIDE COOH CARBOXY TERMINUS'
+export const ProteinTerminusComponentTypeNames = new Set<ChemCompType>([
+    'd-peptide nh3 amino terminus', 'd-peptide cooh carboxy terminus',
+    'l-peptide nh3 amino terminus', 'l-peptide cooh carboxy terminus'
 ]);
 
 /** Chemical component type names for peptide-like protein */
-export const OtherProteinComponentTypeNames = new Set([
-    'PEPTIDE LINKING', 'PEPTIDE-LIKE',
+export const OtherProteinComponentTypeNames = new Set<ChemCompType>([
+    'peptide linking', 'peptide-like',
 ]);
 
 /** Chemical component type names for protein */
@@ -203,38 +205,42 @@ export const ProteinComponentTypeNames = SetUtils.unionMany(
 );
 
 /** Chemical component type names for DNA */
-export const DNAComponentTypeNames = new Set([
-    'DNA LINKING', 'L-DNA LINKING', 'DNA OH 5 PRIME TERMINUS', 'DNA OH 3 PRIME TERMINUS',
+export const DNAComponentTypeNames = new Set<ChemCompType>([
+    'dna linking', 'l-dna linking', 'dna oh 5 prime terminus', 'dna oh 3 prime terminus',
 ]);
 
 /** Chemical component type names for RNA */
-export const RNAComponentTypeNames = new Set([
-    'RNA LINKING', 'L-RNA LINKING', 'RNA OH 5 PRIME TERMINUS', 'RNA OH 3 PRIME TERMINUS',
+export const RNAComponentTypeNames = new Set<ChemCompType>([
+    'rna linking', 'l-rna linking', 'rna oh 5 prime terminus', 'rna oh 3 prime terminus',
 ]);
 
 /** Chemical component type names for saccharide */
-export const SaccharideComponentTypeNames = new Set([
-    'D-SACCHARIDE, BETA LINKING', 'L-SACCHARIDE, BETA LINKING',
-    'D-SACCHARIDE, ALPHA LINKING', 'L-SACCHARIDE, ALPHA LINKING',
-    'L-SACCHARIDE', 'D-SACCHARIDE', 'SACCHARIDE',
-    // the following four are marked to be deprecated in the mmCIF dictionary
-    'D-SACCHARIDE 1,4 AND 1,4 LINKING', 'L-SACCHARIDE 1,4 AND 1,4 LINKING',
-    'D-SACCHARIDE 1,4 AND 1,6 LINKING', 'L-SACCHARIDE 1,4 AND 1,6 LINKING',
-]);
+export const SaccharideComponentTypeNames = SetUtils.unionMany(
+    new Set<ChemCompType>([
+        'd-saccharide, beta linking', 'l-saccharide, beta linking',
+        'd-saccharide, alpha linking', 'l-saccharide, alpha linking',
+        'l-saccharide', 'd-saccharide', 'saccharide',
+    ]),
+    // deprecated in the mmCIF dictionary, kept for backward compatibility
+    new Set([
+        'd-saccharide 1,4 and 1,4 linking', 'l-saccharide 1,4 and 1,4 linking',
+        'd-saccharide 1,4 and 1,6 linking', 'l-saccharide 1,4 and 1,6 linking'
+    ]),
+);
 
 /** Chemical component type names for other */
-export const OtherComponentTypeNames = new Set([
-    'NON-POLYMER', 'OTHER'
+export const OtherComponentTypeNames = new Set<ChemCompType>([
+    'non-polymer', 'other'
 ]);
 
 /** Chemical component type names for ion (extension to mmcif) */
-export const IonComponentTypeNames = new Set([
-    'ION'
+export const IonComponentTypeNames = new Set<ChemCompType>([
+    'ion'
 ]);
 
 /** Chemical component type names for lipid (extension to mmcif) */
-export const LipidComponentTypeNames = new Set([
-    'LIPID'
+export const LipidComponentTypeNames = new Set<ChemCompType>([
+    'lipid'
 ]);
 
 /** Common names for water molecules */
@@ -298,8 +304,7 @@ export const isPyrimidineBase = (compId: string) => PyrimidineBaseNames.has(comp
 export const PolymerNames = SetUtils.unionMany(AminoAcidNames, BaseNames);
 
 /** get the molecule type from component type and id */
-export function getMoleculeType(compType: string, compId: string): MoleculeType {
-    compType = compType.toUpperCase();
+export function getMoleculeType(compType: ChemCompType, compId: string): MoleculeType {
     compId = compId.toUpperCase();
     if (PeptideBaseNames.has(compId)) {
         return MoleculeType.PNA;
@@ -319,7 +324,7 @@ export function getMoleculeType(compType: string, compId: string): MoleculeType
         return MoleculeType.Lipid;
     } else if (OtherComponentTypeNames.has(compType)) {
         if (SaccharideCompIdMap.has(compId)) {
-            // trust our saccharide table more than given 'non-polymer' or 'other' component type
+            // trust our saccharide table more than given 'NON-POLYMER' or 'OTHER' component type
             return MoleculeType.Saccharide;
         } else if (AminoAcidNames.has(compId)) {
             return MoleculeType.Protein;
@@ -335,8 +340,7 @@ export function getMoleculeType(compType: string, compId: string): MoleculeType
     }
 }
 
-export function getPolymerType(compType: string, molType: MoleculeType): PolymerType {
-    compType = compType.toUpperCase();
+export function getPolymerType(compType: ChemCompType, molType: MoleculeType): PolymerType {
     if (molType === MoleculeType.Protein) {
         if (GammaProteinComponentTypeNames.has(compType)) {
             return PolymerType.GammaProtein;
@@ -358,14 +362,14 @@ export function getPolymerType(compType: string, molType: MoleculeType): Polymer
     }
 }
 
-export function getComponentType(compId: string): mmCIF_chemComp_schema['type']['T'] {
+export function getComponentType(compId: string): ChemCompType {
     compId = compId.toUpperCase();
     if (AminoAcidNames.has(compId)) {
         return 'peptide linking';
     } else if (RnaBaseNames.has(compId)) {
-        return 'RNA linking';
+        return 'rna linking';
     } else if (DnaBaseNames.has(compId)) {
-        return 'DNA linking';
+        return 'dna linking';
     } else if (SaccharideCompIdMap.has(compId)) {
         return 'saccharide';
     } else {
@@ -400,9 +404,8 @@ export function getEntityType(compId: string): mmCIF_Schema['entity']['type']['T
     }
 }
 
-export function getEntitySubtype(compId: string, compType: string): EntitySubtype {
+export function getEntitySubtype(compId: string, compType: ChemCompType): EntitySubtype {
     compId = compId.toUpperCase();
-    compType = compType.toUpperCase();
     if (LProteinComponentTypeNames.has(compType)) {
         return 'polypeptide(L)';
     } else if (DProteinComponentTypeNames.has(compType)) {

+ 1 - 1
src/mol-plugin-state/helpers/structure-selection-query.ts

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2019-2021 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * Copyright (c) 2019-2022 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
  * @author David Sehnal <david.sehnal@gmail.com>

+ 22 - 0
src/mol-plugin-ui/react18.ts

@@ -0,0 +1,22 @@
+/**
+ * Copyright (c) 2018-2022 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ *
+ * @author David Sehnal <david.sehnal@gmail.com>
+ * @author Alexander Rose <alexander.rose@weirdbyte.de>
+ */
+
+import { createElement } from 'react';
+import { createRoot } from 'react-dom/client';
+import { Plugin } from './plugin';
+import { PluginUIContext } from './context';
+import { DefaultPluginUISpec, PluginUISpec } from './spec';
+
+export async function createPluginUI(target: HTMLElement, spec?: PluginUISpec, options?: { onBeforeUIRender?: (ctx: PluginUIContext) => (Promise<void> | void) }) {
+    const ctx = new PluginUIContext(spec || DefaultPluginUISpec());
+    await ctx.init();
+    if (options?.onBeforeUIRender) {
+        await options.onBeforeUIRender(ctx);
+    }
+    createRoot(target).render(createElement(Plugin, { plugin: ctx }));
+    return ctx;
+}

+ 6 - 6
src/mol-plugin-ui/state/common.tsx

@@ -10,7 +10,7 @@ import { PurePluginUIComponent } from '../base';
 import { ParameterControls, ParamOnChange } from '../controls/parameters';
 import { PluginContext } from '../../mol-plugin/context';
 import { ParamDefinition as PD } from '../../mol-util/param-definition';
-import { Subject } from 'rxjs';
+import { BehaviorSubject, skip } from 'rxjs';
 import { Icon, RefreshSvg, CheckSvg, ArrowRightSvg, ArrowDropDownSvg, TuneSvg } from '../controls/icons';
 import { ExpandGroup, ToggleButton, Button, IconButton } from '../controls/common';
 
@@ -124,7 +124,7 @@ abstract class TransformControlBase<P, S extends TransformControlBase.ComponentS
     abstract getSourceAndTarget(): { a?: StateObject, b?: StateObject, bCell?: StateObjectCell };
     abstract state: S;
 
-    private busy: Subject<boolean> = new Subject();
+    private busy = new BehaviorSubject(false);
 
     private onEnter = () => {
         if (this.state.error) return;
@@ -167,11 +167,11 @@ abstract class TransformControlBase<P, S extends TransformControlBase.ComponentS
     };
 
     componentDidMount() {
-        this.subscribe(this.plugin.behaviors.state.isBusy, b => {
-            if (this.state.busy !== b) this.busy.next(b);
+        this.subscribe(this.plugin.behaviors.state.isBusy, busy => {
+            if (this.busy.value !== busy) this.busy.next(busy);
         });
-        this.subscribe(this.busy, busy => {
-            if (this.state.busy !== busy) this.setState({ busy });
+        this.subscribe(this.busy.pipe(skip(1)), busy => {
+            this.setState({ busy });
         });
     }
 

+ 45 - 31
src/mol-plugin-ui/task.tsx

@@ -4,32 +4,39 @@
  * @author David Sehnal <david.sehnal@gmail.com>
  */
 
-import { PluginUIComponent } from './base';
+import { PluginReactContext, PluginUIComponent } from './base';
 import { OrderedMap } from 'immutable';
 import { TaskManager } from '../mol-plugin/util/task-manager';
-import { filter } from 'rxjs/operators';
 import { Progress } from '../mol-task';
 import { IconButton } from './controls/common';
 import { CancelSvg } from './controls/icons';
+import { useContext, useEffect, useState } from 'react';
 
-export class BackgroundTaskProgress extends PluginUIComponent<{ }, { tracked: OrderedMap<number, TaskManager.ProgressEvent> }> {
-    componentDidMount() {
-        const hideOverlay = !!this.plugin.spec.components?.hideTaskOverlay;
-        this.subscribe(this.plugin.events.task.progress.pipe(filter(e => e.level === 'background' && (hideOverlay || !e.useOverlay))), e => {
-            this.setState({ tracked: this.state.tracked.set(e.id, e) });
+export function BackgroundTaskProgress() {
+    const plugin = useContext(PluginReactContext);
+    const [tracked, setTracked] = useState<OrderedMap<number, TaskManager.ProgressEvent>>(OrderedMap());
+
+    useEffect(() => {
+        const started = plugin.events.task.progress.subscribe(e => {
+            const hideOverlay = !!plugin.spec.components?.hideTaskOverlay;
+            if (e.level === 'background' && (hideOverlay || !e.useOverlay)) {
+                setTracked(tracked => tracked.set(e.id, e));
+            }
         });
-        this.subscribe(this.plugin.events.task.finished, ({ id }) => {
-            this.setState({ tracked: this.state.tracked.delete(id) });
+
+        const finished = plugin.events.task.finished.subscribe(({ id }) => {
+            setTracked(tracked => tracked.delete(id));
         });
-    }
 
-    state = { tracked: OrderedMap<number, TaskManager.ProgressEvent>() };
+        return () => {
+            started.unsubscribe();
+            finished.unsubscribe();
+        };
+    }, [plugin]);
 
-    render() {
-        return <div className='msp-background-tasks'>
-            {this.state.tracked.valueSeq().map(e => <ProgressEntry key={e!.id} event={e!} />)}
-        </div>;
-    }
+    return <div className='msp-background-tasks'>
+        {tracked.valueSeq().map(e => <ProgressEntry key={e!.id} event={e!} />)}
+    </div>;
 }
 
 class ProgressEntry extends PluginUIComponent<{ event: TaskManager.ProgressEvent }> {
@@ -65,23 +72,30 @@ function countSubtasks(progress: Progress.Node) {
     return sum;
 }
 
-export class OverlayTaskProgress extends PluginUIComponent<{ }, { tracked: OrderedMap<number, TaskManager.ProgressEvent> }> {
-    componentDidMount() {
-        this.subscribe(this.plugin.events.task.progress.pipe(filter(e => !!e.useOverlay)), e => {
-            this.setState({ tracked: this.state.tracked.set(e.id, e) });
+export function OverlayTaskProgress() {
+    const plugin = useContext(PluginReactContext);
+    const [tracked, setTracked] = useState<OrderedMap<number, TaskManager.ProgressEvent>>(OrderedMap());
+
+    useEffect(() => {
+        const started = plugin.events.task.progress.subscribe(e => {
+            if (!!e.useOverlay) {
+                setTracked(tracked => tracked.set(e.id, e));
+            }
         });
-        this.subscribe(this.plugin.events.task.finished, ({ id }) => {
-            this.setState({ tracked: this.state.tracked.delete(id) });
+
+        const finished = plugin.events.task.finished.subscribe(({ id }) => {
+            setTracked(tracked => tracked.delete(id));
         });
-    }
 
-    state = { tracked: OrderedMap<number, TaskManager.ProgressEvent>() };
+        return () => {
+            started.unsubscribe();
+            finished.unsubscribe();
+        };
+    }, [plugin]);
 
-    render() {
-        if (this.state.tracked.size === 0) return null;
+    if (tracked.size === 0) return null;
 
-        return <div className='msp-overlay-tasks'>
-            {this.state.tracked.valueSeq().map(e => <ProgressEntry key={e!.id} event={e!} />)}
-        </div>;
-    }
-}
+    return <div className='msp-overlay-tasks'>
+        {tracked.valueSeq().map(e => <ProgressEntry key={e!.id} event={e!} />)}
+    </div>;
+}

+ 0 - 1
src/mol-plugin/behavior/dynamic/volume-streaming/util.ts

@@ -80,7 +80,6 @@ export async function getContourLevelEmdb(plugin: PluginContext, taskCtx: Runtim
         }
     }
     const contourLevel = parseFloat(primaryContour.getElementsByTagName('level')[0].textContent!);
-
     return contourLevel;
 }
 

+ 3 - 2
src/mol-repr/util.ts

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2018-2021 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * Copyright (c) 2018-2022 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
  */
@@ -57,6 +57,7 @@ export interface QualityProps {
     doubleSided: boolean
     xrayShaded: boolean
     alpha: number
+    allowTransparentBackfaces: boolean
 }
 
 export const DefaultQualityThresholds = {
@@ -192,7 +193,7 @@ export function getQualityProps(props: Partial<QualityProps>, data?: any) {
     resolution = Math.max(resolution, volume / 500_000_000);
     resolution = Math.min(resolution, 20);
 
-    if ((props.alpha !== undefined && props.alpha < 1) || !!props.xrayShaded) {
+    if (!props.allowTransparentBackfaces && ((props.alpha !== undefined && props.alpha < 1) || !!props.xrayShaded)) {
         doubleSided = false;
     }