ソースを参照

wip, react components

Alexander Rose 7 年 前
コミット
730337aca5

+ 441 - 20
package-lock.json

@@ -85,6 +85,15 @@
       "integrity": "sha512-Dt7aifQmvMPTLVimzvfQ99qUn4zeSDCQarFNV4otfDLYu0RFdSRBnqSLgksoAnsRL88xJ/UBKbd66iP2XIab0w==",
       "dev": true
     },
+    "@types/jss": {
+      "version": "9.5.2",
+      "resolved": "https://registry.npmjs.org/@types/jss/-/jss-9.5.2.tgz",
+      "integrity": "sha512-EX87yNYcisXO5BU9tT7stB7OGuDJyV3JwtMwhfUprrmHwYKWh9a3vchAy6DYzUSbmTA7bD46h8qata5jP1V7Zw==",
+      "requires": {
+        "csstype": "2.1.1",
+        "indefinite-observable": "1.0.1"
+      }
+    },
     "@types/mime": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/@types/mime/-/mime-2.0.0.tgz",
@@ -110,7 +119,6 @@
       "version": "16.3.5",
       "resolved": "https://registry.npmjs.org/@types/react/-/react-16.3.5.tgz",
       "integrity": "sha512-hjdnnTrogK++yHd/eRLieGqITd0gZcd+NxYSbgdy6E/jQwq9QlXKIHleKGwgU0cYlL1KWNgCVfFpqmMUwVgniA==",
-      "dev": true,
       "requires": {
         "csstype": "2.1.1"
       }
@@ -125,6 +133,14 @@
         "@types/react": "16.3.5"
       }
     },
+    "@types/react-transition-group": {
+      "version": "2.0.8",
+      "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-2.0.8.tgz",
+      "integrity": "sha512-52rCkAlhkFfaXplkujWUevTMb9/DCsND1DwB6VONPJKAShC3MrRl130ADV7Rc+7t83KVAoz4HPFhJuHI5pfnZA==",
+      "requires": {
+        "@types/react": "16.3.5"
+      }
+    },
     "@types/serve-static": {
       "version": "1.13.1",
       "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.1.tgz",
@@ -1273,7 +1289,6 @@
       "version": "6.26.0",
       "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz",
       "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=",
-      "dev": true,
       "requires": {
         "core-js": "2.5.3",
         "regenerator-runtime": "0.11.1"
@@ -1503,6 +1518,11 @@
         "repeat-element": "1.1.2"
       }
     },
+    "brcast": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/brcast/-/brcast-3.0.1.tgz",
+      "integrity": "sha512-eI3yqf9YEqyGl9PCNTR46MGvDylGtaHjalcz6Q3fAPnP/PhpKkkve52vFdfGpwp4VUvK6LUr4TQN+2stCrEwTg=="
+    },
     "brorand": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz",
@@ -1750,6 +1770,11 @@
         "lazy-cache": "1.0.4"
       }
     },
+    "chain-function": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/chain-function/-/chain-function-1.0.0.tgz",
+      "integrity": "sha1-DUqzfn4Y6tC9xHuSB2QRjOWHM9w="
+    },
     "chalk": {
       "version": "2.3.1",
       "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.1.tgz",
@@ -1778,6 +1803,11 @@
         }
       }
     },
+    "change-emitter": {
+      "version": "0.1.6",
+      "resolved": "https://registry.npmjs.org/change-emitter/-/change-emitter-0.1.6.tgz",
+      "integrity": "sha1-6LL+PX8at9aaMhma/5HqaTFAlRU="
+    },
     "chardet": {
       "version": "0.4.2",
       "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz",
@@ -1915,6 +1945,11 @@
         }
       }
     },
+    "classnames": {
+      "version": "2.2.5",
+      "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.2.5.tgz",
+      "integrity": "sha1-+zgB1FNGdknvNgPH1hoCvRKb3m0="
+    },
     "cli-cursor": {
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz",
@@ -2305,8 +2340,7 @@
     "core-js": {
       "version": "2.5.3",
       "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.3.tgz",
-      "integrity": "sha1-isw4NFgk8W2DZbfJtCWRaOjtYD4=",
-      "dev": true
+      "integrity": "sha1-isw4NFgk8W2DZbfJtCWRaOjtYD4="
     },
     "core-util-is": {
       "version": "1.0.2",
@@ -2419,6 +2453,14 @@
         "randomfill": "1.0.4"
       }
     },
+    "css-vendor": {
+      "version": "0.3.8",
+      "resolved": "https://registry.npmjs.org/css-vendor/-/css-vendor-0.3.8.tgz",
+      "integrity": "sha1-ZCHP0wNM5mT+dnOXL9ARn8KJQfo=",
+      "requires": {
+        "is-in-browser": "1.1.3"
+      }
+    },
     "cssom": {
       "version": "0.3.2",
       "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.2.tgz",
@@ -2437,8 +2479,7 @@
     "csstype": {
       "version": "2.1.1",
       "resolved": "https://registry.npmjs.org/csstype/-/csstype-2.1.1.tgz",
-      "integrity": "sha512-YsNVkaQtmsauSmlwqr/3EhJamZIObOcqfOgOmPuQxEXhsSvt/1/4M+bqN9xpsSEJqT2TWfTs2mPWrmwp0iQX6g==",
-      "dev": true
+      "integrity": "sha512-YsNVkaQtmsauSmlwqr/3EhJamZIObOcqfOgOmPuQxEXhsSvt/1/4M+bqN9xpsSEJqT2TWfTs2mPWrmwp0iQX6g=="
     },
     "cyclist": {
       "version": "0.2.2",
@@ -2531,6 +2572,11 @@
       "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=",
       "dev": true
     },
+    "deepmerge": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-2.1.0.tgz",
+      "integrity": "sha512-Q89Z26KAfA3lpPGhbF6XMfYAm3jIV3avViy6KOJ2JLzFbeWHOvPQUu5aSJIWXap3gDZC2y1eF5HXEPI2wGqgvw=="
+    },
     "default-require-extensions": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-1.0.0.tgz",
@@ -2632,6 +2678,16 @@
         "randombytes": "2.0.6"
       }
     },
+    "dom-helpers": {
+      "version": "3.3.1",
+      "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-3.3.1.tgz",
+      "integrity": "sha512-2Sm+JaYn74OiTM2wHvxJOo3roiq/h25Yi69Fqk269cNUwIXsCvATB6CRSFC9Am/20G2b28hGv/+7NiWydIrPvg=="
+    },
+    "dom-walk": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.1.tgz",
+      "integrity": "sha1-ZyIm3HTI95mtNTB9+TaroRrNYBg="
+    },
     "domain-browser": {
       "version": "1.2.0",
       "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz",
@@ -4514,6 +4570,22 @@
         "find-index": "0.1.1"
       }
     },
