Browse Source

Merge branch 'master' of https://github.com/molstar/molstar-proto

David Sehnal 6 years ago
parent
commit
2a54ae5cbc

+ 90 - 129
package-lock.json

@@ -126,9 +126,9 @@
       "dev": true
     },
     "@types/jest": {
-      "version": "23.3.1",
-      "resolved": "https://registry.npmjs.org/@types/jest/-/jest-23.3.1.tgz",
-      "integrity": "sha512-/UMY+2GkOZ27Vrc51pqC5J8SPd39FKt7kkoGAtWJ8s4msj0b15KehDWIiJpWY3/7tLxBQLLzJhIBhnEsXdzpgw==",
+      "version": "23.3.2",
+      "resolved": "https://registry.npmjs.org/@types/jest/-/jest-23.3.2.tgz",
+      "integrity": "sha512-D1xlXHZpDonVX+VJ28XtcD5xlu8ex6Fc4cQNnrm2wJvlQnbec9RedhCrhQr6kRAE9XWHSec+JPuTmqJ9jC0qsA==",
       "dev": true
     },
     "@types/mime": {
@@ -746,11 +746,6 @@
       "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=",
       "dev": true
     },
-    "asap": {
-      "version": "2.0.6",
-      "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
-      "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY="
-    },
     "asn1": {
       "version": "0.2.3",
       "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz",
@@ -1228,9 +1223,9 @@
       }
     },
     "bluebird": {
-      "version": "3.5.1",
-      "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz",
-      "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==",
+      "version": "3.5.2",
+      "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.2.tgz",
+      "integrity": "sha512-dhHTWMI7kMx5whMQntl7Vr9C6BvV10lFXDAasnqnrMYhXVCzzk6IO9Fo2L75jXHT07WrOngL1WDXOp+yYS91Yg==",
       "dev": true
     },
     "bn.js": {
@@ -2135,24 +2130,40 @@
       }
     },
     "css": {
-      "version": "2.2.3",
-      "resolved": "https://registry.npmjs.org/css/-/css-2.2.3.tgz",
-      "integrity": "sha512-0W171WccAjQGGTKLhw4m2nnl0zPHUlTO/I8td4XzJgIB8Hg3ZZx71qT4G4eX8OVsSiaAKiUMy73E3nsbPlg2DQ==",
+      "version": "2.2.4",
+      "resolved": "https://registry.npmjs.org/css/-/css-2.2.4.tgz",
+      "integrity": "sha512-oUnjmWpy0niI3x/mPL8dVEI1l7MnG3+HHyRPHf+YFSbK+svOhXpmSOcDURUh2aOCgl2grzrOPt1nHLuCVFULLw==",
       "dev": true,
       "requires": {
-        "inherits": "^2.0.1",
-        "source-map": "^0.1.38",
-        "source-map-resolve": "^0.5.1",
+        "inherits": "^2.0.3",
+        "source-map": "^0.6.1",
+        "source-map-resolve": "^0.5.2",
         "urix": "^0.1.0"
       },
       "dependencies": {
+        "atob": {
+          "version": "2.1.2",
+          "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz",
+          "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==",
+          "dev": true
+        },
         "source-map": {
-          "version": "0.1.43",
-          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.43.tgz",
-          "integrity": "sha1-wkvBRspRfBRx9drL4lcbK3+eM0Y=",
+          "version": "0.6.1",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+          "dev": true
+        },
+        "source-map-resolve": {
+          "version": "0.5.2",
+          "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz",
+          "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==",
           "dev": true,
           "requires": {
-            "amdefine": ">=0.0.4"
+            "atob": "^2.1.1",
+            "decode-uri-component": "^0.2.0",
+            "resolve-url": "^0.2.1",
+            "source-map-url": "^0.4.0",
+            "urix": "^0.1.0"
           }
         }
       }
@@ -2570,14 +2581,6 @@
       "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
       "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k="
     },
-    "encoding": {
-      "version": "0.1.12",
-      "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz",
-      "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=",
-      "requires": {
-        "iconv-lite": "~0.4.13"
-      }
-    },
     "end-of-stream": {
       "version": "1.4.1",
       "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz",
@@ -2994,27 +2997,6 @@
         "bser": "^2.0.0"
       }
     },