+    "global": {
+      "version": "4.3.2",
+      "resolved": "https://registry.npmjs.org/global/-/global-4.3.2.tgz",
+      "integrity": "sha1-52mJJopsdMOJCLEwWxD8DjlOnQ8=",
+      "requires": {
+        "min-document": "2.19.0",
+        "process": "0.5.2"
+      },
+      "dependencies": {
+        "process": {
+          "version": "0.5.2",
+          "resolved": "https://registry.npmjs.org/process/-/process-0.5.2.tgz",
+          "integrity": "sha1-FjjYqONML0QKkduVq5rrZ3/Bhc8="
+        }
+      }
+    },
     "global-modules": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz",
@@ -5158,6 +5230,11 @@
       "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=",
       "dev": true
     },
+    "hyphenate-style-name": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/hyphenate-style-name/-/hyphenate-style-name-1.0.2.tgz",
+      "integrity": "sha1-MRYKNpMK2vH8BMYHT360FGXU7Es="
+    },
     "iconv-lite": {
       "version": "0.4.19",
       "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz",
@@ -5191,6 +5268,21 @@
       "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
       "dev": true
     },
+    "indefinite-observable": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/indefinite-observable/-/indefinite-observable-1.0.1.tgz",
+      "integrity": "sha1-CZFUI8yNb36xy3iCrRNGM8mm7cM=",
+      "requires": {
+        "symbol-observable": "1.0.4"
+      },
+      "dependencies": {
+        "symbol-observable": {
+          "version": "1.0.4",
+          "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.0.4.tgz",
+          "integrity": "sha1-Kb9hXUqnEhvdiYsi1LP5vE4qoD0="
+        }
+      }
+    },
     "indent-string": {
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz",
@@ -5242,10 +5334,21 @@
         "lodash": "4.17.4",
         "mute-stream": "0.0.7",
         "run-async": "2.3.0",
-        "rxjs": "5.5.8",
+        "rxjs": "5.5.9",
         "string-width": "2.1.1",
         "strip-ansi": "4.0.0",
         "through": "2.3.8"
+      },
+      "dependencies": {
+        "rxjs": {
+          "version": "5.5.9",
+          "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-5.5.9.tgz",
+          "integrity": "sha512-DHG9AHmCmgaFWgjBcXp6NxFDmh3MvIA62GqTWmLnTzr/3oZ6h5hLD8NA+9j+GF0jEwklNIpI4KuuyLG8UWMEvQ==",
+          "dev": true,
+          "requires": {
+            "symbol-observable": "1.0.1"
+          }
+        }
       }
     },
     "interpret": {
@@ -5430,6 +5533,11 @@
       "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
       "dev": true
     },
+    "is-function": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/is-function/-/is-function-1.0.1.tgz",
+      "integrity": "sha1-Es+5i2W1fdPRk6MSH19uL0N2ArU="
+    },
     "is-generator-fn": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-1.0.0.tgz",
@@ -5445,6 +5553,11 @@
         "is-extglob": "1.0.0"
       }
     },
+    "is-in-browser": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/is-in-browser/-/is-in-browser-1.1.3.tgz",
+      "integrity": "sha1-Vv9NtoOgeMYILrldrX3GLh0E+DU="
+    },
     "is-number": {
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz",
@@ -5504,7 +5617,6 @@
       "version": "2.0.4",
       "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
       "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==",
-      "dev": true,
       "requires": {
         "isobject": "3.0.1"
       },
@@ -5512,8 +5624,7 @@
         "isobject": {
           "version": "3.0.1",
           "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
-          "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
-          "dev": true
+          "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8="
         }
       }
     },
@@ -6299,6 +6410,113 @@
         "verror": "1.10.0"
       }
     },
+    "jss": {
+      "version": "9.8.1",
+      "resolved": "https://registry.npmjs.org/jss/-/jss-9.8.1.tgz",
+      "integrity": "sha512-a9dXInEPTRmdSmzw3LNhbAwdQVZgCRmFU7dFzrpLTMAcdolHXNamhxQ6J+PNIqUtWa9yRbZIzWX6aUlI55LZ/A==",
+      "requires": {
+        "is-in-browser": "1.1.3",
+        "symbol-observable": "1.2.0",
+        "warning": "3.0.0"
+      },
+      "dependencies": {
+        "symbol-observable": {
+          "version": "1.2.0",
+          "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz",
+          "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ=="
+        }
+      }
+    },
+    "jss-camel-case": {
+      "version": "6.1.0",
+      "resolved": "https://registry.npmjs.org/jss-camel-case/-/jss-camel-case-6.1.0.tgz",
+      "integrity": "sha512-HPF2Q7wmNW1t79mCqSeU2vdd/vFFGpkazwvfHMOhPlMgXrJDzdj9viA2SaHk9ZbD5pfL63a8ylp4++irYbbzMQ==",
+      "requires": {
+        "hyphenate-style-name": "1.0.2"
+      }
+    },
+    "jss-compose": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/jss-compose/-/jss-compose-5.0.0.tgz",
+      "integrity": "sha512-YofRYuiA0+VbeOw0VjgkyO380sA4+TWDrW52nSluD9n+1FWOlDzNbgpZ/Sb3Y46+DcAbOS21W5jo6SAqUEiuwA==",
+      "requires": {
+        "warning": "3.0.0"
+      }
+    },
+    "jss-default-unit": {
+      "version": "8.0.2",
+      "resolved": "https://registry.npmjs.org/jss-default-unit/-/jss-default-unit-8.0.2.tgz",
+      "integrity": "sha512-WxNHrF/18CdoAGw2H0FqOEvJdREXVXLazn7PQYU7V6/BWkCV0GkmWsppNiExdw8dP4TU1ma1dT9zBNJ95feLmg=="
+    },
+    "jss-expand": {
+      "version": "5.1.0",
+      "resolved": "https://registry.npmjs.org/jss-expand/-/jss-expand-5.1.0.tgz",
+      "integrity": "sha512-WTxmNipgj0V8kr8gc8Gc6Et7uQZH60H7FFNG9zZHjR6TPJoj7TDK+/EBxwRHtCRQD4B8RTwoa7MyEKD4ReKfXw=="
+    },
+    "jss-extend": {
+      "version": "6.2.0",
+      "resolved": "https://registry.npmjs.org/jss-extend/-/jss-extend-6.2.0.tgz",
+      "integrity": "sha512-YszrmcB6o9HOsKPszK7NeDBNNjVyiW864jfoiHoMlgMIg2qlxKw70axZHqgczXHDcoyi/0/ikP1XaHDPRvYtEA==",
+      "requires": {
+        "warning": "3.0.0"
+      }
+    },
+    "jss-global": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/jss-global/-/jss-global-3.0.0.tgz",
+      "integrity": "sha512-wxYn7vL+TImyQYGAfdplg7yaxnPQ9RaXY/cIA8hawaVnmmWxDHzBK32u1y+RAvWboa3lW83ya3nVZ/C+jyjZ5Q=="
+    },
+    "jss-nested": {
+      "version": "6.0.1",
+      "resolved": "https://registry.npmjs.org/jss-nested/-/jss-nested-6.0.1.tgz",
+      "integrity": "sha512-rn964TralHOZxoyEgeq3hXY8hyuCElnvQoVrQwKHVmu55VRDd6IqExAx9be5HgK0yN/+hQdgAXQl/GUrBbbSTA==",
+      "requires": {
+        "warning": "3.0.0"
+      }
+    },
+    "jss-preset-default": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/jss-preset-default/-/jss-preset-default-4.3.0.tgz",
+      "integrity": "sha512-3VqMmR07OkiGyVPHfke/sjR33kSyRVjIE/3+bGgJ9Pp1jMIAPIDDY3h3wfEwa97DFV25SncTrNjjIgBFVCb4BA==",
+      "requires": {
+        "jss-camel-case": "6.1.0",
+        "jss-compose": "5.0.0",
+        "jss-default-unit": "8.0.2",
+        "jss-expand": "5.1.0",
+        "jss-extend": "6.2.0",
+        "jss-global": "3.0.0",
+        "jss-nested": "6.0.1",
+        "jss-props-sort": "6.0.0",
+        "jss-template": "1.0.1",
+        "jss-vendor-prefixer": "7.0.0"
+      }
+    },
+    "jss-props-sort": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/jss-props-sort/-/jss-props-sort-6.0.0.tgz",
+      "integrity": "sha512-E89UDcrphmI0LzmvYk25Hp4aE5ZBsXqMWlkFXS0EtPkunJkRr+WXdCNYbXbksIPnKlBenGB9OxzQY+mVc70S+g=="
+    },
+    "jss-template": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/jss-template/-/jss-template-1.0.1.tgz",
+      "integrity": "sha512-m5BqEWha17fmIVXm1z8xbJhY6GFJxNB9H68GVnCWPyGYfxiAgY9WTQyvDAVj+pYRgrXSOfN5V1T4+SzN1sJTeg==",
+      "requires": {
+        "warning": "3.0.0"
+      }
+    },
+    "jss-vendor-prefixer": {
+      "version": "7.0.0",
+      "resolved": "https://registry.npmjs.org/jss-vendor-prefixer/-/jss-vendor-prefixer-7.0.0.tgz",
+      "integrity": "sha512-Agd+FKmvsI0HLcYXkvy8GYOw3AAASBUpsmIRvVQheps+JWaN892uFOInTr0DRydwaD91vSSUCU4NssschvF7MA==",
+      "requires": {
+        "css-vendor": "0.3.8"
+      }
+    },
+    "keycode": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/keycode/-/keycode-2.2.0.tgz",
+      "integrity": "sha1-PQr1bce4uOXLqNCpfxByBO7CKwQ="
+    },
     "keyv": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.0.0.tgz",
@@ -6375,7 +6593,7 @@
         "log-update": "1.0.2",
         "ora": "0.2.3",
         "p-map": "1.2.0",
-        "rxjs": "5.5.8",
+        "rxjs": "5.5.9",
         "stream-to-observable": "0.2.0",
         "strip-ansi": "3.0.1"
       },
@@ -6418,6 +6636,15 @@
             "chalk": "1.1.3"
           }
         },
+        "rxjs": {
+          "version": "5.5.9",
+          "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-5.5.9.tgz",
+          "integrity": "sha512-DHG9AHmCmgaFWgjBcXp6NxFDmh3MvIA62GqTWmLnTzr/3oZ6h5hLD8NA+9j+GF0jEwklNIpI4KuuyLG8UWMEvQ==",
+          "dev": true,
+          "requires": {
+            "symbol-observable": "1.0.1"
+          }
+        },
         "strip-ansi": {
           "version": "3.0.1",
           "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
@@ -6644,8 +6871,7 @@
     "lodash": {
       "version": "4.17.4",
       "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz",
-      "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=",
-      "dev": true
+      "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4="
     },
     "lodash.sortby": {
       "version": "4.7.0",
@@ -6802,6 +7028,60 @@
         "object-visit": "1.0.1"
       }
     },
+    "material-ui": {
+      "version": "1.0.0-beta.41",
+      "resolved": "https://registry.npmjs.org/material-ui/-/material-ui-1.0.0-beta.41.tgz",
+      "integrity": "sha512-eUFD7mrrAIHPY/KGX23SDWJE5Xg5TAm4rH+E71yrKjmVOwrXT1YBxw1LUw9r+Y4XQD7rhGmGrUQan5CJAWUG5A==",
+      "requires": {
+        "@types/jss": "9.5.2",
+        "@types/react-transition-group": "2.0.8",
+        "babel-runtime": "6.26.0",
+        "brcast": "3.0.1",
+        "classnames": "2.2.5",
+        "deepmerge": "2.1.0",
+        "dom-helpers": "3.3.1",
+        "hoist-non-react-statics": "2.5.0",
+        "jss": "9.8.1",
+        "jss-camel-case": "6.1.0",
+        "jss-default-unit": "8.0.2",
+        "jss-global": "3.0.0",
+        "jss-nested": "6.0.1",
+        "jss-props-sort": "6.0.0",
+        "jss-vendor-prefixer": "7.0.0",
+        "keycode": "2.2.0",
+        "lodash": "4.17.4",
+        "normalize-scroll-left": "0.1.2",
+        "prop-types": "15.6.1",
+        "react-event-listener": "0.5.3",
+        "react-jss": "8.4.0",
+        "react-lifecycles-compat": "1.1.4",
+        "react-popper": "0.8.3",
+        "react-scrollbar-size": "2.1.0",
+        "react-transition-group": "2.3.0",
+        "recompose": "0.26.0",
+        "scroll": "2.0.3",
+        "warning": "3.0.0"
+      },
+      "dependencies": {
+        "hoist-non-react-statics": {
+          "version": "2.5.0",
+          "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-2.5.0.tgz",
+          "integrity": "sha512-6Bl6XsDT1ntE0lHbIhr4Kp2PGcleGZ66qu5Jqk8lc0Xc/IeG6gVLmwUGs/K0Us+L8VWoKgj0uWdPMataOsm31w=="
+        },
+        "react-transition-group": {
+          "version": "2.3.0",
+          "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-2.3.0.tgz",
+          "integrity": "sha512-OU3/swEL8y233u5ajTn3FIcQQ/b3XWjLXB6e2LnM1OK5JATtsyfJvPTZ8c/dawHNqjUltcdHRSpgMtPe7v07pw==",
+          "requires": {
+            "chain-function": "1.0.0",
+            "dom-helpers": "3.3.1",
+            "loose-envify": "1.3.1",
+            "prop-types": "15.6.1",
+            "warning": "3.0.0"
+          }
+        }
+      }
+    },
     "md5.js": {
       "version": "1.3.4",
       "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.4.tgz",
@@ -6997,6 +7277,14 @@
       "integrity": "sha1-3z02Uqc/3ta5sLJBRub9BSNTRY4=",
       "dev": true
     },