-    "fbjs": {
-      "version": "0.8.17",
-      "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-0.8.17.tgz",
-      "integrity": "sha1-xNWY6taUkRJlPWWIsBpc3Nn5D90=",
-      "requires": {
-        "core-js": "^1.0.0",
-        "isomorphic-fetch": "^2.1.1",
-        "loose-envify": "^1.0.0",
-        "object-assign": "^4.1.0",
-        "promise": "^7.1.1",
-        "setimmediate": "^1.0.5",
-        "ua-parser-js": "^0.7.18"
-      },
-      "dependencies": {
-        "core-js": {
-          "version": "1.2.7",
-          "resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz",
-          "integrity": "sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY="
-        }
-      }
-    },
     "fecha": {
       "version": "2.3.3",
       "resolved": "https://registry.npmjs.org/fecha/-/fecha-2.3.3.tgz",
@@ -3326,14 +3308,12 @@
         "balanced-match": {
           "version": "1.0.0",
           "bundled": true,
-          "dev": true,
-          "optional": true
+          "dev": true
         },
         "brace-expansion": {
           "version": "1.1.11",
           "bundled": true,
           "dev": true,
-          "optional": true,
           "requires": {
             "balanced-match": "^1.0.0",
             "concat-map": "0.0.1"
@@ -3348,20 +3328,17 @@
         "code-point-at": {
           "version": "1.1.0",
           "bundled": true,
-          "dev": true,
-          "optional": true
+          "dev": true
         },
         "concat-map": {
           "version": "0.0.1",
           "bundled": true,
-          "dev": true,
-          "optional": true
+          "dev": true
         },
         "console-control-strings": {
           "version": "1.1.0",
           "bundled": true,
-          "dev": true,
-          "optional": true
+          "dev": true
         },
         "core-util-is": {
           "version": "1.0.2",
@@ -3478,8 +3455,7 @@
         "inherits": {
           "version": "2.0.3",
           "bundled": true,
-          "dev": true,
-          "optional": true
+          "dev": true
         },
         "ini": {
           "version": "1.3.5",
@@ -3491,7 +3467,6 @@
           "version": "1.0.0",
           "bundled": true,
           "dev": true,
-          "optional": true,
           "requires": {
             "number-is-nan": "^1.0.0"
           }
@@ -3506,7 +3481,6 @@
           "version": "3.0.4",
           "bundled": true,
           "dev": true,
-          "optional": true,
           "requires": {
             "brace-expansion": "^1.1.7"
           }
@@ -3514,14 +3488,12 @@
         "minimist": {
           "version": "0.0.8",
           "bundled": true,
-          "dev": true,
-          "optional": true
+          "dev": true
         },
         "minipass": {
           "version": "2.2.4",
           "bundled": true,
           "dev": true,
-          "optional": true,
           "requires": {
             "safe-buffer": "^5.1.1",
             "yallist": "^3.0.0"
@@ -3540,7 +3512,6 @@
           "version": "0.5.1",
           "bundled": true,
           "dev": true,
-          "optional": true,
           "requires": {
             "minimist": "0.0.8"
           }
@@ -3621,8 +3592,7 @@
         "number-is-nan": {
           "version": "1.0.1",
           "bundled": true,
-          "dev": true,
-          "optional": true
+          "dev": true
         },
         "object-assign": {
           "version": "4.1.1",
@@ -3634,7 +3604,6 @@
           "version": "1.4.0",
           "bundled": true,
           "dev": true,
-          "optional": true,
           "requires": {
             "wrappy": "1"
           }
@@ -3756,7 +3725,6 @@
           "version": "1.0.2",
           "bundled": true,
           "dev": true,
-          "optional": true,
           "requires": {
             "code-point-at": "^1.0.0",
             "is-fullwidth-code-point": "^1.0.0",
@@ -5136,7 +5104,8 @@
     "is-stream": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
-      "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ="
+      "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=",
+      "dev": true
     },
     "is-symbol": {
       "version": "1.0.1",
@@ -5201,26 +5170,6 @@
         "isarray": "1.0.0"
       }
     },
-    "isomorphic-fetch": {
-      "version": "2.2.1",
-      "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz",
-      "integrity": "sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk=",
-      "requires": {
-        "node-fetch": "^1.0.1",
-        "whatwg-fetch": ">=0.10.0"
-      },
-      "dependencies": {
-        "node-fetch": {
-          "version": "1.7.3",
-          "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz",
-          "integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==",
-          "requires": {
-            "encoding": "^0.1.11",
-            "is-stream": "^1.0.1"
-          }
-        }
-      }
-    },
     "isstream": {
       "version": "0.1.2",
       "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
@@ -7508,14 +7457,6 @@
       "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=",
       "dev": true
     },
-    "promise": {
-      "version": "7.3.1",
-      "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz",
-      "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==",
-      "requires": {
-        "asap": "~2.0.3"
-      }
-    },
     "promise-inflight": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz",
@@ -7776,25 +7717,25 @@
       "dev": true
     },
     "react": {
-      "version": "16.4.2",
-      "resolved": "https://registry.npmjs.org/react/-/react-16.4.2.tgz",
-      "integrity": "sha512-dMv7YrbxO4y2aqnvA7f/ik9ibeLSHQJTI6TrYAenPSaQ6OXfb+Oti+oJiy8WBxgRzlKatYqtCjphTgDSCEiWFg==",
+      "version": "16.5.0",
+      "resolved": "https://registry.npmjs.org/react/-/react-16.5.0.tgz",
+      "integrity": "sha512-nw/yB/L51kA9PsAy17T1JrzzGRk+BlFCJwFF7p+pwVxgqwPjYNeZEkkH7LXn9dmflolrYMXLWMTkQ77suKPTNQ==",
       "requires": {
-        "fbjs": "^0.8.16",
         "loose-envify": "^1.1.0",
         "object-assign": "^4.1.1",
-        "prop-types": "^15.6.0"
+        "prop-types": "^15.6.2",
+        "schedule": "^0.3.0"
       }
     },
     "react-dom": {
-      "version": "16.4.2",
-      "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.4.2.tgz",
-      "integrity": "sha512-Usl73nQqzvmJN+89r97zmeUpQDKDlh58eX6Hbs/ERdDHzeBzWy+ENk7fsGQ+5KxArV1iOFPT46/VneklK9zoWw==",
+      "version": "16.5.0",
+      "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.5.0.tgz",
+      "integrity": "sha512-qgsQdjFH54pQ1AGLCBKsqjPxib4Pnp+cOsNxGPlkHn5YnsSt43sBvHSif6FheY7NMMS6HPeSJOxXf6ECanjacA==",
       "requires": {
-        "fbjs": "^0.8.16",
         "loose-envify": "^1.1.0",
         "object-assign": "^4.1.1",
-        "prop-types": "^15.6.0"
+        "prop-types": "^15.6.2",
+        "schedule": "^0.3.0"
       }
     },
     "read-pkg": {
@@ -8071,9 +8012,9 @@
       "dev": true
     },
     "resolve-url-loader": {
-      "version": "2.3.0",
-      "resolved": "https://registry.npmjs.org/resolve-url-loader/-/resolve-url-loader-2.3.0.tgz",
-      "integrity": "sha512-RaEUWgF/B6aTg9VKaOv2o6dfm5f75/lGh8S+SQwoMcBm48WkA2nhLR+V7KEawkxXjU4lLB16IVeHCe7F69nyVw==",
+      "version": "2.3.1",
+      "resolved": "https://registry.npmjs.org/resolve-url-loader/-/resolve-url-loader-2.3.1.tgz",
+      "integrity": "sha512-tpt4A/tOT8jxRDa91RbBV4c22AGj+WllOxT8rYSYhT2XDdL33Nca9HudwVx4mvP9PLokz+wpCu44tWUGVMYYLA==",
       "dev": true,
       "requires": {
         "adjust-sourcemap-loader": "^1.1.0",
@@ -8189,9 +8130,9 @@
       }
     },
     "rxjs": {
-      "version": "6.3.1",
-      "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.3.1.tgz",
-      "integrity": "sha512-hRVfb1Mcf8rLXq1AZEjYpzBnQbO7Duveu1APXkWRTvqzhmkoQ40Pl2F9Btacx+gJCOqsMiugCGG4I2HPQgJRtA==",
+      "version": "6.3.2",
+      "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.3.2.tgz",
+      "integrity": "sha512-hV7criqbR0pe7EeL3O66UYVg92IR0XsA97+9y+BWTePK9SKmEI5Qd3Zj6uPnGkNzXsBywBQWTvujPl+1Kn9Zjw==",
       "requires": {
         "tslib": "^1.9.0"
       }
@@ -8664,6 +8605,14 @@
       "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==",
       "dev": true
     },
+    "schedule": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmjs.org/schedule/-/schedule-0.3.0.tgz",
+      "integrity": "sha512-20+1KVo517sR7Nt+bYBN8a+bEJDKLPEx7Ohtts1kX05E4/HY53YUNuhfkVNItmWAnBYHcpG9vsd2/CJxG+aPCQ==",
+      "requires": {
+        "object-assign": "^4.1.1"
+      }
+    },
     "schema-utils": {
       "version": "0.4.5",
       "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.4.5.tgz",
@@ -8800,7 +8749,8 @@
     "setimmediate": {
       "version": "1.0.5",
       "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
-      "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU="
+      "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=",
+      "dev": true
     },
     "setprototypeof": {
       "version": "1.1.0",
@@ -10124,11 +10074,6 @@
       "integrity": "sha512-kk80vLW9iGtjMnIv11qyxLqZm20UklzuR2tL0QAnDIygIUIemcZMxlMWudl9OOt76H3ntVzcTiddQ1/pAAJMYg==",
       "dev": true
     },
-    "ua-parser-js": {
-      "version": "0.7.18",
-      "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.18.tgz",
-      "integrity": "sha512-LtzwHlVHwFGTptfNSgezHp7WUlwiqb0gA9AALRbKaERfxwJoiX0A73QbTToxteIAuIaFshhgIZfqK8s7clqgnA=="
-    },
     "uglify-js": {
       "version": "3.4.9",
       "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.4.9.tgz",
@@ -10866,9 +10811,9 @@
       "dev": true
     },
     "webpack": {
-      "version": "4.17.1",
-      "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.17.1.tgz",
-      "integrity": "sha512-vdPYogljzWPhFKDj3Gcp01Vqgu7K3IQlybc3XIdKSQHelK1C3eIQuysEUR7MxKJmdandZlQB/9BG2Jb1leJHaw==",
+      "version": "4.17.2",
+      "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.17.2.tgz",
+      "integrity": "sha512-hCK8FPco2Paz9FVMlo3ZdVd7Jsr7qxoiEwhd7f4dMaWBLZtc7E+/9QNee4CYHlVSvpmspWBnhFpx4MiWSl3nNg==",
       "dev": true,
       "requires": {
         "@webassemblyjs/ast": "1.5.13",
@@ -10895,13 +10840,13 @@
         "tapable": "^1.0.0",
         "uglifyjs-webpack-plugin": "^1.2.4",
         "watchpack": "^1.5.0",
-        "webpack-sources": "^1.0.1"
+        "webpack-sources": "^1.2.0"
       },
       "dependencies": {
         "acorn": {
-          "version": "5.7.1",
-          "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.1.tgz",
-          "integrity": "sha512-d+nbxBUGKg7Arpsvbnlq61mc12ek3EY8EQldM3GPAhWJ1UVxC6TDGbIvUMNU6obBX3i1+ptCIzV4vq0gFPEGVQ==",
+          "version": "5.7.2",
+          "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.2.tgz",
+          "integrity": "sha512-cJrKCNcr2kv8dlDnbw+JPUGjHZzo4myaxOLmpOX8a+rgX94YeTcTMv/LFJUSByRpc+i4GgVnnhLxvMu/2Y+rqw==",
           "dev": true
         },
         "ajv": {
@@ -11202,6 +11147,12 @@
             "to-regex": "^3.0.2"
           }
         },
+        "source-map": {
+          "version": "0.6.1",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+          "dev": true
+        },
         "uri-js": {
           "version": "4.2.2",
           "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz",
@@ -11210,6 +11161,16 @@
           "requires": {
             "punycode": "^2.1.0"
           }
+        },
+        "webpack-sources": {
+          "version": "1.2.0",
+          "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.2.0.tgz",
+          "integrity": "sha512-9BZwxR85dNsjWz3blyxdOhTgtnQvv3OEs5xofI0wPYTwu5kaWxS08UuD1oI7WLBLpRO+ylf0ofnXLXWmGb2WMw==",
+          "dev": true,
+          "requires": {
+            "source-list-map": "^2.0.0",
+            "source-map": "~0.6.1"
+          }
         }
       }
     },

+ 6 - 6
package.json

@@ -75,7 +75,7 @@
     "@types/benchmark": "^1.0.31",
     "@types/compression": "0.0.36",
     "@types/express": "^4.16.0",
-    "@types/jest": "^23.3.1",
+    "@types/jest": "^23.3.2",
     "@types/node": "^10.9.4",
     "@types/node-fetch": "^2.1.2",
     "@types/react": "^16.4.13",
@@ -95,7 +95,7 @@
     "mini-css-extract-plugin": "^0.4.2",
     "node-sass": "^4.9.3",
     "raw-loader": "^0.5.1",
-    "resolve-url-loader": "^2.3.0",
+    "resolve-url-loader": "^2.3.1",
     "sass-loader": "^7.1.0",
     "style-loader": "^0.23.0",
     "ts-jest": "^23.1.4",
@@ -103,7 +103,7 @@
     "typescript": "^3.0.3",
     "uglify-js": "^3.4.9",
     "util.promisify": "^1.0.0",
-    "webpack": "^4.17.1",
+    "webpack": "^4.17.2",
     "webpack-cli": "^3.1.0"
   },
   "dependencies": {
@@ -114,8 +114,8 @@
     "graphql-request": "^1.8.2",
     "immutable": "^4.0.0-rc.9",
     "node-fetch": "^2.2.0",
-    "react": "^16.4.2",
-    "react-dom": "^16.4.2",
-    "rxjs": "^6.3.1"
+    "react": "^16.5.0",
+    "react-dom": "^16.5.0",
+    "rxjs": "^6.3.2"
   }
 }

+ 15 - 11
src/apps/canvas/component/app.tsx

@@ -9,17 +9,7 @@ import { StructureView } from '../structure-view';
 import { App } from '../app';
 import { Viewport } from './viewport';
 import { StructureViewComponent } from './structure-view';
-
-// export function FileInput (props: {
-//     accept: string
-//     onChange: (v: FileList | null) => void,
-// }) {
-//     return <input
-//         accept={props.accept || '*.*'}
-//         type='file'
-//         onChange={e => props.onChange.call(null, e.target.files)}
-//     />
-// }
+import { Examples } from '../examples';
 
 export interface AppProps {
     app: App
@@ -75,6 +65,20 @@ export class AppComponent extends React.Component<AppProps, AppState> {
                         }}
                     />
                 </div>
+                <div>
+                    <span>Load example </span>
+                    <select
+                        style={{width: '200px'}}
+                        onChange={e => {
+                            this.props.app.loadPdbId(e.target.value)
+                        }}
+                    >
+                        <option value=''></option>
+                        {Examples.map(({pdbId, description}, i) => {
+                            return <option key={i} value={pdbId}>{`${pdbId} - ${description}`}</option>
+                        })}
+                    </select>
+                </div>
                 <hr/>
                 <div style={{marginBottom: '10px'}}>
                     {structureView ? <StructureViewComponent structureView={structureView} /> : ''}

+ 17 - 1
src/apps/canvas/component/structure-representation.tsx

@@ -19,6 +19,7 @@ export interface StructureRepresentationComponentProps {
 export interface StructureRepresentationComponentState {
     label: string
     visible: boolean
+    alpha: number
     quality: VisualQuality
     colorTheme: ColorThemeProps
 }
@@ -27,6 +28,7 @@ export class StructureRepresentationComponent extends React.Component<StructureR
     state = {
         label: this.props.representation.label,
         visible: this.props.representation.props.visible,
+        alpha: this.props.representation.props.alpha,
         quality: this.props.representation.props.quality,
         colorTheme: this.props.representation.props.colorTheme,
     }
@@ -38,6 +40,7 @@ export class StructureRepresentationComponent extends React.Component<StructureR
             ...this.state,
             label: repr.label,
             visible: repr.props.visible,
+            alpha: repr.props.alpha,
             quality: repr.props.quality,
             colorTheme: repr.props.colorTheme,
         })
@@ -49,6 +52,7 @@ export class StructureRepresentationComponent extends React.Component<StructureR
 
         if (state.visible !== undefined) props.visible = state.visible
         if (state.quality !== undefined) props.quality = state.quality
+        if (state.alpha !== undefined) props.alpha = state.alpha
         if (state.colorTheme !== undefined) props.colorTheme = state.colorTheme
 
         await repr.createOrUpdate(props).run()
@@ -60,13 +64,14 @@ export class StructureRepresentationComponent extends React.Component<StructureR
             ...this.state,
             visible: repr.props.visible,
             quality: repr.props.quality,
+            alpha: repr.props.alpha,
             colorTheme: repr.props.colorTheme,
         }
         this.setState(newState)
     }
 
     render() {
-        const { label, visible, quality, colorTheme } = this.state
+        const { label, visible, quality, alpha, colorTheme } = this.state
 
         const ct = ColorTheme(colorTheme)
 
@@ -91,6 +96,17 @@ export class StructureRepresentationComponent extends React.Component<StructureR
                         {VisualQualityNames.map(name => <option key={name} value={name}>{name}</option>)}
                     </select>
                 </div>
+                <div>
+                    <span>Opacity </span>
+                    <input type='range'
+                        defaultValue={alpha.toString()}
+                        min='0'
+                        max='1'
+                        step='0.05'
+                        onInput={(e) => this.update({ alpha: parseFloat(e.currentTarget.value) })}
+                    >
+                    </input>
+                </div>
                 <div>
                     <span>Color Theme </span>
                     <select value={colorTheme.name} onChange={(e) => this.update({ colorTheme: { name: e.target.value as ColorThemeName } }) }>

+ 169 - 0
src/apps/canvas/examples.ts

@@ -0,0 +1,169 @@
+
+
+export interface Example {
+    pdbId: string
+    description: string
+}
+
+export const Examples: Example[] = [
+    {
+        pdbId: '1jj2',
+        description: 'ribosome'
+    },
+    {
+        pdbId: '1grm',
+        description: 'helix-like sheets'
+    },
+    {
+        pdbId: '4umt',
+        description: 'ligand has bond with order 3'
+    },
+    {
+        pdbId: '1crn',
+        description: 'small'
+    },
+    {
+        pdbId: '1hrv',
+        description: 'viral assembly'
+    },
+    {
+        pdbId: '1rb8',
+        description: 'virus'
+    },
+    {
+        pdbId: '1blu',
+        description: 'metal coordination'
+    },
+    {
+        pdbId: '3pqr',
+        description: 'inter unit bonds, two polymer chains, ligands, water, carbohydrates linked to protein'
+    },
+    {
+        pdbId: '4v5a',
+        description: 'ribosome'
+    },
+    {
+        pdbId: '3j3q',
+        description: '...'
+    },
+    {
+        pdbId: '2np2',
+        description: 'dna'
+    },
+    {
+        pdbId: '1d66',
+        description: 'dna'
+    },
+    {
+        pdbId: '9dna',
+        description: 'A form dna'
+    },
+    {
+        pdbId: '1bna',
+        description: 'B form dna'
+    },
+    {
+        pdbId: '199d',
+        description: 'C form dna'
+    },
+    {
+        pdbId: '4lb6',
+        description: 'Z form dna'
+    },
+    {
+        pdbId: '1egk',
+        description: '4-way dna-rna junction'
+    },
+    {
+        pdbId: '1y26',
+        description: 'rna'
+    },
+    {
+        pdbId: '1xv6',
+        description: 'rna, modified nucleotides'
+    },
+    {
+        pdbId: '3bbm',
+        description: 'rna with linker'
+    },
+    {
+        pdbId: '1euq',
+        description: 't-rna'
+    },
+    {
+        pdbId: '2e2i',
+        description: 'rna, dna, protein'
+    },
+    {
+        pdbId: '1gfl',
+        description: 'GFP, flourophore has carbonyl oxygen removed'
+    },
+    {
+        pdbId: '1sfi',
+        description: 'contains cyclic peptid'
+    },
+    {
+        pdbId: '3sn6',
+        description: 'discontinuous chains'
+    },
+    {
+        pdbId: '2zex',
+        description: 'contains carbohydrate polymer'
+    },
+    {
+        pdbId: '3sgj',
+        description: 'contains carbohydrate polymer'
+    },
+    {
+        pdbId: '3ina',
+        description: 'contains GlcN and IdoA'
+    },
+    {
+        pdbId: '1umz',
+        description: 'contains Xyl (Xyloglucan)'
+    },
+    {
+        pdbId: '1mfb',
+        description: 'contains Abe'
+    },
+    {
+        pdbId: '2gdu',
+        description: 'contains sucrose'
+    },
+    {
+        pdbId: '2fnc',
+        description: 'contains maltotriose'
+    },
+    {
+        pdbId: '4zs9',
+        description: 'contains raffinose'
+    },
+    {
+        pdbId: '2yft',
+        description: 'contains kestose'
+    },
+    {
+        pdbId: '2b5t',
+        description: 'contains large carbohydrate polymer'
+    },
+    {
+        pdbId: '1b5f',
+        description: 'contains carbohydrate with alternate locations'
+    },
+    {
+        pdbId: '5u0q',
+        description: 'mixed dna/rna in same polymer'
+    },
+    {
+        pdbId: '1xj9',
+        description: 'PNA (peptide nucleic acid)'
+    },
+    {
+        pdbId: '5eme',
+        description: 'PNA (peptide nucleic acid) and RNA'
+    },
+    {
+        pdbId: '2X3T',
+        description: 'temp'
+    },
+]

+ 3 - 0
src/apps/canvas/structure-view.ts

@@ -24,6 +24,7 @@ import { StructureRepresentation } from 'mol-geo/representation/structure';
 import { BehaviorSubject } from 'rxjs';
 import { SpacefillRepresentation } from 'mol-geo/representation/structure/representation/spacefill';
 import { DistanceRestraintRepresentation } from 'mol-geo/representation/structure/representation/distance-restraint';
+import { SurfaceRepresentation } from 'mol-geo/representation/structure/representation/surface';
 
 export interface StructureView {
     readonly viewer: Viewer
@@ -66,6 +67,7 @@ export async function StructureView(viewer: Viewer, models: ReadonlyArray<Model>
     const active: { [k: string]: boolean } = {
         cartoon: true,
         point: false,
+        surface: true,
         ballAndStick: false,
         carbohydrate: false,
         spacefill: false,
@@ -76,6 +78,7 @@ export async function StructureView(viewer: Viewer, models: ReadonlyArray<Model>
 
     const structureRepresentations: { [k: string]: StructureRepresentation<any> } = {
         cartoon: CartoonRepresentation(),
+        surface: SurfaceRepresentation(),
         point: PointRepresentation(),
         ballAndStick: BallAndStickRepresentation(),
         carbohydrate: CarbohydrateRepresentation(),

+ 47 - 0
src/mol-geo/representation/structure/representation/surface.ts

@@ -0,0 +1,47 @@
+/**
+ * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ *
+ * @author Alexander Rose <alexander.rose@weirdbyte.de>
+ */
+
+import { UnitsRepresentation } from '..';
+import { GaussianSurfaceVisual, DefaultGaussianSurfaceProps } from '../visual/gaussian-surface-mesh';
+import { StructureRepresentation } from '../units-representation';
+import { Structure } from 'mol-model/structure';
+import { MarkerAction } from '../../../util/marker-data';
+import { Loci } from 'mol-model/loci';
+import { PickingId } from '../../../util/picking';
+
+export const DefaultSurfaceProps = {
+    ...DefaultGaussianSurfaceProps,
+}
+export type SurfaceProps = typeof DefaultSurfaceProps
+
+export type SurfaceRepresentation = StructureRepresentation<SurfaceProps>
+
+export function SurfaceRepresentation(): SurfaceRepresentation {
+    let currentProps: SurfaceProps
+    const gaussianRepr = UnitsRepresentation('Gaussian surface', GaussianSurfaceVisual)
+    return {
+        label: 'Surface',
+        get renderObjects() {
+            return [ ...gaussianRepr.renderObjects ]
+        },
+        get props() {
+            return { ...gaussianRepr.props }
+        },
+        createOrUpdate: (props: Partial<SurfaceProps> = {}, structure?: Structure) => {
+            currentProps = Object.assign({}, DefaultSurfaceProps, currentProps, props)
+            return gaussianRepr.createOrUpdate(currentProps, structure)
+        },
+        getLoci: (pickingId: PickingId) => {
+            return gaussianRepr.getLoci(pickingId)
+        },
+        mark: (loci: Loci, action: MarkerAction) => {
+            return gaussianRepr.mark(loci, action)
+        },
+        destroy() {
+            gaussianRepr.destroy()
+        }
+    }
+}

+ 3 - 3
src/mol-geo/representation/structure/units-visual.ts

@@ -32,7 +32,7 @@ export type UnitsMeshProps = typeof DefaultUnitsMeshProps
 
 export interface UnitsMeshVisualBuilder<P extends UnitsMeshProps> {
     defaultProps: P
-    createMesh(ctx: RuntimeContext, unit: Unit, props: P, mesh?: Mesh): Promise<Mesh>
+    createMesh(ctx: RuntimeContext, unit: Unit, structure: Structure, props: P, mesh?: Mesh): Promise<Mesh>
     createLocationIterator(group: Unit.SymmetryGroup): LocationIterator
     getLoci(pickingId: PickingId, group: Unit.SymmetryGroup, id: number): Loci
     mark(loci: Loci, group: Unit.SymmetryGroup, apply: (interval: Interval) => boolean): boolean
@@ -59,7 +59,7 @@ export function UnitsMeshVisual<P extends UnitsMeshProps>(builder: UnitsMeshVisu
         const unit = group.units[0]
         currentConformationId = Unit.conformationId(unit)
         mesh = currentProps.unitKinds.includes(unit.kind)
-            ? await createMesh(ctx, unit, currentProps, mesh)
+            ? await createMesh(ctx, unit, currentStructure, currentProps, mesh)
             : Mesh.createEmpty(mesh)
 
         // TODO create empty location iterator when not in unitKinds
@@ -102,7 +102,7 @@ export function UnitsMeshVisual<P extends UnitsMeshProps>(builder: UnitsMeshVisu
 
         if (updateState.createMesh) {
             mesh = newProps.unitKinds.includes(unit.kind)
-                ? await createMesh(ctx, unit, newProps, mesh)
+                ? await createMesh(ctx, unit, currentStructure, newProps, mesh)
                 : Mesh.createEmpty(mesh)
             ValueCell.update(renderObject.values.drawCount, mesh.triangleCount * 3)
             updateState.updateColor = true

+ 2 - 1
src/mol-geo/representation/structure/visual/element-point.ts

@@ -23,7 +23,7 @@ import { SizeThemeProps } from 'mol-view/theme/size';
 import { LocationIterator } from '../../../util/location-iterator';
 import { createTransforms } from '../../../util/transform-data';
 import { StructureGroup } from '../units-visual';
-import { updateRenderableState } from '../../util';
+import { updateRenderableState, updateBaseValues } from '../../util';
 
 export const DefaultElementPointProps = {
     ...DefaultStructureProps,
@@ -130,6 +130,7 @@ export function ElementPointVisual(): UnitsVisual<ElementPointProps> {
                     await createSizes(ctx, locationIt, newProps.sizeTheme, renderObject.values)
                 }
 
+                updateBaseValues(renderObject.values, newProps)
                 updateRenderableState(renderObject.state, newProps)
 
                 currentProps = newProps

+ 153 - 0
src/mol-geo/representation/structure/visual/gaussian-surface-mesh.ts

@@ -0,0 +1,153 @@
+/**
+ * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ *
+ * @author Alexander Rose <alexander.rose@weirdbyte.de>
+ */
+
+import { Unit, Structure } from 'mol-model/structure';
+import { UnitsVisual, MeshUpdateState } from '..';
+import { RuntimeContext } from 'mol-task'
+import { Mesh } from '../../../mesh/mesh';
+import { UnitsMeshVisual, DefaultUnitsMeshProps } from '../units-visual';
+import { StructureElementIterator, getElementLoci, markElement } from './util/element';
+import { computeMarchingCubes } from '../../../util/marching-cubes/algorithm';
+import { Tensor, Vec3, Mat4 } from 'mol-math/linear-algebra';
+import { Box3D } from 'mol-math/geometry';
+import { ValueCell } from 'mol-util';
+import { smoothstep } from 'mol-math/interpolate';
+
+export interface GaussianSurfaceMeshProps {
+    
+}
+
+function getDelta(box: Box3D) {
+    const extent = Vec3.sub(Vec3.zero(), box.max, box.min)
+
+    const n = Math.pow(128, 3)
+    const f = (extent[0] * extent[1] * extent[2]) / n
+    const s = Math.pow(f, 1 / 3)
+    const size = Vec3.zero()
+    // Vec3.scale(size, extent, s)
+    Vec3.ceil(size, Vec3.scale(size, extent, s))
+    const delta = Vec3.div(Vec3.zero(), extent, size)
+    return delta
+}
+
+async function createGaussianSurfaceMesh(ctx: RuntimeContext, unit: Unit, structure: Structure, props: GaussianSurfaceMeshProps, mesh?: Mesh): Promise<Mesh> {
+
+    const { elements } = unit;
+    const elementCount = elements.length;
+
+    const r = 2.5;
+
+    const v = Vec3.zero()
+    const p = Vec3.zero()
+    const pos = unit.conformation.invariantPosition
+    const box = unit.lookup3d.boundary.box
+    const expandedBox = Box3D.expand(Box3D.empty(), box, Vec3.create(r*3, r*3, r*3));
+    const extent = Vec3.sub(Vec3.zero(), expandedBox.max, expandedBox.min)
+    const min = expandedBox.min
+
+    // const n = Math.pow(128, 3)
+    // const f = (extent[0] * extent[1] * extent[2]) / n
+    // const s = Math.pow(f, 1 / 3)
+    // const size = Vec3.zero()
+    // // Vec3.scale(size, extent, s)
+    // Vec3.ceil(size, Vec3.scale(size, extent, s))
+    // const delta = Vec3.div(Vec3.zero(), extent, size)
+
+    // console.log('extent', extent)
+    // console.log('n', n)
+    // console.log('f', f)
+    // console.log('s', s)
+    // console.log('size', size)
+    // console.log('delta', delta)
+    const delta = getDelta(Box3D.expand(Box3D.empty(), structure.boundary.box, Vec3.create(r*3, r*3, r*3)))
+    const dim = Vec3.zero()
+    Vec3.ceil(dim, Vec3.mul(dim, extent, delta))
+    // console.log('dim', dim, dim[0] * dim[1] * dim[2])
+
+    const space = Tensor.Space(dim, [0, 1, 2], Float32Array)
+    const data = space.create()
+    const field = Tensor.create(space, data)
+
+    for (let i = 0; i < elementCount; i++) {
+        pos(elements[i], v)
+
+        Vec3.mul(v, Vec3.sub(v, v, min), delta)
+
+        const size = r
+        const radius = size * delta[0]
+
+        const minX = Math.floor(v[0] - radius)
+        const minY = Math.floor(v[1] - radius)
+        const minZ = Math.floor(v[2] - radius)
+        const maxX = Math.floor(v[0] + radius)
+        const maxY = Math.floor(v[1] + radius)
+        const maxZ = Math.floor(v[2] + radius)
+
+        for (let x = minX; x <= maxX; ++x) {
+            for (let y = minY; y <= maxY; ++y) {
+                for (let z = minZ; z <= maxZ; ++z) {
+                    const dist = Vec3.distance(Vec3.set(p, x, y, z), v)
+                    if (dist <= radius) {
+                        const density = 1.0 - smoothstep(0.0, radius * 1.0, dist)
+                        space.set(data, x, y, z, space.get(data, x, y, z) + density)
+                    }
+                } 
+            }   
+        }
+
+        if (i % 10000 === 0 && ctx.shouldUpdate) {
+            await ctx.update({ message: 'Gaussian surface', current: i, max: elementCount });
+        }
+    }
+
+    // console.log('data', data)
+
+    const surface = await computeMarchingCubes({
+        isoLevel: 0.1,
+        scalarField: field,
+        oldSurface: mesh
+        
+    }).runAsChild(ctx);
+
+    const t = Mat4.identity()
+    Mat4.fromUniformScaling(t, 1 / delta[0])
+    Mat4.setTranslation(t, expandedBox.min)
+
+    ValueCell.update(surface.groupBuffer, new Float32Array(surface.vertexCount)) 
+    Mesh.transformImmediate(surface, t)
+    await Mesh.computeNormals(surface).runAsChild(ctx)
+
+    // console.log('surface', surface)
+
+    // const transform = VolumeData.getGridToCartesianTransform(volume);
+    // ctx.update({ message: 'Transforming mesh...' });
+    // Mesh.transformImmediate(surface, transform);
+
+    return surface;
+}
+
+export const DefaultGaussianSurfaceProps = {
+    ...DefaultUnitsMeshProps,
+    linearSegments: 8,
+    radialSegments: 12,
+    aspectRatio: 5,
+    arrowFactor: 1.5,
+
+    flipSided: true,
+    // flatShaded: true,
+}
+export type GaussianSurfaceProps = typeof DefaultGaussianSurfaceProps
+
+export function GaussianSurfaceVisual(): UnitsVisual<GaussianSurfaceProps> {
+    return UnitsMeshVisual<GaussianSurfaceProps>({
+        defaultProps: DefaultGaussianSurfaceProps,
+        createMesh: createGaussianSurfaceMesh,
+        createLocationIterator: StructureElementIterator.fromGroup,
+        getLoci: getElementLoci,
+        mark: markElement,
+        setUpdateState: (state: MeshUpdateState, newProps: GaussianSurfaceProps, currentProps: GaussianSurfaceProps) => {}
+    })
+}

+ 2 - 2
src/mol-geo/representation/structure/visual/intra-unit-link-cylinder.ts

@@ -5,7 +5,7 @@
  * @author David Sehnal <david.sehnal@gmail.com>
  */
 
-import { Unit, Link, StructureElement } from 'mol-model/structure';
+import { Unit, Link, StructureElement, Structure } from 'mol-model/structure';
 import { UnitsVisual, MeshUpdateState } from '..';
 import { RuntimeContext } from 'mol-task'
 import { DefaultLinkCylinderProps, LinkCylinderProps, createLinkCylinderMesh, LinkIterator } from './util/link';
@@ -18,7 +18,7 @@ import { Interval } from 'mol-data/int';
 import { SizeThemeProps, SizeTheme } from 'mol-view/theme/size';
 import { BitFlags } from 'mol-util';
 
-async function createIntraUnitLinkCylinderMesh(ctx: RuntimeContext, unit: Unit, props: LinkCylinderProps, mesh?: Mesh) {
+async function createIntraUnitLinkCylinderMesh(ctx: RuntimeContext, unit: Unit, structure: Structure, props: LinkCylinderProps, mesh?: Mesh) {
     if (!Unit.isAtomic(unit)) return Mesh.createEmpty(mesh)
 
     const sizeTheme = SizeTheme(props.sizeTheme)

+ 2 - 2
src/mol-geo/representation/structure/visual/nucleotide-block-mesh.ts

@@ -4,7 +4,7 @@
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
  */
 
-import { Unit } from 'mol-model/structure';
+import { Unit, Structure } from 'mol-model/structure';
 import { UnitsVisual } from '..';
 import { RuntimeContext } from 'mol-task'
 import { Mesh } from '../../../mesh/mesh';
@@ -33,7 +33,7 @@ const sVec = Vec3.zero()
 const box = Box()
 
 // TODO define props, should be scalable
-async function createNucleotideBlockMesh(ctx: RuntimeContext, unit: Unit, props: {}, mesh?: Mesh) {
+async function createNucleotideBlockMesh(ctx: RuntimeContext, unit: Unit, structure: Structure, props: {}, mesh?: Mesh) {
     if (!Unit.isAtomic(unit)) return Mesh.createEmpty(mesh)
 
     // TODO better vertex count estimate

+ 2 - 2
src/mol-geo/representation/structure/visual/polymer-backbone-cylinder.ts

@@ -4,7 +4,7 @@
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
  */
 
-import { Unit } from 'mol-model/structure';
+import { Unit, Structure } from 'mol-model/structure';
 import { UnitsVisual, MeshUpdateState } from '..';
 import { RuntimeContext } from 'mol-task'
 import { Mesh } from '../../../mesh/mesh';
@@ -23,7 +23,7 @@ export interface PolymerBackboneCylinderProps {
     radialSegments: number
 }
 
-async function createPolymerBackboneCylinderMesh(ctx: RuntimeContext, unit: Unit, props: PolymerBackboneCylinderProps, mesh?: Mesh) {
+async function createPolymerBackboneCylinderMesh(ctx: RuntimeContext, unit: Unit, structure: Structure, props: PolymerBackboneCylinderProps, mesh?: Mesh) {
     const polymerElementCount = unit.polymerElements.length
     if (!polymerElementCount) return Mesh.createEmpty(mesh)
 

+ 2 - 2
src/mol-geo/representation/structure/visual/polymer-direction-wedge.ts

@@ -4,7 +4,7 @@
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
  */
 
-import { Unit } from 'mol-model/structure';
+import { Unit, Structure } from 'mol-model/structure';
 import { UnitsVisual } from '..';
 import { RuntimeContext } from 'mol-task'
 import { Mesh } from '../../../mesh/mesh';
@@ -32,7 +32,7 @@ export interface PolymerDirectionWedgeProps {
     sizeTheme: SizeThemeProps
 }
 
-async function createPolymerDirectionWedgeMesh(ctx: RuntimeContext, unit: Unit, props: PolymerDirectionWedgeProps, mesh?: Mesh) {
+async function createPolymerDirectionWedgeMesh(ctx: RuntimeContext, unit: Unit, structure: Structure, props: PolymerDirectionWedgeProps, mesh?: Mesh) {
     const polymerElementCount = unit.polymerElements.length
     if (!polymerElementCount) return Mesh.createEmpty(mesh)
 

+ 2 - 2
src/mol-geo/representation/structure/visual/polymer-gap-cylinder.ts

@@ -4,7 +4,7 @@
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
  */
 
-import { Unit } from 'mol-model/structure';
+import { Unit, Structure } from 'mol-model/structure';
 import { UnitsVisual, MeshUpdateState } from '..';
 import { RuntimeContext } from 'mol-task'
 import { Mesh } from '../../../mesh/mesh';
@@ -24,7 +24,7 @@ export interface PolymerGapCylinderProps {
     radialSegments: number
 }
 
-async function createPolymerGapCylinderMesh(ctx: RuntimeContext, unit: Unit, props: PolymerGapCylinderProps, mesh?: Mesh) {
+async function createPolymerGapCylinderMesh(ctx: RuntimeContext, unit: Unit, structure: Structure, props: PolymerGapCylinderProps, mesh?: Mesh) {
     const polymerGapCount = unit.gapElements.length
     if (!polymerGapCount) return Mesh.createEmpty(mesh)
 

+ 2 - 2
src/mol-geo/representation/structure/visual/polymer-trace-mesh.ts

@@ -4,7 +4,7 @@
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
  */
 
-import { Unit } from 'mol-model/structure';
+import { Unit, Structure } from 'mol-model/structure';
 import { UnitsVisual, MeshUpdateState } from '..';
 import { RuntimeContext } from 'mol-task'
 import { Mesh } from '../../../mesh/mesh';
@@ -26,7 +26,7 @@ export interface PolymerTraceMeshProps {
 
 // TODO handle polymer ends properly
 
-async function createPolymerTraceMesh(ctx: RuntimeContext, unit: Unit, props: PolymerTraceMeshProps, mesh?: Mesh) {
+async function createPolymerTraceMesh(ctx: RuntimeContext, unit: Unit, structure: Structure, props: PolymerTraceMeshProps, mesh?: Mesh) {
     const polymerElementCount = unit.polymerElements.length
     if (!polymerElementCount) return Mesh.createEmpty(mesh)
 

+ 2 - 2
src/mol-geo/representation/structure/visual/util/element.ts

@@ -5,7 +5,7 @@
  */
 
 import { Vec3 } from 'mol-math/linear-algebra';
-import { Unit, StructureElement } from 'mol-model/structure';
+import { Unit, StructureElement, Structure } from 'mol-model/structure';
 import { RuntimeContext } from 'mol-task';
 import { sphereVertexCount } from '../../../../primitive/sphere';
 import { Mesh } from '../../../../mesh/mesh';
@@ -22,7 +22,7 @@ export interface ElementSphereMeshProps {
     detail: number,
 }
 
-export async function createElementSphereMesh(ctx: RuntimeContext, unit: Unit, props: ElementSphereMeshProps, mesh?: Mesh) {
+export async function createElementSphereMesh(ctx: RuntimeContext, unit: Unit, structure: Structure, props: ElementSphereMeshProps, mesh?: Mesh) {
     const { detail } = props
 
     const { elements } = unit;

+ 3 - 1
src/mol-gl/shader/chunks/assign-material-color.glsl

@@ -1,5 +1,7 @@
 #if defined(dColorType_uniform)
     vec4 material = vec4(uColor, uAlpha);
-#elif defined(dColorType_attribute) || defined(dColorType_instance) || defined(dColorType_group) || defined(dColorType_groupInstance) || defined(dColorType_objectPicking) || defined(dColorType_instancePicking) || defined(dColorType_groupPicking)
+#elif defined(dColorType_attribute) || defined(dColorType_instance) || defined(dColorType_group) || defined(dColorType_groupInstance)
+    vec4 material = vec4(vColor.rgb, uAlpha);
+#elif defined(dColorType_objectPicking) || defined(dColorType_instancePicking) || defined(dColorType_groupPicking)
     vec4 material = vColor;
 #endif

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

@@ -182,7 +182,7 @@ export const MonosaccharidesColorTable: [string, Color][] = [
     ['Alt-family', SaccharideColors.Pink],
     ['All-family', SaccharideColors.Purple],
     ['Tal-family', SaccharideColors.LightBlue],
-    ['Ido-family', SaccharideColors.Blue],
+    ['Ido-family', SaccharideColors.Brown],
     ['Fuc-family', SaccharideColors.Red],
     ['Generic/Unknown/Secondary', SaccharideColors.Secondary],
 ]