+    "min-document": {
+      "version": "2.19.0",
+      "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz",
+      "integrity": "sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU=",
+      "requires": {
+        "dom-walk": "0.1.1"
+      }
+    },
     "minimalistic-assert": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.0.tgz",
@@ -7339,6 +7627,11 @@
         "remove-trailing-separator": "1.1.0"
       }
     },
+    "normalize-scroll-left": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/normalize-scroll-left/-/normalize-scroll-left-0.1.2.tgz",
+      "integrity": "sha512-F9YMRls0zCF6BFIE2YnXDRpHPpfd91nOIaNdDgrx5YMoPLo8Wqj+6jNXHQsYBavJeXP4ww8HCt0xQAKc5qk2Fg=="
+    },
     "normalize-url": {
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-2.0.1.tgz",
@@ -7932,6 +8225,11 @@
       "integrity": "sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA==",
       "dev": true
     },
+    "popper.js": {
+      "version": "1.14.3",
+      "resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.14.3.tgz",
+      "integrity": "sha1-FDj5jQRqz3tNeM1QK/QYrGTU8JU="
+    },
     "posix-character-classes": {
       "version": "0.1.1",
       "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz",
@@ -8178,6 +8476,14 @@
         }
       }
     },
+    "rafl": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/rafl/-/rafl-1.2.2.tgz",
+      "integrity": "sha1-/pMPdYIRAg1H44gV9Rlqi+QVB0A=",
+      "requires": {
+        "global": "4.3.2"
+      }
+    },
     "randomatic": {
       "version": "1.1.7",
       "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-1.1.7.tgz",
@@ -8305,6 +8611,61 @@
         "prop-types": "15.6.1"
       }
     },
+    "react-event-listener": {
+      "version": "0.5.3",
+      "resolved": "https://registry.npmjs.org/react-event-listener/-/react-event-listener-0.5.3.tgz",
+      "integrity": "sha512-fTGYvhe7eTsqq0m664Km0rxKQcqLIGZWZINmy1LU0fu312tay8Mt3Twq2P5Xj1dfDVvvzT1Ql3/FDkiMPJ1MOg==",
+      "requires": {
+        "babel-runtime": "6.26.0",
+        "fbjs": "0.8.16",
+        "prop-types": "15.6.1",
+        "warning": "3.0.0"
+      }
+    },
+    "react-jss": {
+      "version": "8.4.0",
+      "resolved": "https://registry.npmjs.org/react-jss/-/react-jss-8.4.0.tgz",
+      "integrity": "sha512-yIi4udcTIIh5u4KJ47wsL3UZYMuSrp5xR1YBvPeRNshpCdRoJxt5BWmCu1RA3LIa+//dnRsAtAQmMAYeg1W9oQ==",
+      "requires": {
+        "hoist-non-react-statics": "2.5.0",
+        "jss": "9.8.1",
+        "jss-preset-default": "4.3.0",
+        "prop-types": "15.6.1",
+        "theming": "1.3.0"
+      },
+      "dependencies": {
+        "hoist-non-react-statics": {
+          "version": "2.5.0",
+          "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-2.5.0.tgz",
+          "integrity": "sha512-6Bl6XsDT1ntE0lHbIhr4Kp2PGcleGZ66qu5Jqk8lc0Xc/IeG6gVLmwUGs/K0Us+L8VWoKgj0uWdPMataOsm31w=="
+        }
+      }
+    },
+    "react-lifecycles-compat": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-1.1.4.tgz",
+      "integrity": "sha512-g3pdexIqkn+CVvSpYIoyON8zUbF9kgfhp672gyz7wQ7PQyXVmJtah+GDYqpHpOrdwex3F77iv+alq79iux9HZw=="
+    },
+    "react-popper": {
+      "version": "0.8.3",
+      "resolved": "https://registry.npmjs.org/react-popper/-/react-popper-0.8.3.tgz",
+      "integrity": "sha1-D3MzMTfJ+wr27EB00tBYWgoEYeE=",
+      "requires": {
+        "popper.js": "1.14.3",
+        "prop-types": "15.6.1"
+      }
+    },
+    "react-scrollbar-size": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/react-scrollbar-size/-/react-scrollbar-size-2.1.0.tgz",
+      "integrity": "sha512-9dDUJvk7S48r0TRKjlKJ9e/LkLLYgc9LdQR6W21I8ZqtSrEsedPOoMji4nU3DHy7fx2l8YMScJS/N7qiloYzXQ==",
+      "requires": {
+        "babel-runtime": "6.26.0",
+        "prop-types": "15.6.1",
+        "react-event-listener": "0.5.3",
+        "stifle": "1.0.4"
+      }
+    },
     "read-chunk": {
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/read-chunk/-/read-chunk-2.1.0.tgz",
@@ -8430,6 +8791,29 @@
         "resolve": "1.1.7"
       }
     },
+    "recompose": {
+      "version": "0.26.0",
+      "resolved": "https://registry.npmjs.org/recompose/-/recompose-0.26.0.tgz",
+      "integrity": "sha512-KwOu6ztO0mN5vy3+zDcc45lgnaUoaQse/a5yLVqtzTK13czSWnFGmXbQVmnoMgDkI5POd1EwIKSbjU1V7xdZog==",
+      "requires": {
+        "change-emitter": "0.1.6",
+        "fbjs": "0.8.16",
+        "hoist-non-react-statics": "2.5.0",
+        "symbol-observable": "1.2.0"
+      },
+      "dependencies": {
+        "hoist-non-react-statics": {
+          "version": "2.5.0",
+          "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-2.5.0.tgz",
+          "integrity": "sha512-6Bl6XsDT1ntE0lHbIhr4Kp2PGcleGZ66qu5Jqk8lc0Xc/IeG6gVLmwUGs/K0Us+L8VWoKgj0uWdPMataOsm31w=="
+        },
+        "symbol-observable": {
+          "version": "1.2.0",
+          "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz",
+          "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ=="
+        }
+      }
+    },
     "regenerate": {
       "version": "1.3.3",
       "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.3.3.tgz",
@@ -8439,8 +8823,7 @@
     "regenerator-runtime": {
       "version": "0.11.1",
       "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz",
-      "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==",
-      "dev": true
+      "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg=="
     },
     "regenerator-transform": {
       "version": "0.10.1",
@@ -8730,12 +9113,18 @@
       }
     },
     "rxjs": {
-      "version": "5.5.8",
-      "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-5.5.8.tgz",
-      "integrity": "sha512-Bz7qou7VAIoGiglJZbzbXa4vpX5BmTTN2Dj/se6+SwADtw4SihqBIiEa7VmTXJ8pynvq0iFr5Gx9VLyye1rIxQ==",
-      "dev": true,
+      "version": "6.0.0-beta.4",
+      "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.0.0-beta.4.tgz",
+      "integrity": "sha512-H+ghJ4H2mPrugoMfgbeky0yhmOrk4y0ykRyZpYvU2za0VbE2WTKgY/9pF7HJCogPFNIyI4GqI9Ujk3Xr4XxHbQ==",
       "requires": {
-        "symbol-observable": "1.0.1"
+        "tslib": "1.9.0"
+      },
+      "dependencies": {
+        "tslib": {
+          "version": "1.9.0",
+          "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.0.tgz",
+          "integrity": "sha512-f/qGG2tUkrISBlQZEjEqoZ3B2+npJjIf04H1wuAv9iA8i04Icp+61KRXxFdha22670NJopsZCIjhC3SnjPRKrQ=="
+        }
       }
     },
     "safe-buffer": {
@@ -9078,6 +9467,14 @@
       "integrity": "sha1-o0a7Gs1CB65wvXwMfKnlZra63bg=",
       "dev": true
     },
+    "scroll": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/scroll/-/scroll-2.0.3.tgz",
+      "integrity": "sha512-3ncZzf8gUW739h3LeS68nSssO60O+GGjT3SxzgofQmT8PIoyHzebql9HHPJopZX8iT6TKOdwaWFMqL6LzUN3DQ==",
+      "requires": {
+        "rafl": "1.2.2"
+      }
+    },
     "semver": {
       "version": "5.4.1",
       "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz",
@@ -9756,6 +10153,11 @@
       "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=",
       "dev": true
     },
+    "stifle": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/stifle/-/stifle-1.0.4.tgz",
+      "integrity": "sha1-izvN9SQZsKnHnjWtrc5QEjwdjpk="
+    },
     "stream-browserify": {
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.1.tgz",
@@ -10238,6 +10640,17 @@
       "integrity": "sha512-j5EMxnryTvKxwH2Cq+Pb43tsf6sdEgw6Pdwxk83mPaq0ToeFJt6WE4J3s5BqY7vmjlLgkgXvhtXUxo80FyBhCA==",
       "dev": true
     },
+    "theming": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/theming/-/theming-1.3.0.tgz",
+      "integrity": "sha512-ya5Ef7XDGbTPBv5ENTwrwkPUexrlPeiAg/EI9kdlUAZhNlRbCdhMKRgjNX1IcmsmiPcqDQZE6BpSaH+cr31FKw==",
+      "requires": {
+        "brcast": "3.0.1",
+        "is-function": "1.0.1",
+        "is-plain-object": "2.0.4",
+        "prop-types": "15.6.1"
+      }
+    },
     "throat": {
       "version": "4.1.0",
       "resolved": "https://registry.npmjs.org/throat/-/throat-4.1.0.tgz",
@@ -10938,6 +11351,14 @@
         "makeerror": "1.0.11"
       }
     },
+    "warning": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/warning/-/warning-3.0.0.tgz",
+      "integrity": "sha1-MuU3fLVy3kqwR1O9+IIcAe1gW3w=",
+      "requires": {
+        "loose-envify": "1.3.1"
+      }
+    },
     "watch": {
       "version": "0.18.0",
       "resolved": "https://registry.npmjs.org/watch/-/watch-0.18.0.tgz",

+ 3 - 1
package.json

@@ -80,8 +80,10 @@
   "dependencies": {
     "argparse": "^1.0.10",
     "express": "^4.16.3",
+    "material-ui": "^1.0.0-beta.41",
     "node-fetch": "^2.1.2",
     "react": "^16.3.1",
-    "react-dom": "^16.3.1"
+    "react-dom": "^16.3.1",
+    "rxjs": "^6.0.0-beta.4"
   }
 }

+ 40 - 0
src/apps/render-test/components/file-input.tsx

@@ -0,0 +1,40 @@
+/**
+ * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ *
+ * @author Alexander Rose <alexander.rose@weirdbyte.de>
+ */
+
+import * as React from 'react'
+import { WithStyles } from 'material-ui/styles';
+import TextField from 'material-ui/TextField';
+// import FileUpload from '@material-ui/icons/FileUpload';
+
+import State from '../state'
+import Observer from './observer';
+
+export default class FileInput extends Observer<{ state: State } & WithStyles, { loading: boolean }> {
+    state = { loading: false }
+
+    componentDidMount() {
+        this.subscribe(this.props.state.loading, value => {
+           this.setState({ loading: value });
+        });
+    }
+
+    render() {
+        const { classes, state } = this.props;
+
+        return <TextField
+            label='PDB ID'
+            className={classes.textField}
+            disabled={this.state.loading}
+            margin='normal'
+            onChange={(event) => {
+                state.pdbId = event.target.value
+            }}
+            onKeyPress={(event) => {
+                if (event.key === 'Enter') state.loadPdbId()
+            }}
+        />
+    }
+}

+ 21 - 0
src/apps/render-test/components/observer.tsx

@@ -0,0 +1,21 @@
+/**
+ * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ *
+ * @author Alexander Rose <alexander.rose@weirdbyte.de>
+ */
+
+import * as React from 'react'
+import { Observable, Subscription } from 'rxjs';
+
+export default class Observer<S, P> extends React.Component<S, P> {
+    private _subs: Subscription[] = []
+
+    subscribe<T>(obs: Observable<T>, onNext: (v: T) => void) {
+        this._subs.push(obs.subscribe(onNext));
+    }
+
+    componentWillUnmount() {
+        for (const s of this._subs) s.unsubscribe();
+        this._subs = [];
+    }
+}

+ 22 - 0
src/apps/render-test/components/viewport.tsx

@@ -0,0 +1,22 @@
+/**
+ * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ *
+ * @author Alexander Rose <alexander.rose@weirdbyte.de>
+ */
+
+import * as React from 'react'
+import State from '../state'
+
+export default class Viewport extends React.Component<{ state: State }, { initialized: boolean }> {
+    private canvasContainer: HTMLDivElement | null = null;
+    state = { initialized: false }
+
+    componentDidMount() {
+        if (this.canvasContainer) this.props.state.initRenderer(this.canvasContainer).then(() => this.setState({ initialized: true }))
+    }
+
+    render() {
+        return <div ref={elm => this.canvasContainer = elm} style={{ height: '100%' }}>
+        </div>
+    }
+}

+ 1 - 1
src/apps/render-test/index.tsx

@@ -10,4 +10,4 @@ import * as React from 'react'
 import * as ReactDOM from 'react-dom'
 
 const state = new State()
-ReactDOM.render(<UI state={state} />, document.getElementById('app'));
+ReactDOM.render(<UI state={ state } />, document.getElementById('app'));

+ 115 - 110
src/apps/render-test/state.ts

@@ -4,127 +4,47 @@
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
  */
 
-import { ValueCell } from 'mol-util/value-cell'
+import { BehaviorSubject } from 'rxjs';
 
-import { Vec3, Mat4 } from 'mol-math/linear-algebra'
-import { createRenderer, createRenderObject } from 'mol-gl/renderer'
-import { createColorTexture } from 'mol-gl/util';
+// import { ValueCell } from 'mol-util/value-cell'
+
+// import { Vec3, Mat4 } from 'mol-math/linear-algebra'
+import { createRenderer, Renderer } from 'mol-gl/renderer'
+// import { createColorTexture } from 'mol-gl/util';
 // import Icosahedron from 'mol-geo/primitive/icosahedron'
 // import Box from 'mol-geo/primitive/box'
 import Spacefill from 'mol-geo/representation/structure/spacefill'
 import Point from 'mol-geo/representation/structure/point'
 
-import CIF from 'mol-io/reader/cif'
-import { Run, Progress } from 'mol-task'
-import { Structure, Symmetry } from 'mol-model/structure'
-
-function log(progress: Progress) {
-    const p = progress.root.progress
-    console.log(`${p.message} ${(p.current/p.max*100).toFixed(2)}%`)
-}
-
-async function parseCif(data: string|Uint8Array) {
-    const comp = CIF.parse(data)
-    const parsed = await Run(comp, log, 100);
-    if (parsed.isError) throw parsed;
-    return parsed
-}
-
-async function getPdb(pdb: string) {
-    const data = await fetch(`https://files.rcsb.org/download/${pdb}.cif`)
-    const parsed = await parseCif(await data.text())
-    const structure = Structure.ofData({ kind: 'mmCIF', data: CIF.schema.mmCIF(parsed.result.blocks[0]) })
-    return structure
-}
+import { Run } from 'mol-task'
+import { Symmetry } from 'mol-model/structure'
 
-import mcubes from './mcubes'
+// import mcubes from './utils/mcubes'
+import { getStructuresFromPdbId } from './utils'
 import { StructureRepresentation } from 'mol-geo/representation/structure';
 // import Cylinder from 'mol-geo/primitive/cylinder';
 
 export default class State {
+    renderer: Renderer
+    pdbId = '1crn'
+    initialized = new BehaviorSubject<boolean>(false)
+    loading = new BehaviorSubject<boolean>(false)
+
     async initRenderer (container: HTMLDivElement) {
-        const renderer = createRenderer(container)
-
-        const p1 = Vec3.create(0, 4, 0)
-        const p2 = Vec3.create(-3, 0, 0)
-
-        // const position = ValueCell.create(new Float32Array([0, -1, 0, -1, 0, 0, 1, 1, 0]))
-        // const normal = ValueCell.create(new Float32Array([0, 0, 0, 0, 0, 0, 0, 0, 0]))
-
-        const transformArray1 = ValueCell.create(new Float32Array(16))
-        const transformArray2 = ValueCell.create(new Float32Array(16 * 3))
-        const m4 = Mat4.identity()
-        Mat4.toArray(m4, transformArray1.ref.value, 0)
-        Mat4.toArray(m4, transformArray2.ref.value, 0)
-        Mat4.setTranslation(m4, p1)
-        Mat4.toArray(m4, transformArray2.ref.value, 16)
-        Mat4.setTranslation(m4, p2)
-        Mat4.toArray(m4, transformArray2.ref.value, 32)
-
-        const color = ValueCell.create(createColorTexture(3))
-        color.ref.value.set([
-            0, 0, 255,
-            0, 255, 0,
-            255, 0, 0
-        ])
-
-        // const points = createRenderObject('point', {
-        //     position,
-        //     transform: transformArray1
-        // })
-        // // renderer.add(points)
-
-        // const mesh = createRenderObject('mesh', {
-        //     position,
-        //     normal,
-        //     color,
-        //     transform: transformArray2
-        // })
-        // renderer.add(mesh)
-
-        // const cylinder = Cylinder({ height: 3, radiusBottom: 0.5, radiusTop: 0.5 })
-        // console.log(cylinder)
-        // const cylinderMesh = createRenderObject('mesh', {
-        //     position: ValueCell.create(cylinder.vertices),
-        //     normal: ValueCell.create(cylinder.normals),
-        //     color,
-        //     transform: transformArray2
-        // }, cylinder.indices)
-        // renderer.add(cylinderMesh)
-
-        // const sphere = Icosahedron()
-        // console.log(sphere)
-
-        // const box = Box()
-        // console.log(box)
-
-        // const points2 = createRenderObject('point', {
-        //     position: ValueCell.create(new Float32Array(box.vertices)),
-        //     transform: transformArray1
-        // })
-        // renderer.add(points2)
-
-        let rr = 0.7;
-        function cubesF(x: number, y: number, z: number) {
-            return x * x + y * y + z * z - rr * rr;
-        }
-        let cubes = await mcubes(cubesF);
-
-        const makeCubesMesh = () => createRenderObject('mesh', {
-            position: cubes.surface.vertexBuffer,
-            normal: cubes.surface.normalBuffer,
-            color,
-            transform: transformArray2,
-            elements: cubes.surface.indexBuffer,
-
-            instanceCount: transformArray2.ref.value.length / 16,
-            elementCount: cubes.surface.triangleCount,
-            positionCount: cubes.surface.vertexCount
-        }, {});
-        const mesh2 = makeCubesMesh();
-        renderer.add(mesh2)
-
-        const structures = await getPdb('1rb8')
+        this.renderer = createRenderer(container)
+        this.initialized.next(true)
+        this.loadPdbId()
+        this.renderer.frame()
+    }
+
+    async loadPdbId () {
+        const { renderer, pdbId } = this
+        renderer.clear()
+
+        if (pdbId.length !== 4) return
+        this.loading.next(true)
+
+        const structures = await getStructuresFromPdbId(pdbId)
         const struct = Symmetry.buildAssembly(structures[0], '1')
 
         const structPointRepr = StructureRepresentation(Point)
@@ -135,6 +55,91 @@ export default class State {
         await Run(structSpacefillRepr.create(struct))
         structSpacefillRepr.renderObjects.forEach(renderer.add)
 
-        renderer.frame()
+        renderer.draw(true)
+
+        this.loading.next(false)
     }
 }
+
+
+
+// async foo () {
+//     const p1 = Vec3.create(0, 4, 0)
+//     const p2 = Vec3.create(-3, 0, 0)
+
+//     // const position = ValueCell.create(new Float32Array([0, -1, 0, -1, 0, 0, 1, 1, 0]))
+//     // const normal = ValueCell.create(new Float32Array([0, 0, 0, 0, 0, 0, 0, 0, 0]))
+
+//     const transformArray1 = ValueCell.create(new Float32Array(16))
+//     const transformArray2 = ValueCell.create(new Float32Array(16 * 3))
+//     const m4 = Mat4.identity()
+//     Mat4.toArray(m4, transformArray1.ref.value, 0)
+//     Mat4.toArray(m4, transformArray2.ref.value, 0)
+//     Mat4.setTranslation(m4, p1)
+//     Mat4.toArray(m4, transformArray2.ref.value, 16)
+//     Mat4.setTranslation(m4, p2)
+//     Mat4.toArray(m4, transformArray2.ref.value, 32)
+
+//     const color = ValueCell.create(createColorTexture(3))
+//     color.ref.value.set([
+//         0, 0, 255,
+//         0, 255, 0,
+//         255, 0, 0
+//     ])
+
+//     // const points = createRenderObject('point', {
+//     //     position,
+//     //     transform: transformArray1
+//     // })
+//     // // renderer.add(points)
+
+//     // const mesh = createRenderObject('mesh', {
+//     //     position,
+//     //     normal,
+//     //     color,
+//     //     transform: transformArray2
+//     // })
+//     // renderer.add(mesh)
+
+//     // const cylinder = Cylinder({ height: 3, radiusBottom: 0.5, radiusTop: 0.5 })
+//     // console.log(cylinder)
+//     // const cylinderMesh = createRenderObject('mesh', {
+//     //     position: ValueCell.create(cylinder.vertices),
+//     //     normal: ValueCell.create(cylinder.normals),
+//     //     color,
+//     //     transform: transformArray2
+//     // }, cylinder.indices)
+//     // renderer.add(cylinderMesh)
+
+//     // const sphere = Icosahedron()
+//     // console.log(sphere)
+
+//     // const box = Box()
+//     // console.log(box)
+
+//     // const points2 = createRenderObject('point', {
+//     //     position: ValueCell.create(new Float32Array(box.vertices)),
+//     //     transform: transformArray1
+//     // })
+//     // renderer.add(points2)
+
+//     // let rr = 0.7;
+//     // function cubesF(x: number, y: number, z: number) {
+//     //     return x * x + y * y + z * z - rr * rr;
+//     // }
+//     // let cubes = await mcubes(cubesF);
+
+//     // const makeCubesMesh = () => createRenderObject('mesh', {
+//     //     position: cubes.surface.vertexBuffer,
+//     //     normal: cubes.surface.normalBuffer,
+//     //     color,
+//     //     transform: transformArray2,
+//     //     elements: cubes.surface.indexBuffer,
+
+//     //     instanceCount: transformArray2.ref.value.length / 16,
+//     //     elementCount: cubes.surface.triangleCount,
+//     //     positionCount: cubes.surface.vertexCount
+//     // }, {});
+//     // const mesh2 = makeCubesMesh();
+//     // renderer.add(mesh2)
+// }

+ 66 - 9
src/apps/render-test/ui.tsx

@@ -5,18 +5,75 @@
  */
 
 import * as React from 'react'
+import { withStyles, WithStyles, Theme, StyleRulesCallback } from 'material-ui/styles';
+import Typography from 'material-ui/Typography';
+import Toolbar from 'material-ui/Toolbar';
+import AppBar from 'material-ui/AppBar';
+import Drawer from 'material-ui/Drawer';
+
+import Viewport from './components/viewport'
+import FileInput from './components/file-input'
 import State from './state'
 
-export default class Root extends React.Component<{ state: State }, { initialized: boolean }> {
-    private canvasContainer: HTMLDivElement | null = null;
-    state = { initialized: false }
+const styles: StyleRulesCallback<any> = (theme: Theme) => ({
+    root: {
+        flexGrow: 1,
+        height: 830,
+        zIndex: 1,
+        overflow: 'hidden',
+        position: 'relative',
+        display: 'flex',
+    },
+    appBar: {
+        zIndex: theme.zIndex.drawer + 1,
+    },
+    drawerPaper: {
+        position: 'relative',
+        width: 240,
+    },
+    content: {
+        flexGrow: 1,
+        backgroundColor: theme.palette.background.default,
+        padding: theme.spacing.unit * 3,
+        minWidth: 0, // So the Typography noWrap works
+    },
+    toolbar: theme.mixins.toolbar,
+    textField: {
+        marginLeft: theme.spacing.unit,
+        marginRight: theme.spacing.unit,
+        width: 200,
+    },
+});
 
-    componentDidMount() {
-        if (this.canvasContainer) this.props.state.initRenderer(this.canvasContainer).then(() => this.setState({ initialized: true }))
-    }
+const decorate = withStyles(styles);
 
+interface Props {
+    state: State;
+};
+
+class UI extends React.Component<{ state: State } & WithStyles, {  }> {
     render() {
-        return <div ref={elm => this.canvasContainer = elm} style={{ position: 'absolute', top: 0, right: 0, left: 0, bottom: 0, overflow: 'hidden' }}>
-        </div>
+        const { classes, state } = this.props;
+        return (
+            <div className={classes.root}>
+                <AppBar position='absolute' className={classes.appBar}>
+                    <Toolbar>
+                    <Typography variant='title' color='inherit' noWrap>
+                        Mol* Render Test
+                    </Typography>
+                    </Toolbar>
+                </AppBar>
+                <Drawer variant='permanent' classes={{ paper: classes.drawerPaper, }}>
+                    <div className={classes.toolbar} />
+                    <FileInput state={state} classes={classes}></FileInput>
+                </Drawer>
+                <main className={classes.content}>
+                    <div className={classes.toolbar} />
+                    <Viewport state={state}></Viewport>
+                </main>
+            </div>
+        );
     }
-}
+}
+
+export default decorate<Props>(UI)

+ 27 - 0
src/apps/render-test/utils/index.ts

@@ -0,0 +1,27 @@
+/**
+ * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ *
+ * @author Alexander Rose <alexander.rose@weirdbyte.de>
+ */
+
+import CIF from 'mol-io/reader/cif'
+import { Run, Progress } from 'mol-task'
+import { Structure } from 'mol-model/structure'
+
+export function log(progress: Progress) {
+    const p = progress.root.progress
+    console.log(`${p.message} ${(p.current/p.max*100).toFixed(2)}%`)
+}
+
+export async function parseCif(data: string|Uint8Array) {
+    const comp = CIF.parse(data)
+    const parsed = await Run(comp, log, 100);
+    if (parsed.isError) throw parsed;
+    return parsed
+}
+
+export async function getStructuresFromPdbId(pdbid: string) {
+    const data = await fetch(`https://files.rcsb.org/download/${pdbid}.cif`)
+    const parsed = await parseCif(await data.text())
+    return Structure.ofData({ kind: 'mmCIF', data: CIF.schema.mmCIF(parsed.result.blocks[0]) })
+}

+ 0 - 0
src/apps/render-test/mcubes.ts → src/apps/render-test/utils/mcubes.ts


+ 3 - 2
src/mol-gl/camera.ts

@@ -49,7 +49,7 @@ export interface Camera {
     update: (props: any, block: any) => void,
     setState: (newState: CameraState) => void,
     getState: () => CameraState,
-    isDirty: () => boolean
+    dirty: boolean
 }
 
 export namespace Camera {
@@ -185,7 +185,8 @@ export namespace Camera {
             update,
             setState,
             getState: () => Object.assign({}, state),
-            isDirty: () => dirty
+            get dirty() { return dirty },
+            set dirty(value: boolean) { dirty = value }
         }
     }
 }

+ 0 - 1
src/mol-gl/renderable/mesh.ts

@@ -31,7 +31,6 @@ namespace Mesh {
     }
 
     export function create(regl: REGL.Regl, data: Data, uniforms: Uniforms): Renderable {
-        console.log(data)
         const instanceId = ValueCell.create(fillSerial(new Float32Array(data.instanceCount)))
         const command = regl({
             ...MeshShaders,

+ 0 - 1
src/mol-gl/renderable/point.ts

@@ -24,7 +24,6 @@ namespace Point {
     }
 
     export function create(regl: REGL.Regl, data: Data): Renderable {
-        console.log(data)
         const instanceId = ValueCell.create(fillSerial(new Float32Array(data.instanceCount)))
         const command = regl({
             ...PointShaders,

+ 41 - 16
src/mol-gl/renderer.ts

@@ -39,7 +39,8 @@ export function createRenderObject(type: 'mesh' | 'point', data: PointRenderable
 export interface Renderer {
     add: (o: RenderObject) => void
     remove: (o: RenderObject) => void
-    draw: () => void
+    clear: () => void
+    draw: (force: boolean) => void
     frame: () => void
 }
 
@@ -54,18 +55,33 @@ export function createRenderer(container: HTMLDivElement): Renderer {
     const renderableList: Renderable[] = []
     const objectIdRenderableMap: { [k: number]: Renderable } = {}
 
-    const regl = glContext.create({
-        container,
-        extensions: [
-            'OES_texture_float',
-            'OES_texture_float_linear',
-            'OES_element_index_uint',
-            // 'EXT_disjoint_timer_query',
-            'EXT_blend_minmax',
-            'ANGLE_instanced_arrays'
-        ],
-        profile: true
-    })
+    let regl: REGL.Regl
+    try {
+        regl = glContext.create({
+            container,
+            extensions: [
+                'OES_texture_float',
+                'OES_texture_float_linear',
+                'OES_element_index_uint',
+                'EXT_disjoint_timer_query',
+                'EXT_blend_minmax',
+                'ANGLE_instanced_arrays'
+            ],
+            profile: true
+        })
+    } catch (e) {
+        regl = glContext.create({
+            container,
+            extensions: [
+                'OES_texture_float',
+                'OES_texture_float_linear',
+                'OES_element_index_uint',
+                'EXT_blend_minmax',
+                'ANGLE_instanced_arrays'
+            ],
+            profile: true
+        })
+    }
 
     const camera = Camera.create(regl, container, {
         center: Vec3.create(0, 0, 0),
@@ -91,12 +107,12 @@ export function createRenderer(container: HTMLDivElement): Renderer {
         }
     })
 
-    const draw = () => {
+    const draw = (force = false) => {
         camera.update((state: any) => {
-            if (!camera.isDirty()) return;
+            if (!force && !camera.dirty) return;
             baseContext(() => {
                 // console.log(ctx)
-                regl.clear({color: [0, 0, 0, 1]})
+                regl.clear({ color: [0, 0, 0, 1] })
                 // TODO painters sort, filter visible, filter picking, visibility culling?
                 renderableList.forEach(r => {
                     r.draw()
@@ -118,6 +134,15 @@ export function createRenderer(container: HTMLDivElement): Renderer {
                 delete objectIdRenderableMap[o.id]
             }
         },
+        clear: () => {
+            for (const id in objectIdRenderableMap) {
+                // TODO
+                // objectIdRenderableMap[id].destroy()
+                delete objectIdRenderableMap[id]
+            }
+            renderableList.length = 0
+            camera.dirty = true
+        },
         draw,
         frame: () => {
             regl.frame((ctx) => draw())