Alexander Rose 6 jaren geleden
bovenliggende
commit
349880ce90
100 gewijzigde bestanden met toevoegingen van 435 en 9860 verwijderingen
  1. 19 19
      package-lock.json
  2. 3 4
      src/apps/canvas/app.ts
  3. 49 0
      src/apps/canvas/component/representation.tsx
  4. 0 261
      src/apps/canvas/component/structure-representation.tsx
  5. 4 3
      src/apps/canvas/component/structure-view.tsx
  6. 0 245
      src/apps/canvas/component/volume-representation.tsx
  7. 1 1
      src/apps/canvas/index.ts
  8. 2 2
      src/apps/canvas/structure-view.ts
  9. 1 1
      src/apps/structure-info/volume.ts
  10. 0 13
      src/apps/viewer/index.html
  11. 0 107
      src/apps/viewer/index.tsx
  12. 56 0
      src/mol-app/component/color-theme.tsx
  13. 38 0
      src/mol-app/component/parameter/boolean.tsx
  14. 44 0
      src/mol-app/component/parameter/number.tsx
  15. 44 0
      src/mol-app/component/parameter/range.tsx
  16. 41 0
      src/mol-app/component/parameter/select.tsx
  17. 52 0
      src/mol-app/component/parameters.tsx
  18. 81 0
      src/mol-app/component/sequence.tsx
  19. 0 67
      src/mol-app/context/context.ts
  20. 0 49
      src/mol-app/controller/controller.ts
  21. 0 27
      src/mol-app/controller/entity/tree.ts
  22. 0 216
      src/mol-app/controller/layout.ts
  23. 0 81
      src/mol-app/controller/misc/jobs.ts
  24. 0 24
      src/mol-app/controller/misc/log.ts
  25. 0 27
      src/mol-app/controller/transform/list.ts
  26. 0 21
      src/mol-app/controller/visualization/sequence-view.ts
  27. 0 27
      src/mol-app/controller/visualization/viewport.ts
  28. 0 40
      src/mol-app/event/basic.ts
  29. 0 43
      src/mol-app/event/event.ts
  30. 0 59
      src/mol-app/service/dispatcher.ts
  31. 0 132
      src/mol-app/service/job.ts
  32. 0 51
      src/mol-app/service/logger.ts
  33. 0 45
      src/mol-app/skin/base.scss
  34. 0 25
      src/mol-app/skin/bootstrap.scss
  35. 0 68
      src/mol-app/skin/bootstrap/badges.scss
  36. 0 244
      src/mol-app/skin/bootstrap/button-groups.scss
  37. 0 168
      src/mol-app/skin/bootstrap/buttons.scss
  38. 0 617
      src/mol-app/skin/bootstrap/forms.scss
  39. 0 171
      src/mol-app/skin/bootstrap/input-groups.scss
  40. 0 66
      src/mol-app/skin/bootstrap/labels.scss
  41. 0 40
      src/mol-app/skin/bootstrap/mixins.scss
  42. 0 12
      src/mol-app/skin/bootstrap/mixins/background-variant.scss
  43. 0 18
      src/mol-app/skin/bootstrap/mixins/border-radius.scss
  44. 0 65
      src/mol-app/skin/bootstrap/mixins/buttons.scss
  45. 0 22
      src/mol-app/skin/bootstrap/mixins/clearfix.scss
  46. 0 88
      src/mol-app/skin/bootstrap/mixins/forms.scss
  47. 0 122
      src/mol-app/skin/bootstrap/mixins/grid.scss
  48. 0 33
      src/mol-app/skin/bootstrap/mixins/image.scss
  49. 0 12
      src/mol-app/skin/bootstrap/mixins/labels.scss
  50. 0 8
      src/mol-app/skin/bootstrap/mixins/opacity.scss
  51. 0 9
      src/mol-app/skin/bootstrap/mixins/tab-focus.scss
  52. 0 12
      src/mol-app/skin/bootstrap/mixins/text-emphasis.scss
  53. 0 8
      src/mol-app/skin/bootstrap/mixins/text-overflow.scss
  54. 0 222
      src/mol-app/skin/bootstrap/mixins/vendor-prefixes.scss
  55. 0 424
      src/mol-app/skin/bootstrap/normalize.scss
  56. 0 161
      src/mol-app/skin/bootstrap/scaffolding.scss
  57. 0 298
      src/mol-app/skin/bootstrap/type.scss
  58. 0 353
      src/mol-app/skin/bootstrap/variables.scss
  59. 0 24
      src/mol-app/skin/colors/blue.scss
  60. 0 22
      src/mol-app/skin/colors/dark.scss
  61. 0 30
      src/mol-app/skin/colors/light.scss
  62. 0 144
      src/mol-app/skin/components/controls-base.scss
  63. 0 197
      src/mol-app/skin/components/controls.scss
  64. 0 225
      src/mol-app/skin/components/entity.scss
  65. 0 28
      src/mol-app/skin/components/help.scss
  66. 0 131
      src/mol-app/skin/components/jobs.scss
  67. 0 97
      src/mol-app/skin/components/log.scss
  68. 0 69
      src/mol-app/skin/components/misc.scss
  69. 0 142
      src/mol-app/skin/components/panel.scss
  70. 0 9
      src/mol-app/skin/components/sequence-view.scss
  71. 0 164
      src/mol-app/skin/components/slider.scss
  72. 0 93
      src/mol-app/skin/components/viewport.scss
  73. BIN
      src/mol-app/skin/fonts/fontello.eot
  74. 0 442
      src/mol-app/skin/fonts/fontello.svg
  75. BIN
      src/mol-app/skin/fonts/fontello.ttf
  76. BIN
      src/mol-app/skin/fonts/fontello.woff
  77. BIN
      src/mol-app/skin/fonts/fontello.woff2
  78. 0 135
      src/mol-app/skin/icons.scss
  79. 0 29
      src/mol-app/skin/layout.scss
  80. 0 60
      src/mol-app/skin/layout/common.scss
  81. 0 81
      src/mol-app/skin/layout/landscape.scss
  82. 0 89
      src/mol-app/skin/layout/outside.scss
  83. 0 99
      src/mol-app/skin/layout/portrait.scss
  84. 0 45
      src/mol-app/skin/logo.scss
  85. 0 2
      src/mol-app/skin/molstar-blue.scss
  86. 0 2
      src/mol-app/skin/molstar-dark.scss
  87. 0 2
      src/mol-app/skin/molstar-light.scss
  88. 0 39
      src/mol-app/skin/ui.scss
  89. 0 78
      src/mol-app/skin/variables.scss
  90. 0 167
      src/mol-app/ui/controls/common.tsx
  91. 0 824
      src/mol-app/ui/controls/slider.tsx
  92. 0 113
      src/mol-app/ui/entity/tree.tsx
  93. 0 89
      src/mol-app/ui/layout.tsx
  94. 0 64
      src/mol-app/ui/misc/jobs.tsx
  95. 0 69
      src/mol-app/ui/misc/log.tsx
  96. 0 244
      src/mol-app/ui/transform/backbone.tsx
  97. 0 234
      src/mol-app/ui/transform/ball-and-stick.tsx
  98. 0 250
      src/mol-app/ui/transform/carbohydrate.tsx
  99. 0 278
      src/mol-app/ui/transform/cartoon.tsx
  100. 0 219
      src/mol-app/ui/transform/distance-restraint.tsx

+ 19 - 19
package-lock.json

@@ -475,7 +475,7 @@
     },
     "adjust-sourcemap-loader": {
       "version": "1.2.0",
-      "resolved": "http://registry.npmjs.org/adjust-sourcemap-loader/-/adjust-sourcemap-loader-1.2.0.tgz",
+      "resolved": "https://registry.npmjs.org/adjust-sourcemap-loader/-/adjust-sourcemap-loader-1.2.0.tgz",
       "integrity": "sha512-958oaHHVEXMvsY7v7cC5gEkNIcoaAVIhZ4mBReYVZJOTP9IgKmzLjIOhTtzpLMu+qriXvLsVjJ155EeInp45IQ==",
       "dev": true,
       "requires": {
@@ -969,7 +969,7 @@
     },
     "babel-plugin-istanbul": {
       "version": "4.1.6",
-      "resolved": "http://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-4.1.6.tgz",
+      "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-4.1.6.tgz",
       "integrity": "sha512-PWP9FQ1AhZhS01T/4qLSKoHGY/xvkZdVBGlKM/HuxxS3+sC66HhTNR7+MpbO/so/cz/wY94MeSWJuP1hXIPfwQ==",
       "dev": true,
       "requires": {
@@ -987,7 +987,7 @@
     },
     "babel-plugin-syntax-object-rest-spread": {
       "version": "6.13.0",
-      "resolved": "http://registry.npmjs.org/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz",
+      "resolved": "https://registry.npmjs.org/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz",
       "integrity": "sha1-/WU28rzhODb/o6VFjEkDpZe7O/U=",
       "dev": true
     },
@@ -1353,7 +1353,7 @@
     },
     "browserify-aes": {
       "version": "1.2.0",
-      "resolved": "http://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz",
+      "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz",
       "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==",
       "dev": true,
       "requires": {
@@ -1398,7 +1398,7 @@
     },
     "browserify-rsa": {
       "version": "4.0.1",
-      "resolved": "http://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz",
+      "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz",
       "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=",
       "dev": true,
       "requires": {
@@ -1450,7 +1450,7 @@
     },
     "buffer": {
       "version": "4.9.1",
-      "resolved": "http://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz",
+      "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz",
       "integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=",
       "dev": true,
       "requires": {
@@ -2098,7 +2098,7 @@
     },
     "create-hash": {
       "version": "1.2.0",
-      "resolved": "http://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz",
+      "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz",
       "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==",
       "dev": true,
       "requires": {
@@ -2111,7 +2111,7 @@
     },
     "create-hmac": {
       "version": "1.1.7",
-      "resolved": "http://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz",
+      "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz",
       "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==",
       "dev": true,
       "requires": {
@@ -2486,7 +2486,7 @@
     },
     "diffie-hellman": {
       "version": "5.0.3",
-      "resolved": "http://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz",
+      "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz",
       "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==",
       "dev": true,
       "requires": {
@@ -7249,7 +7249,7 @@
     },
     "parse-asn1": {
       "version": "5.1.1",
-      "resolved": "http://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.1.tgz",
+      "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.1.tgz",
       "integrity": "sha512-KPx7flKXg775zZpnp9SxJlz00gTd4BmJ2yJufSc44gMCRrRQ7NSzAcSJQfifuOLgW6bEi+ftrALtsgALeB2Adw==",
       "dev": true,
       "requires": {
@@ -7628,7 +7628,7 @@
     },
     "public-encrypt": {
       "version": "4.0.2",
-      "resolved": "http://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.2.tgz",
+      "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.2.tgz",
       "integrity": "sha512-4kJ5Esocg8X3h8YgJsKAuoesBgB7mqH3eowiDzMUPKiRDDE7E/BqqZD1hnTByIaAFiwAw246YEltSq7tdrOH0Q==",
       "dev": true,
       "requires": {
@@ -8216,7 +8216,7 @@
       "dependencies": {
         "convert-source-map": {
           "version": "0.3.5",
-          "resolved": "http://registry.npmjs.org/convert-source-map/-/convert-source-map-0.3.5.tgz",
+          "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-0.3.5.tgz",
           "integrity": "sha1-8dgClQr33SYxof6+BZZVDIarMZA=",
           "dev": true
         }
@@ -8602,7 +8602,7 @@
         },
         "minimist": {
           "version": "1.2.0",
-          "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+          "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
           "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
           "dev": true
         }
@@ -8901,7 +8901,7 @@
     },
     "sha.js": {
       "version": "2.4.11",
-      "resolved": "http://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz",
+      "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz",
       "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==",
       "dev": true,
       "requires": {
@@ -9468,7 +9468,7 @@
         },
         "readable-stream": {
           "version": "2.3.6",
-          "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
           "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
           "dev": true,
           "requires": {
@@ -10336,7 +10336,7 @@
       "dependencies": {
         "minimist": {
           "version": "1.2.0",
-          "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+          "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
           "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
           "dev": true
         }
@@ -11322,7 +11322,7 @@
         },
         "readable-stream": {
           "version": "2.3.6",
-          "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
           "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
           "dev": true,
           "requires": {
@@ -11364,7 +11364,7 @@
         },
         "readable-stream": {
           "version": "2.3.6",
-          "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
           "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
           "dev": true,
           "requires": {
@@ -11502,7 +11502,7 @@
     },
     "yargs": {
       "version": "11.1.0",
-      "resolved": "http://registry.npmjs.org/yargs/-/yargs-11.1.0.tgz",
+      "resolved": "https://registry.npmjs.org/yargs/-/yargs-11.1.0.tgz",
       "integrity": "sha512-NwW69J42EsCSanF8kyn5upxvjp5ds+t3+udGBeTbFnERA+lF541DDpMawzo4z6W/QrzNM18D+BPMiOBibnFV5A==",
       "dev": true,
       "requires": {

+ 3 - 4
src/apps/canvas/app.ts

@@ -11,8 +11,7 @@ import { BehaviorSubject } from 'rxjs';
 import { CifBlock } from 'mol-io/reader/cif';
 import { volumeFromCcp4 } from 'mol-model/volume/formats/ccp4';
 import { VolumeRepresentation } from 'mol-geo/representation/volume';
-import SurfaceVisual from 'mol-geo/representation/volume/surface';
-import { VolumeIsoValue } from 'mol-model/volume';
+import IsosurfaceVisual from 'mol-geo/representation/volume/isosurface';
 
 export class App {
     viewer: Viewer
@@ -88,9 +87,9 @@ export class App {
         const ccp4 = await getCcp4FromUrl(url)
         console.log(ccp4)
         const volume = await volumeFromCcp4(ccp4).run()
-        const volRepr = VolumeRepresentation(SurfaceVisual)
+        const volRepr = VolumeRepresentation(IsosurfaceVisual)
         await volRepr.createOrUpdate({
-            isoValue: VolumeIsoValue.relative(volume.dataStats, 1)
+            isoValue: 1
         }, volume).run()
         this.viewer.add(volRepr)
         console.log('volRepr', volRepr)

+ 49 - 0
src/apps/canvas/component/representation.tsx

@@ -0,0 +1,49 @@
+/**
+ * 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 Viewer from 'mol-view/viewer';
+import { App } from '../app';
+import { Params } from 'mol-view/parameter';
+import { Representation } from 'mol-geo/representation';
+import { ParametersComponent } from 'mol-app/component/parameters';
+
+export interface RepresentationComponentProps {
+    app: App
+    viewer: Viewer
+    repr: Representation<Params>
+}
+
+export interface RepresentationComponentState {
+
+}
+
+export class RepresentationComponent extends React.Component<RepresentationComponentProps, RepresentationComponentState> {
+
+    async onChange(k: string, v: any) {
+        await this.props.app.runTask(this.props.repr.createOrUpdate({ [k]: v }).run(), 'Representation Update')
+        this.props.viewer.add(this.props.repr)
+        this.props.viewer.requestDraw(true)
+    }
+
+    render() {
+        const { repr } = this.props
+        // const ct = ColorTheme(colorTheme)
+
+        return <div>
+            <div>
+                <h4>{repr.label}</h4>
+            </div>
+            <div>
+                <ParametersComponent
+                    params={repr.params}
+                    values={repr.props}
+                    onChange={(k, v) => this.onChange(k as string, v)}
+                />
+            </div>
+        </div>;
+    }
+}

+ 0 - 261
src/apps/canvas/component/structure-representation.tsx

@@ -1,261 +0,0 @@
-/**
- * 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 { StructureRepresentation, StructureProps } from 'mol-geo/representation/structure';
-import Viewer from 'mol-view/viewer';
-import { ColorThemeProps, ColorThemeName, ColorThemeNames, ColorTheme } from 'mol-view/theme/color';
-import { Color } from 'mol-util/color';
-import { Progress } from 'mol-task';
-import { VisualQuality, VisualQualityNames } from 'mol-geo/geometry/geometry';
-import { SizeThemeProps } from 'mol-view/theme/size';
-import { App } from '../app';
-
-export interface StructureRepresentationComponentProps {
-    app: App
-    viewer: Viewer
-    representation: StructureRepresentation<StructureProps>
-}
-
-export interface StructureRepresentationComponentState {
-    label: string
-    visible: boolean
-    alpha: number
-    quality: VisualQuality
-    colorTheme: ColorThemeProps
-    sizeTheme: SizeThemeProps
-    depthMask: boolean
-
-    flatShaded?: boolean
-    resolutionFactor?: number
-    radiusOffset?: number
-    smoothness?: number
-    pointSizeAttenuation?: boolean
-    pointFilledCircle?: boolean
-    pointEdgeBleach?: number
-
-    visuals?: { [k: string]: boolean }
-}
-
-export class StructureRepresentationComponent extends React.Component<StructureRepresentationComponentProps, StructureRepresentationComponentState> {
-    state = this.stateFromRepresentation(this.props.representation)
-
-    private stateFromRepresentation(repr: StructureRepresentation<StructureProps>) {
-        return {
-            label: repr.label,
-            visible: repr.props.visible,
-            alpha: repr.props.alpha,
-            quality: repr.props.quality,
-            colorTheme: repr.props.colorTheme,
-            sizeTheme: repr.props.sizeTheme,
-            depthMask: repr.props.depthMask,
-
-            flatShaded: (repr.props as any).flatShaded,
-            resolutionFactor: (repr.props as any).resolutionFactor,
-            radiusOffset: (repr.props as any).radiusOffset,
-            smoothness: (repr.props as any).smoothness,
-            pointSizeAttenuation: (repr.props as any).pointSizeAttenuation,
-            pointFilledCircle: (repr.props as any).pointFilledCircle,
-            pointEdgeBleach: (repr.props as any).pointEdgeBleach,
-
-            visuals: (repr.props as any).visuals,
-        }
-    }
-
-    componentWillMount() {
-        this.setState(this.stateFromRepresentation(this.props.representation))
-    }
-
-    async update(state: Partial<StructureRepresentationComponentState>) {
-        const repr = this.props.representation
-        const props: Partial<StructureProps> = {}
-
-        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
-        if (state.sizeTheme !== undefined) props.sizeTheme = state.sizeTheme
-        if (state.depthMask !== undefined) props.depthMask = state.depthMask
-
-        if (state.flatShaded !== undefined) (props as any).flatShaded = state.flatShaded
-        if (state.resolutionFactor !== undefined) (props as any).resolutionFactor = state.resolutionFactor
-        if (state.radiusOffset !== undefined) (props as any).radiusOffset = state.radiusOffset
-        if (state.smoothness !== undefined) (props as any).smoothness = state.smoothness
-        if (state.pointSizeAttenuation !== undefined) (props as any).pointSizeAttenuation = state.pointSizeAttenuation
-        if (state.pointFilledCircle !== undefined) (props as any).pointFilledCircle = state.pointFilledCircle
-        if (state.pointEdgeBleach !== undefined) (props as any).pointEdgeBleach = state.pointEdgeBleach
-
-        if (state.visuals !== undefined) (props as any).visuals = state.visuals
-
-        await this.props.app.runTask(repr.createOrUpdate(props).run(
-            progress => console.log(Progress.format(progress))
-        ), 'Create/update representation')
-        this.props.viewer.add(repr)
-        this.props.viewer.draw(true)
-
-        this.setState(this.stateFromRepresentation(repr))
-    }
-
-    render() {
-        const { label, visible, quality, alpha, colorTheme, depthMask } = this.state
-        const ct = ColorTheme(colorTheme)
-
-        return <div>
-            <div>
-                <h4>{label}</h4>
-            </div>
-            <div>
-                <div>
-                    <span>Visible </span>
-                    <button onClick={(e) => this.update({ visible: !visible }) }>
-                        {visible ? 'Hide' : 'Show'}
-                    </button>
-                </div>
-                { this.state.visuals !== undefined ? <div>
-                    <span>Visuals: </span>
-                    { Object.keys(this.state.visuals).map(k => {
-                        return <span key={k}>{k} <input
-                            type='checkbox'
-                            checked={this.state.visuals[k]}
-                            onChange={e => {
-                                this.update({ visuals: { ...this.state.visuals, [k]: !!e.target.checked } })
-                            }}
-                        ></input> </span>
-                    }) }
-                </div> : '' }
-                <div>
-                    <span>Depth Mask </span>
-                    <button onClick={(e) => this.update({ depthMask: !depthMask }) }>
-                        {depthMask ? 'Deactivate' : 'Activate'}
-                    </button>
-                </div>
-                { this.state.flatShaded !== undefined ? <div>
-                    <span>Flat Shaded </span>
-                    <button onClick={(e) => this.update({ flatShaded: !this.state.flatShaded }) }>
-                        {this.state.flatShaded ? 'Deactivate' : 'Activate'}
-                    </button>
-                </div> : '' }
-                <div>
-                    <span>Quality </span>
-                    <select value={quality} onChange={e => this.update({ quality: e.target.value as VisualQuality }) }>
-                        {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>
-                { this.state.resolutionFactor !== undefined ? <div>
-                    <span>Resolution Factor </span>
-                    <input type='range'
-                        defaultValue={this.state.resolutionFactor.toString()}
-                        min='4'
-                        max='9'
-                        step='1'
-                        onChange={(e) => this.update({ resolutionFactor: parseInt(e.currentTarget.value) })}
-                    >
-                    </input>
-                </div> : '' }
-                { this.state.smoothness !== undefined ? <div>
-                    <span>Smoothness </span>
-                    <input type='range'
-                        defaultValue={this.state.smoothness.toString()}
-                        min='1'
-                        max='3'
-                        step='0.1'
-                        onChange={e => this.update({ smoothness: parseFloat(e.currentTarget.value) })}
-                    >
-                    </input>
-                </div> : '' }
-                { this.state.radiusOffset !== undefined ? <div>
-                    <span>Radius Offset </span>
-                    <input type='range'
-                        defaultValue={this.state.radiusOffset.toString()}
-                        min='0'
-                        max='4'
-                        step='0.1'
-                        onChange={e => this.update({ radiusOffset: parseFloat(e.currentTarget.value) })}
-                    >
-                    </input>
-                </div> : '' }
-                { this.state.pointSizeAttenuation !== undefined ? <div>
-                    <span>Size Attenuation </span>
-                    <button onClick={e => this.update({ pointSizeAttenuation: !this.state.pointSizeAttenuation }) }>
-                        {this.state.pointSizeAttenuation ? 'Deactivate' : 'Activate'}
-                    </button>
-                </div> : '' }
-                { this.state.pointFilledCircle !== undefined ? <div>
-                    <span>Filled Circle </span>
-                    <button onClick={e => this.update({ pointFilledCircle: !this.state.pointFilledCircle }) }>
-                        {this.state.pointFilledCircle ? 'Deactivate' : 'Activate'}
-                    </button>
-                </div> : '' }
-                { this.state.pointEdgeBleach !== undefined ? <div>
-                    <span>Edge Bleach </span>
-                    <input type='range'
-                        defaultValue={this.state.pointEdgeBleach.toString()}
-                        min='0'
-                        max='1'
-                        step='0.05'
-                        onInput={e => this.update({ pointEdgeBleach: parseFloat(e.currentTarget.value) })}
-                    >
-                    </input>
-                </div> : '' }
-                { this.state.sizeTheme !== undefined && this.state.sizeTheme.name === 'uniform' ? <div>
-                    <span>Uniform Size </span>
-                    <input type='range'
-                        defaultValue={this.state.sizeTheme.value!.toString()}
-                        min='0'
-                        max='10'
-                        step='0.1'
-                        onInput={e => this.update({
-                            sizeTheme: { name: 'uniform', value: 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 } }) }>
-                        {ColorThemeNames.map(name => <option key={name} value={name}>{name}</option>)}
-                    </select>
-                    {ct.description ? <div><i>{ct.description}</i></div> : ''}
-                    {
-                        ct.legend && ct.legend.kind === 'scale-legend'
-                            ? <div
-                                style={{
-                                    width: '100%',
-                                    height: '30px',
-                                    background: `linear-gradient(to right, ${ct.legend.colors.map(c => Color.toStyle(c)).join(', ')})`
-                                }}
-                            >
-                                <span style={{float: 'left', padding: '6px', color: 'white', fontWeight: 'bold', backgroundColor: 'rgba(0, 0, 0, 0.2)'}}>{ct.legend.minLabel}</span>
-                                <span style={{float: 'right', padding: '6px', color: 'white', fontWeight: 'bold', backgroundColor: 'rgba(0, 0, 0, 0.2)'}}>{ct.legend.maxLabel}</span>
-                            </div>
-                        : ct.legend && ct.legend.kind === 'table-legend'
-                            ? <div>
-                                {ct.legend.table.map((value, i) => {
-                                    const [name, color] = value
-                                    return <div key={i} style={{minWidth: '60px', marginRight: '5px', display: 'inline-block'}}>
-                                        <div style={{width: '30px', height: '20px', backgroundColor: Color.toStyle(color), display: 'inline-block'}}></div>
-                                        {name}
-                                    </div>
-                                })}
-                            </div>
-                        : ''
-                    }
-                </div>
-            </div>
-        </div>;
-    }
-}

+ 4 - 3
src/apps/canvas/component/structure-view.tsx

@@ -7,7 +7,8 @@
 import * as React from 'react'
 import { StructureView } from '../structure-view';
 import { StructureRepresentation } from 'mol-geo/representation/structure';
-import { StructureRepresentationComponent } from './structure-representation';
+import { RepresentationComponent } from './representation';
+import { Representation } from 'mol-geo/representation';
 
 // export function FileInput (props: {
 //     accept: string
@@ -182,8 +183,8 @@ export class StructureViewComponent extends React.Component<StructureViewCompone
                     { Object.keys(structureRepresentations).map((k, i) => {
                         if (active[k]) {
                             return <div key={i}>
-                                <StructureRepresentationComponent
-                                    representation={structureRepresentations[k]}
+                                <RepresentationComponent
+                                    repr={structureRepresentations[k] as Representation<any>}
                                     viewer={structureView.viewer}
                                     app={structureView.app}
                                 />

+ 0 - 245
src/apps/canvas/component/volume-representation.tsx

@@ -1,245 +0,0 @@
-/**
- * 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 Viewer from 'mol-view/viewer';
-import { ColorThemeProps, ColorThemeName, ColorThemeNames, ColorTheme } from 'mol-view/theme/color';
-import { Color } from 'mol-util/color';
-import { Progress } from 'mol-task';
-import { VisualQuality, VisualQualityNames } from 'mol-geo/geometry/geometry';
-import { SizeThemeProps } from 'mol-view/theme/size';
-import { App } from '../app';
-import { VolumeRepresentation, VolumeProps } from 'mol-geo/representation/volume';
-
-export interface VolumeRepresentationComponentProps {
-    app: App
-    viewer: Viewer
-    representation: VolumeRepresentation<VolumeProps>
-}
-
-export interface VolumeRepresentationComponentState {
-    label: string
-    visible: boolean
-    alpha: number
-    quality: VisualQuality
-    colorTheme: ColorThemeProps
-    depthMask: boolean
-
-    flatShaded?: boolean
-    resolutionFactor?: number
-    radiusOffset?: number
-    smoothness?: number
-    pointSizeAttenuation?: boolean
-    pointFilledCircle?: boolean
-    pointEdgeBleach?: number
-
-    visuals?: { [k: string]: boolean }
-}
-
-export class VolumeRepresentationComponent extends React.Component<VolumeRepresentationComponentProps, VolumeRepresentationComponentState> {
-    state = this.stateFromRepresentation(this.props.representation)
-
-    private stateFromRepresentation(repr: VolumeRepresentation<VolumeProps>) {
-        return {
-            label: repr.label,
-            visible: repr.props.visible,
-            alpha: repr.props.alpha,
-            quality: repr.props.quality,
-            colorTheme: repr.props.colorTheme,
-            depthMask: repr.props.depthMask,
-
-            flatShaded: (repr.props as any).flatShaded,
-            resolutionFactor: (repr.props as any).resolutionFactor,
-            radiusOffset: (repr.props as any).radiusOffset,
-            smoothness: (repr.props as any).smoothness,
-            pointSizeAttenuation: (repr.props as any).pointSizeAttenuation,
-            pointFilledCircle: (repr.props as any).pointFilledCircle,
-            pointEdgeBleach: (repr.props as any).pointEdgeBleach,
-
-            visuals: (repr.props as any).visuals,
-        }
-    }
-
-    componentWillMount() {
-        this.setState(this.stateFromRepresentation(this.props.representation))
-    }
-
-    async update(state: Partial<VolumeRepresentationComponentState>) {
-        const repr = this.props.representation
-        const props: Partial<VolumeProps> = {}
-
-        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
-        if (state.depthMask !== undefined) props.depthMask = state.depthMask
-
-        if (state.flatShaded !== undefined) (props as any).flatShaded = state.flatShaded
-        if (state.resolutionFactor !== undefined) (props as any).resolutionFactor = state.resolutionFactor
-        if (state.radiusOffset !== undefined) (props as any).radiusOffset = state.radiusOffset
-        if (state.smoothness !== undefined) (props as any).smoothness = state.smoothness
-        if (state.pointSizeAttenuation !== undefined) (props as any).pointSizeAttenuation = state.pointSizeAttenuation
-        if (state.pointFilledCircle !== undefined) (props as any).pointFilledCircle = state.pointFilledCircle
-        if (state.pointEdgeBleach !== undefined) (props as any).pointEdgeBleach = state.pointEdgeBleach
-
-        if (state.visuals !== undefined) (props as any).visuals = state.visuals
-
-        await this.props.app.runTask(repr.createOrUpdate(props).run(
-            progress => console.log(Progress.format(progress))
-        ), 'Create/update representation')
-        this.props.viewer.add(repr)
-        this.props.viewer.draw(true)
-
-        this.setState(this.stateFromRepresentation(repr))
-    }
-
-    render() {
-        const { label, visible, quality, alpha, colorTheme, depthMask } = this.state
-        const ct = ColorTheme(colorTheme)
-
-        return <div>
-            <div>
-                <h4>{label}</h4>
-            </div>
-            <div>
-                <div>
-                    <span>Visible </span>
-                    <button onClick={(e) => this.update({ visible: !visible }) }>
-                        {visible ? 'Hide' : 'Show'}
-                    </button>
-                </div>
-                { this.state.visuals !== undefined ? <div>
-                    <span>Visuals: </span>
-                    { Object.keys(this.state.visuals).map(k => {
-                        return <span key={k}>{k} <input
-                            type='checkbox'
-                            checked={this.state.visuals[k]}
-                            onChange={e => {
-                                this.update({ visuals: { ...this.state.visuals, [k]: !!e.target.checked } })
-                            }}
-                        ></input> </span>
-                    }) }
-                </div> : '' }
-                <div>
-                    <span>Depth Mask </span>
-                    <button onClick={(e) => this.update({ depthMask: !depthMask }) }>
-                        {depthMask ? 'Deactivate' : 'Activate'}
-                    </button>
-                </div>
-                { this.state.flatShaded !== undefined ? <div>
-                    <span>Flat Shaded </span>
-                    <button onClick={(e) => this.update({ flatShaded: !this.state.flatShaded }) }>
-                        {this.state.flatShaded ? 'Deactivate' : 'Activate'}
-                    </button>
-                </div> : '' }
-                <div>
-                    <span>Quality </span>
-                    <select value={quality} onChange={e => this.update({ quality: e.target.value as VisualQuality }) }>
-                        {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>
-                { this.state.resolutionFactor !== undefined ? <div>
-                    <span>Resolution Factor </span>
-                    <input type='range'
-                        defaultValue={this.state.resolutionFactor.toString()}
-                        min='4'
-                        max='9'
-                        step='1'
-                        onChange={(e) => this.update({ resolutionFactor: parseInt(e.currentTarget.value) })}
-                    >
-                    </input>
-                </div> : '' }
-                { this.state.smoothness !== undefined ? <div>
-                    <span>Smoothness </span>
-                    <input type='range'
-                        defaultValue={this.state.smoothness.toString()}
-                        min='1'
-                        max='3'
-                        step='0.1'
-                        onChange={e => this.update({ smoothness: parseFloat(e.currentTarget.value) })}
-                    >
-                    </input>
-                </div> : '' }
-                { this.state.radiusOffset !== undefined ? <div>
-                    <span>Radius Offset </span>
-                    <input type='range'
-                        defaultValue={this.state.radiusOffset.toString()}
-                        min='0'
-                        max='4'
-                        step='0.1'
-                        onChange={e => this.update({ radiusOffset: parseFloat(e.currentTarget.value) })}
-                    >
-                    </input>
-                </div> : '' }
-                { this.state.pointSizeAttenuation !== undefined ? <div>
-                    <span>Size Attenuation </span>
-                    <button onClick={e => this.update({ pointSizeAttenuation: !this.state.pointSizeAttenuation }) }>
-                        {this.state.pointSizeAttenuation ? 'Deactivate' : 'Activate'}
-                    </button>
-                </div> : '' }
-                { this.state.pointFilledCircle !== undefined ? <div>
-                    <span>Filled Circle </span>
-                    <button onClick={e => this.update({ pointFilledCircle: !this.state.pointFilledCircle }) }>
-                        {this.state.pointFilledCircle ? 'Deactivate' : 'Activate'}
-                    </button>
-                </div> : '' }
-                { this.state.pointEdgeBleach !== undefined ? <div>
-                    <span>Edge Bleach </span>
-                    <input type='range'
-                        defaultValue={this.state.pointEdgeBleach.toString()}
-                        min='0'
-                        max='1'
-                        step='0.05'
-                        onInput={e => this.update({ pointEdgeBleach: 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 } }) }>
-                        {ColorThemeNames.map(name => <option key={name} value={name}>{name}</option>)}
-                    </select>
-                    {ct.description ? <div><i>{ct.description}</i></div> : ''}
-                    {
-                        ct.legend && ct.legend.kind === 'scale-legend'
-                            ? <div
-                                style={{
-                                    width: '100%',
-                                    height: '30px',
-                                    background: `linear-gradient(to right, ${ct.legend.colors.map(c => Color.toStyle(c)).join(', ')})`
-                                }}
-                            >
-                                <span style={{float: 'left', padding: '6px', color: 'white', fontWeight: 'bold', backgroundColor: 'rgba(0, 0, 0, 0.2)'}}>{ct.legend.minLabel}</span>
-                                <span style={{float: 'right', padding: '6px', color: 'white', fontWeight: 'bold', backgroundColor: 'rgba(0, 0, 0, 0.2)'}}>{ct.legend.maxLabel}</span>
-                            </div>
-                        : ct.legend && ct.legend.kind === 'table-legend'
-                            ? <div>
-                                {ct.legend.table.map((value, i) => {
-                                    const [name, color] = value
-                                    return <div key={i} style={{minWidth: '60px', marginRight: '5px', display: 'inline-block'}}>
-                                        <div style={{width: '30px', height: '20px', backgroundColor: Color.toStyle(color), display: 'inline-block'}}></div>
-                                        {name}
-                                    </div>
-                                })}
-                            </div>
-                        : ''
-                    }
-                </div>
-            </div>
-        </div>;
-    }
-}

+ 1 - 1
src/apps/canvas/index.ts

@@ -23,4 +23,4 @@ const assemblyId = urlQueryParameter('assembly')
 const pdbId = urlQueryParameter('pdb')
 if (pdbId) app.loadPdbIdOrMmcifUrl(pdbId, { assemblyId })
 
-app.loadCcp4File()
+// app.loadCcp4File()

+ 2 - 2
src/apps/canvas/structure-view.ts

@@ -24,7 +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';
+import { MolecularSurfaceRepresentation } from 'mol-geo/representation/structure/representation/molecular-surface';
 import { App } from './app';
 import { Progress } from 'mol-task';
 
@@ -81,7 +81,7 @@ export async function StructureView(app: App, viewer: Viewer, models: ReadonlyAr
 
     const structureRepresentations: { [k: string]: StructureRepresentation<any> } = {
         cartoon: CartoonRepresentation(),
-        surface: SurfaceRepresentation(),
+        surface: MolecularSurfaceRepresentation(),
         point: PointRepresentation(),
         ballAndStick: BallAndStickRepresentation(),
         carbohydrate: CarbohydrateRepresentation(),

+ 1 - 1
src/apps/structure-info/volume.ts

@@ -13,7 +13,7 @@ import { downloadCif } from './helpers'
 import CIF from 'mol-io/reader/cif'
 import { DensityServer_Data_Database } from 'mol-io/reader/cif/schema/density-server';
 import { Table } from 'mol-data/db';
-import { computeVolumeSurface } from 'mol-geo/representation/volume/surface';
+import { computeVolumeSurface } from 'mol-geo/representation/volume/isosurface';
 import { StringBuilder } from 'mol-util';
 
 require('util.promisify').shim();

+ 0 - 13
src/apps/viewer/index.html

@@ -1,13 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-    <head>
-        <meta charset="utf-8" />
-        <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
-        <title>Mol* Viewer</title>
-        <link href='./app.css', rel="stylesheet">
-    </head>
-    <body>
-        <div id="app"></div>
-        <script type="text/javascript" src="./index.js"></script>
-    </body>
-</html>

+ 0 - 107
src/apps/viewer/index.tsx

@@ -1,107 +0,0 @@
-/**
- * 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 * as ReactDOM from 'react-dom'
-
-import './index.html'
-import 'mol-app/skin/molstar-light.scss'
-
-import { Context } from 'mol-app/context/context';
-import { Viewport } from 'mol-app/ui/visualization/viewport'
-import { makeEmptyTargets, LayoutRegion } from 'mol-app/controller/layout';
-import { Layout } from 'mol-app/ui/layout';
-import { LogController } from 'mol-app/controller/misc/log';
-import { Log } from 'mol-app/ui/misc/log';
-import { JobsController } from 'mol-app/controller/misc/jobs';
-import { BackgroundJobs, Overlay } from 'mol-app/ui/misc/jobs';
-import { EntityTree } from 'mol-app/ui/entity/tree';
-import { EntityTreeController } from 'mol-app/controller/entity/tree';
-import { TransformListController } from 'mol-app/controller/transform/list';
-import { TransformList } from 'mol-app/ui/transform/list';
-import { SequenceView } from 'mol-app/ui/visualization/sequence-view';
-import { InteractivityEvents } from 'mol-app/event/basic';
-import { MarkerAction } from 'mol-geo/geometry/marker-data';
-import { EveryLoci } from 'mol-model/loci';
-
-const elm = document.getElementById('app')
-if (!elm) throw new Error('Can not find element with id "app".')
-
-const ctx = new Context()
-const targets = makeEmptyTargets();
-
-targets[LayoutRegion.Main].components.push({
-    key: 'molstar-internal-viewport',
-    controller: ctx.viewport,
-    region: LayoutRegion.Main,
-    view: Viewport,
-    isStatic: true
-});
-
-targets[LayoutRegion.Bottom].components.push({
-    key: 'molstar-log',
-    controller: new LogController(ctx),
-    region: LayoutRegion.Bottom,
-    view: Log,
-    isStatic: true
-});
-
-targets[LayoutRegion.Top].components.push({
-    key: 'molstar-sequence-view',
-    controller: ctx.components.sequenceView,
-    region: LayoutRegion.Top,
-    view: SequenceView,
-    isStatic: true
-});
-
-targets[LayoutRegion.Main].components.push({
-    key: 'molstar-background-jobs',
-    controller: new JobsController(ctx, 'Background'),
-    region: LayoutRegion.Main,
-    view: BackgroundJobs,
-    isStatic: true
-});
-
-targets[LayoutRegion.Root].components.push({
-    key: 'molstar-overlay',
-    controller: new JobsController(ctx, 'Normal'),
-    region: LayoutRegion.Root,
-    view: Overlay,
-    isStatic: true
-});
-
-targets[LayoutRegion.Right].components.push({
-    key: 'molstar-transform-list',
-    controller: new TransformListController(ctx),
-    region: LayoutRegion.Right,
-    view: TransformList,
-    isStatic: false
-});
-
-targets[LayoutRegion.Left].components.push({
-    key: 'molstar-entity-tree',
-    controller: new EntityTreeController(ctx),
-    region: LayoutRegion.Left,
-    view: EntityTree,
-    isStatic: true
-});
-
-ctx.createLayout(targets, elm)
-ctx.layout.setState({
-    isExpanded: true,
-    hideControls: false,
-    collapsedControlsLayout: 0
-})
-// ctx.viewport.setState()
-
-ctx.dispatcher.getStream(InteractivityEvents.HighlightLoci).subscribe(event => {
-    ctx.stage.viewer.mark(EveryLoci, MarkerAction.RemoveHighlight)
-    if (event && event.data) {
-        ctx.stage.viewer.mark(event.data, MarkerAction.Highlight)
-    }
-})
-
-ReactDOM.render(React.createElement(Layout, { controller: ctx.layout }), elm);

+ 56 - 0
src/mol-app/component/color-theme.tsx

@@ -0,0 +1,56 @@
+/**
+ * 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 { ColorTheme } from 'mol-view/theme/color';
+import { Color } from 'mol-util/color';
+
+export interface ColorThemeComponentProps {
+    colorTheme: ColorTheme
+}
+
+export interface ColorThemeComponentState {
+    
+}
+
+export class ColorThemeComponent extends React.Component<ColorThemeComponentProps, ColorThemeComponentState> {
+    state = {
+        
+    }
+
+    render() {
+        const ct = this.props.colorTheme
+        return <div>
+            <span>Color Theme </span>
+
+            {ct.description ? <div><i>{ct.description}</i></div> : ''}
+            {
+                ct.legend && ct.legend.kind === 'scale-legend'
+                    ? <div
+                        style={{
+                            width: '100%',
+                            height: '30px',
+                            background: `linear-gradient(to right, ${ct.legend.colors.map(c => Color.toStyle(c)).join(', ')})`
+                        }}
+                    >
+                        <span style={{float: 'left', padding: '6px', color: 'white', fontWeight: 'bold', backgroundColor: 'rgba(0, 0, 0, 0.2)'}}>{ct.legend.minLabel}</span>
+                        <span style={{float: 'right', padding: '6px', color: 'white', fontWeight: 'bold', backgroundColor: 'rgba(0, 0, 0, 0.2)'}}>{ct.legend.maxLabel}</span>
+                    </div>
+                : ct.legend && ct.legend.kind === 'table-legend'
+                    ? <div>
+                        {ct.legend.table.map((value, i) => {
+                            const [name, color] = value
+                            return <div key={i} style={{minWidth: '60px', marginRight: '5px', display: 'inline-block'}}>
+                                <div style={{width: '30px', height: '20px', backgroundColor: Color.toStyle(color), display: 'inline-block'}}></div>
+                                {name}
+                            </div>
+                        })}
+                    </div>
+                : ''
+            }
+        </div>;
+    }
+}

+ 38 - 0
src/mol-app/component/parameter/boolean.tsx

@@ -0,0 +1,38 @@
+/**
+ * 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 { BooleanParam } from 'mol-view/parameter';
+
+export interface BooleanParamComponentProps {
+    param: BooleanParam
+    value: boolean
+    onChange(v: boolean): void
+}
+
+export interface BooleanParamComponentState {
+    value: boolean
+}
+
+export class BooleanParamComponent extends React.Component<BooleanParamComponentProps, BooleanParamComponentState> {
+    state = {
+        value: this.props.value
+    }
+
+    onChange(value: boolean) {
+        this.setState({ value })
+        this.props.onChange(value)
+    }
+
+    render() {
+        return <div>
+            <span>{this.props.param.label} </span>
+            <button onClick={e => this.onChange(!this.state.value) }>
+                {this.state.value ? 'Off' : 'On'}
+            </button>
+        </div>;
+    }
+}

+ 44 - 0
src/mol-app/component/parameter/number.tsx

@@ -0,0 +1,44 @@
+/**
+ * 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 { NumberParam } from 'mol-view/parameter';
+
+export interface NumberParamComponentProps {
+    param: NumberParam
+    value: number
+    onChange(v: number): void
+}
+
+export interface NumberParamComponentState {
+    value: number
+}
+
+export class NumberParamComponent extends React.Component<NumberParamComponentProps, NumberParamComponentState> {
+    state = {
+        value: this.props.value
+    }
+
+    onChange(valueStr: string) {
+        const value = Number.isInteger(this.props.param.step) ? parseInt(valueStr) : parseFloat(valueStr)
+        this.setState({ value })
+        this.props.onChange(value)
+    }
+
+    render() {
+        return <div>
+            <span>{this.props.param.label} </span>
+            <input type='range'
+                value={this.state.value}
+                min={this.props.param.min}
+                max={this.props.param.max}
+                step={this.props.param.step}
+                onChange={e => this.onChange(e.currentTarget.value)}
+            >
+            </input>
+        </div>;
+    }
+}

+ 44 - 0
src/mol-app/component/parameter/range.tsx

@@ -0,0 +1,44 @@
+/**
+ * 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 { RangeParam } from 'mol-view/parameter';
+
+export interface RangeParamComponentProps {
+    param: RangeParam
+    value: number
+    onChange(v: number): void
+}
+
+export interface RangeParamComponentState {
+    value: number
+}
+
+export class RangeParamComponent extends React.Component<RangeParamComponentProps, RangeParamComponentState> {
+    state = {
+        value: this.props.value
+    }
+
+    onChange(valueStr: string) {
+        const value = Number.isInteger(this.props.param.step) ? parseInt(valueStr) : parseFloat(valueStr)
+        this.setState({ value })
+        this.props.onChange(value)
+    }
+
+    render() {
+        return <div>
+            <span>{this.props.param.label} </span>
+            <input type='range'
+                value={this.state.value}
+                min={this.props.param.min}
+                max={this.props.param.max}
+                step={this.props.param.step}
+                onChange={e => this.onChange(e.currentTarget.value)}
+            >
+            </input>
+        </div>;
+    }
+}

+ 41 - 0
src/mol-app/component/parameter/select.tsx

@@ -0,0 +1,41 @@
+/**
+ * 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 { SelectParam } from 'mol-view/parameter';
+
+export interface SelectParamComponentProps<T extends string> {
+    param: SelectParam<T>
+    value: T
+    onChange(v: T): void
+}
+
+export interface SelectParamComponentState<T extends string> {
+    value: T
+}
+
+export class SelectParamComponent<T extends string> extends React.Component<SelectParamComponentProps<T>, SelectParamComponentState<T>> {
+    state = {
+        value: this.props.value
+    }
+
+    onChange(value: T) {
+        this.setState({ value })
+        this.props.onChange(value)
+    }
+
+    render() {
+        return <div>
+            <span>{this.props.param.label} </span>
+            <select value={this.state.value} onChange={e => this.onChange(e.target.value as T) }>
+                {this.props.param.options.map(v => {
+                    const [value, label] = v
+                    return <option key={label} value={value}>{label}</option>
+                })}
+            </select>
+        </div>;
+    }
+}

+ 52 - 0
src/mol-app/component/parameters.tsx

@@ -0,0 +1,52 @@
+/**
+ * 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 { Param, Params } from 'mol-view/parameter';
+import { BooleanParamComponent } from './parameter/boolean';
+import { NumberParamComponent } from './parameter/number';
+import { RangeParamComponent } from './parameter/range';
+import { SelectParamComponent } from './parameter/select';
+
+interface ParametersProps<P extends Params> {
+    params: P
+    values: { [k in keyof P]: P[k]['defaultValue'] }
+    onChange<K extends keyof P>(k: K, v: P[K]['defaultValue']): void
+}
+
+type ParametersState = {}
+
+function getParamComponent<P extends Param>(p: Param, value: P['defaultValue'], onChange: (v: P['defaultValue']) => void) {
+    switch (p.type) {
+        case 'boolean':
+            return <BooleanParamComponent param={p} value={value} onChange={onChange} />
+        case 'number':
+            return <NumberParamComponent param={p} value={value} onChange={onChange} />
+        case 'range':
+            return <RangeParamComponent param={p} value={value} onChange={onChange} />
+        case 'select':
+            return <SelectParamComponent param={p} value={value} onChange={onChange} />
+    }
+    return ''
+}
+
+export class ParametersComponent<P extends Params> extends React.Component<ParametersProps<P>, ParametersState> {
+    onChange(k: string, value: any) {
+        this.props.onChange(k, value)
+    }
+
+    render() {
+        return <div>
+            { Object.keys(this.props.params).map(k => {
+                const param = this.props.params[k]
+                const value = this.props.values[k]
+                return <div key={k}>
+                    {getParamComponent(param, value, v => this.onChange(k, v))}
+                </div>
+            })}
+        </div>;
+    }
+}

+ 81 - 0
src/mol-app/component/sequence.tsx

@@ -0,0 +1,81 @@
+// /**
+//  * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
+//  *
+//  * @author David Sehnal <david.sehnal@gmail.com>
+//  */
+
+// import * as React from 'react'
+// import { Structure, StructureSequence, Queries, StructureSelection, StructureProperties, StructureQuery } from 'mol-model/structure';
+// import { EmptyLoci } from 'mol-model/loci';
+
+// export class SequenceView extends View<SequenceViewController, {}, {}> {
+//     render() {
+//         const s = this.controller.latestState.structure;
+//         if (!s) return <div className='molstar-sequence-view-wrap'>No structure available.</div>;
+
+//         const seqs = s.models[0].sequence.sequences;
+//         return <div className='molstar-sequence-view-wrap'>
+//             {seqs.map((seq, i) => <EntitySequence key={i} ctx={this.controller.context} seq={seq} structure={s} /> )}
+//         </div>;
+//     }
+// }
+
+// function createQuery(entityId: string, label_seq_id: number) {
+//     return Queries.generators.atoms({
+//         entityTest: ctx => StructureProperties.entity.id(ctx.element) === entityId,
+//         residueTest: ctx => StructureProperties.residue.label_seq_id(ctx.element) === label_seq_id
+//     });
+// }
+
+// // TODO: this is really ineffective and should be done using a canvas.
+// class EntitySequence extends React.Component<{ ctx: Context, seq: StructureSequence.Entity, structure: Structure }> {
+
+//     raiseInteractityEvent(seqId?: number) {
+//         if (typeof seqId === 'undefined') {
+//             InteractivityEvents.HighlightLoci.dispatch(this.props.ctx, EmptyLoci);
+//             return;
+//         }
+
+//         const query = createQuery(this.props.seq.entityId, seqId);
+//         const loci = StructureSelection.toLoci(StructureQuery.run(query, this.props.structure));
+//         if (loci.elements.length === 0) InteractivityEvents.HighlightLoci.dispatch(this.props.ctx, EmptyLoci);
+//         else InteractivityEvents.HighlightLoci.dispatch(this.props.ctx, loci);
+//     }
+
+
+//     render() {
+//         const { ctx, seq } = this.props;
+//         const { offset, sequence } = seq.sequence;
+
+//         const elems: JSX.Element[] = [];
+//         for (let i = 0, _i = sequence.length; i < _i; i++) {
+//             elems[elems.length] = <ResidueView ctx={ctx} seqId={offset + i} letter={sequence[i]} parent={this} key={i} />;
+//         }
+
+//         return <div style={{ wordWrap: 'break-word' }}>
+//             <span style={{ fontWeight: 'bold' }}>{this.props.seq.entityId}:{offset}&nbsp;</span>
+//             {elems}
+//         </div>;
+//     }
+// }
+
+// class ResidueView extends React.Component<{ ctx: Context, seqId: number, letter: string, parent: EntitySequence }, { isHighlighted: boolean }> {
+//     state = { isHighlighted: false }
+
+//     mouseEnter = () => {
+//         this.setState({ isHighlighted: true });
+//         this.props.parent.raiseInteractityEvent(this.props.seqId);
+//     }
+
+//     mouseLeave = () => {
+//         this.setState({ isHighlighted: false });
+//         this.props.parent.raiseInteractityEvent();
+//     }
+
+//     render() {
+//         return <span onMouseEnter={this.mouseEnter} onMouseLeave={this.mouseLeave}
+//             style={{ cursor: 'pointer', backgroundColor: this.state.isHighlighted ? 'yellow' : void 0 }}>
+//             {this.props.letter}
+//         </span>;
+//     }
+// }

+ 0 - 67
src/mol-app/context/context.ts

@@ -1,67 +0,0 @@
-/*
- * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
- *
- * Adapted from LiteMol
- * Copyright (c) 2016 - now David Sehnal, licensed under Apache 2.0, See LICENSE file for more info.
- */
-
-import { UUID } from 'mol-util'
-import { PerformanceMonitor } from 'mol-util/performance-monitor';
-import { Dispatcher } from '../service/dispatcher'
-import { Logger } from '../service/logger'
-import { LayoutTarget, LayoutController } from '../controller/layout';
-import { ViewportController } from '../controller/visualization/viewport';
-import { Stage } from 'mol-view/stage';
-import { AnyTransform } from 'mol-view/state/transform';
-import { BehaviorSubject } from 'rxjs';
-import { AnyEntity } from 'mol-view/state/entity';
-import { SequenceViewController } from '../controller/visualization/sequence-view';
-
-export class Settings {
-    private settings = new Map<string, any>();
-
-    set(key: string, value: any) {
-        this.settings.set(key, value);
-    }
-
-    get(key: string) {
-        return this.settings.get(key);
-    }
-}
-
-export class Context {
-    id = UUID.create()
-
-    dispatcher = new Dispatcher();
-    logger = new Logger(this);
-    performance = new PerformanceMonitor();
-
-    stage = new Stage(this);
-    viewport = new ViewportController(this);
-    layout: LayoutController;
-    settings = new Settings();
-
-    // TODO: this is a temporary solution
-    components = {
-        sequenceView: new SequenceViewController(this)
-    };
-
-    currentEntity = new BehaviorSubject(undefined) as BehaviorSubject<AnyEntity | undefined>
-    currentTransforms = new BehaviorSubject([] as AnyTransform[])
-
-    createLayout(targets: LayoutTarget[], target: HTMLElement) {
-        this.layout = new LayoutController(this, targets, target);
-    }
-
-    initStage(canvas: HTMLCanvasElement, container: HTMLDivElement) {
-        this.stage.initRenderer(canvas, container)
-        return true
-    }
-
-    destroy() {
-        if (this.stage) {
-            this.stage.dispose()
-            this.stage = null as any
-        }
-    }
-}

+ 0 - 49
src/mol-app/controller/controller.ts

@@ -1,49 +0,0 @@
-/*
- * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
- *
- * Adapted from LiteMol
- * Copyright (c) 2016 - now David Sehnal, licensed under Apache 2.0, See LICENSE file for more info.
- */
-
-import { BehaviorSubject } from 'rxjs';
-import { merge } from 'mol-util';
-import { Context } from '../context/context'
-import { LayoutRegion } from './layout';
-
-export class Controller<State> {
-
-    private _state = new BehaviorSubject<State>(<any>void 0);
-    private _latestState: State = <any>void 0;
-
-    get dispatcher() {
-        return this.context.dispatcher;
-    }
-
-    setState(...states: Partial<State>[]) {
-        let s = merge(this._latestState, ...states);
-        if (s !== this._latestState) {
-            this._latestState = s;
-            this._state.next(s);
-        }
-    }
-
-    get state() {
-        return this._state;
-    }
-
-    get latestState() {
-        return this._latestState;
-    }
-
-    constructor(public context: Context, initialState: State) {
-        this._latestState = initialState;
-    }
-}
-
-export interface ControllerInfo {
-    key: string;
-    controller: Controller<any>;
-    view: any;
-    region: LayoutRegion;
-    isStatic?: boolean;
-}

+ 0 - 27
src/mol-app/controller/entity/tree.ts

@@ -1,27 +0,0 @@
-/*
- * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
- *
- * Adapted from LiteMol
- * Copyright (c) 2016 - now David Sehnal, licensed under Apache 2.0, See LICENSE file for more info.
- */
-
-import { Context } from '../../context/context'
-import { Controller } from '../controller';
-import { AnyEntity } from 'mol-view/state/entity';
-
-export interface EntityTreeState {
-    entities: Set<AnyEntity>
-}
-
-export class EntityTreeController extends Controller<EntityTreeState> {
-    constructor(context: Context) {
-        super(context, { entities: new Set() });
-
-        context.stage.ctx.change.subscribe(() => {
-            if (context.stage.ctx) {
-                this.state.next({ entities: context.stage.ctx.entities }) // TODO
-                this.setState({ entities: context.stage.ctx.entities })
-            }
-        })
-    }
-}

+ 0 - 216
src/mol-app/controller/layout.ts

@@ -1,216 +0,0 @@
-/*
- * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
- *
- * Adapted from LiteMol
- * Copyright (c) 2016 - now David Sehnal, licensed under Apache 2.0, See LICENSE file for more info.
- */
-
-import { Context } from '../context/context'
-import { Controller, ControllerInfo } from './controller'
-import { CommonEvents, LayoutEvents } from '../event/basic';
-
-export enum LayoutRegion {
-    Main     = 0,
-    Top      = 1,
-    Right    = 2,
-    Bottom   = 3,
-    Left     = 4,
-    Root     = 5
-}
-
-export enum CollapsedControlsLayout {
-    Outside   = 0,
-    Landscape = 1,
-    Portrait  = 2
-}
-
-export class LayoutTarget {
-    components: ControllerInfo[] = [];
-    constructor(public cssClass: string) {
-    }
-}
-
-export function makeEmptyTargets() {
-    let ret: LayoutTarget[] = [];
-    for (let i = 0; i <= LayoutRegion.Root; i++) {
-        ret.push(new LayoutTarget(LayoutRegion[i].toLowerCase()));
-    }
-    return ret;
-}
-
-export type RegionState = 'Hidden' | 'Sticky' | 'Default'
-
-export interface LayoutState {
-    isExpanded: boolean,
-    hideControls: boolean,
-    collapsedControlsLayout: CollapsedControlsLayout,
-    regionStates?: { [region: number]: RegionState }
-}
-
-interface RootState {
-    top: string | null,
-    bottom: string | null,
-    left: string | null,
-    right: string | null,
-
-    width: string | null;
-    height: string | null;
-    maxWidth: string | null;
-    maxHeight: string | null;
-    margin: string | null;
-    marginLeft: string | null;
-    marginRight: string | null;
-    marginTop: string | null;
-    marginBottom: string | null;
-
-    scrollTop: number,
-    scrollLeft: number,
-    position: string | null,
-    overflow: string | null,
-    viewports: HTMLElement[],
-    zindex: string | null
-}
-
-export class LayoutController extends Controller<LayoutState> {
-
-    update(state: Partial<LayoutState>) {
-        let prevExpanded = !!this.latestState.isExpanded;
-        this.setState(state);
-        if (typeof state.isExpanded === 'boolean' && state.isExpanded !== prevExpanded) this.handleExpand();
-
-        this.dispatcher.schedule(() => CommonEvents.LayoutChanged.dispatch(this.context, {}));
-    }
-
-    private rootState: RootState | undefined = void 0;
-    private expandedViewport: HTMLMetaElement;
-
-    private getScrollElement() {
-        if ((document as any).scrollingElement) return (document as any).scrollingElement;
-        if (document.documentElement) return document.documentElement;
-        return document.body;
-    }
-
-    private handleExpand() {
-        try {
-            let body = document.getElementsByTagName('body')[0];
-            let head = document.getElementsByTagName('head')[0];
-
-            if (!body || !head) return;
-
-            if (this.latestState.isExpanded) {
-
-                let children = head.children;
-                let hasExp = false;
-                let viewports: HTMLElement[] = [];
-                for (let i = 0; i < children.length; i++) {
-                    if (children[i] === this.expandedViewport) {
-                        hasExp = true;
-                    } else if (((children[i] as any).name || '').toLowerCase() === 'viewport') {
-                        viewports.push(children[i] as any);
-                    }
-                }
-
-                for (let v of viewports) {
-                    head.removeChild(v);
-                }
-
-                if (!hasExp) head.appendChild(this.expandedViewport);
-
-
-                let s = body.style;
-
-                let doc = this.getScrollElement();
-                let scrollLeft = doc.scrollLeft;
-                let scrollTop = doc.scrollTop;
-
-                this.rootState = {
-                    top: s.top, bottom: s.bottom, right: s.right, left: s.left, scrollTop, scrollLeft, position: s.position, overflow: s.overflow, viewports, zindex: this.root.style.zIndex,
-                    width: s.width, height: s.height,
-                    maxWidth: s.maxWidth, maxHeight: s.maxHeight,
-                    margin: s.margin, marginLeft: s.marginLeft, marginRight: s.marginRight, marginTop: s.marginTop, marginBottom: s.marginBottom
-                };
-
-                s.overflow = 'hidden';
-                s.position = 'fixed';
-                s.top = '0';
-                s.bottom = '0';
-                s.right = '0';
-                s.left = '0';
-
-                s.width = '100%';
-                s.height = '100%';
-                s.maxWidth = '100%';
-                s.maxHeight = '100%';
-                s.margin = '0';
-                s.marginLeft = '0';
-                s.marginRight = '0';
-                s.marginTop = '0';
-                s.marginBottom = '0';
-
-                this.root.style.zIndex = '100000';
-            } else {
-                // root.style.overflow = rootOverflow;
-                let children = head.children;
-                for (let i = 0; i < children.length; i++) {
-                    if (children[i] === this.expandedViewport) {
-                        head.removeChild(this.expandedViewport);
-                        break;
-                    }
-                }
-
-                if (this.rootState) {
-                    let s = body.style, t = this.rootState;
-                    for (let v of t.viewports) {
-                        head.appendChild(v);
-                    }
-                    s.top = t.top;
-                    s.bottom = t.bottom;
-                    s.left = t.left;
-                    s.right = t.right;
-
-                    s.width = t.width;
-                    s.height = t.height;
-                    s.maxWidth = t.maxWidth;
-                    s.maxHeight = t.maxHeight;
-                    s.margin = t.margin;
-                    s.marginLeft = t.marginLeft;
-                    s.marginRight = t.marginRight;
-                    s.marginTop = t.marginTop;
-                    s.marginBottom = t.marginBottom;
-
-                    s.position = t.position;
-                    s.overflow = t.overflow;
-                    let doc = this.getScrollElement();
-                    doc.scrollTop = t.scrollTop;
-                    doc.scrollLeft = t.scrollLeft;
-                    this.rootState = void 0;
-                    this.root.style.zIndex = t.zindex;
-                }
-            }
-        } catch (e) {
-            this.context.logger.error('Layout change error, you might have to reload the page.');
-            console.log('Layout change error, you might have to reload the page.', e);
-        }
-    }
-
-    updateTargets(targets: LayoutTarget[]) {
-        this.targets = targets;
-        this.dispatcher.schedule(() => CommonEvents.ComponentsChanged.dispatch(this.context, {}));
-    }
-
-    constructor(context: Context, public targets: LayoutTarget[], private root: HTMLElement) {
-        super(context, {
-            isExpanded: false,
-            hideControls: false,
-            collapsedControlsLayout: CollapsedControlsLayout.Outside,
-            regionStates: { }
-        });
-
-        LayoutEvents.SetState.getStream(this.context).subscribe(e => this.update(e.data));
-
-        // <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" />
-        this.expandedViewport = document.createElement('meta') as any;
-        this.expandedViewport.name = 'viewport';
-        this.expandedViewport.content = 'width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0';
-    }
-}

+ 0 - 81
src/mol-app/controller/misc/jobs.ts

@@ -1,81 +0,0 @@
-/**
- * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
- *
- * Adapted from LiteMol
- * Copyright (c) 2016 - now David Sehnal, licensed under Apache 2.0, See LICENSE file for more info.
- */
-
-import produce from 'immer'
-import { filter } from 'rxjs/operators';
-
-import { Controller } from '../controller'
-import { JobEvents } from '../../event/basic';
-import { Context } from '../../context/context';
-import { Job } from '../../service/job';
-
-
-export interface JobInfo {
-    name: string;
-    message: string;
-    abort?: () => void
-}
-
-export interface JobsState {
-    jobs: { [k: number]: JobInfo }
-}
-
-export class JobsController extends Controller<JobsState> {
-    private updated(state: Job.State) {
-        let isWatched = state.type === this.type;
-        let jobs = this.latestState.jobs!;
-
-        if (!isWatched) {
-            if (jobs[state.jobId] !== undefined) {
-                jobs = produce(jobs, _jobs => { delete _jobs[state.jobId] });
-                this.setState({ jobs });
-            }
-            return;
-        }
-
-        jobs = produce(jobs, _jobs => {
-            _jobs[state.jobId] = {
-                name: state.name,
-                message: state.message,
-                abort: state.abort
-            };
-        })
-        this.setState({ jobs });
-    }
-
-    private started(job: Job.Info) {
-        this.setState({
-            jobs: produce(this.latestState.jobs!, _jobs => {
-                _jobs[job.id] = { name: job.name, message: 'Running...' }
-            })
-        });
-    }
-
-    private completed(taskId: number) {
-        if (!this.latestState.jobs![taskId]) return;
-
-        this.setState({
-            jobs: produce(this.latestState.jobs!, _jobs => { delete _jobs[taskId] })
-        });
-    }
-
-    constructor(context: Context, private type: Job.Type) {
-        super(context, {
-            jobs: {}
-        });
-
-        JobEvents.StateUpdated.getStream(this.context)
-            .subscribe(e => this.updated(e.data));
-
-        JobEvents.Started.getStream(this.context).pipe(
-            filter(e => e.data.type === type))
-            .subscribe(e => this.started(e.data));
-
-        JobEvents.Completed.getStream(this.context)
-            .subscribe(e => this.completed(e.data));
-    }
-}

+ 0 - 24
src/mol-app/controller/misc/log.ts

@@ -1,24 +0,0 @@
-/*
- * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
- *
- * Adapted from LiteMol
- * Copyright (c) 2016 - now David Sehnal, licensed under Apache 2.0, See LICENSE file for more info.
- */
-
-import produce from 'immer'
-
-import { Controller } from '../controller'
-import { Context } from '../../context/context';
-import { LogEvent } from '../../event/basic';
-import { Logger } from '../../service/logger';
-
-export class LogController extends Controller<{ entries: Logger.Entry[] }> {
-    constructor(context: Context) {
-        super(context, { entries: [] });
-
-        LogEvent.getStream(this.context)
-            .subscribe(e => this.setState({
-                entries: produce(this.latestState.entries, _entries => { _entries.push(e.data) })
-            }))
-    }
-}

+ 0 - 27
src/mol-app/controller/transform/list.ts

@@ -1,27 +0,0 @@
-/*
- * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
- *
- * Adapted from LiteMol
- * Copyright (c) 2016 - now David Sehnal, licensed under Apache 2.0, See LICENSE file for more info.
- */
-
-import { Context } from '../../context/context'
-import { Controller } from '../controller';
-import { AnyTransform } from 'mol-view/state/transform';
-import { AnyEntity } from 'mol-view/state/entity';
-
-export interface TransformListState {
-    entity?: AnyEntity
-    transforms: AnyTransform[]
-}
-
-export class TransformListController extends Controller<TransformListState> {
-    constructor(context: Context) {
-        super(context, { transforms: [], entity: undefined });
-
-        context.currentTransforms.subscribe((transforms) => {
-            this.state.next({ transforms, entity: context.currentEntity.getValue() }) // TODO
-            this.setState({ transforms, entity: context.currentEntity.getValue() })
-        })
-    }
-}

+ 0 - 21
src/mol-app/controller/visualization/sequence-view.ts

@@ -1,21 +0,0 @@
-/**
- * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
- *
- * @author David Sehnal <david.sehnal@gmail.com>
- */
-
-import { shallowClone } from 'mol-util';
-import { Context } from '../../context/context'
-import { Controller } from '../controller';
-import { Structure } from 'mol-model/structure';
-
-export const DefaultSequenceViewState = {
-    structure: void 0 as (Structure | undefined)
-}
-export type SequenceViewState = typeof DefaultSequenceViewState
-
-export class SequenceViewController extends Controller<SequenceViewState> {
-    constructor(context: Context) {
-        super(context, shallowClone(DefaultSequenceViewState));
-    }
-}

+ 0 - 27
src/mol-app/controller/visualization/viewport.ts

@@ -1,27 +0,0 @@
-/*
- * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
- *
- * Adapted from LiteMol
- * Copyright (c) 2016 - now David Sehnal, licensed under Apache 2.0, See LICENSE file for more info.
- */
-
-// import { throttle } from 'rxjs/operators';
-// import { interval } from 'rxjs';
-
-import { shallowClone } from 'mol-util';
-import { Context } from '../../context/context'
-import { Controller } from '../controller';
-
-export const DefaultViewportOptions = {
-    clearColor: { r: 1, g: 1, b: 1 },
-    enableFog: true,
-    cameraFOV: 30,
-    cameraSpeed: 4
-}
-export type ViewportOptions = typeof DefaultViewportOptions
-
-export class ViewportController extends Controller<ViewportOptions> {
-    constructor(context: Context) {
-        super(context, shallowClone(DefaultViewportOptions));
-    }
-}

+ 0 - 40
src/mol-app/event/basic.ts

@@ -1,40 +0,0 @@
-/*
- * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
- *
- * Adapted from LiteMol
- * Copyright (c) 2016 - now David Sehnal, licensed under Apache 2.0, See LICENSE file for more info.
- */
-
-import { Event } from './event'
-import { Logger } from '../service/logger';
-import { Dispatcher } from '../service/dispatcher'
-import { LayoutState } from '../controller/layout';
-import { ViewportOptions } from '../controller/visualization/viewport';
-import { Job } from '../service/job';
-import { Loci } from 'mol-model/loci';
-
-const Lane = Dispatcher.Lane;
-
-export const LogEvent = Event.create<Logger.Entry>('bs.Log', Lane.Log);
-
-export namespace CommonEvents {
-    export const LayoutChanged = Event.create('bs.Common.LayoutChanged', Lane.Slow);
-    export const ComponentsChanged = Event.create('bs.Common.ComponentsChanged', Lane.Slow);
-}
-
-export namespace JobEvents {
-    export const Started = Event.create<Job.Info>('bs.Jobs.Started', Lane.Job);
-    export const Completed = Event.create<number>('bs.Jobs.Completed', Lane.Job);
-    export const StateUpdated = Event.create<Job.State>('bs.Jobs.StateUpdated', Lane.Busy);
-}
-
-export namespace LayoutEvents {
-    export const SetState = Event.create<Partial<LayoutState>>('lm.cmd.Layout.SetState', Lane.Slow);
-    export const SetViewportOptions = Event.create<ViewportOptions>('bs.cmd.Layout.SetViewportOptions', Lane.Slow);
-}
-
-export namespace InteractivityEvents {
-    export const HighlightLoci = Event.create<Loci>('bs.Interactivity.HighlightLoci', Lane.Slow);
-    export const SelectLoci = Event.create<Loci>('bs.Interactivity.SelectLoci', Lane.Slow);
-    export const LabelLoci = Event.create<Loci>('bs.Interactivity.LabelLoci', Lane.Slow);
-}

+ 0 - 43
src/mol-app/event/event.ts

@@ -1,43 +0,0 @@
-/*
- * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
- *
- * Adapted from LiteMol
- * Copyright (c) 2016 - now David Sehnal, licensed under Apache 2.0, See LICENSE file for more info.
- */
-
-import { Observable } from 'rxjs';
-import { Context } from '../context/context'
-import { Dispatcher } from '../service/dispatcher'
-
-export interface Event<T> {
-    type: Event.Type<T>;
-    data: T;
-}
-
-export namespace Event {
-    export type Stream<T> = Observable<Event<T>>;
-
-    import Lane = Dispatcher.Lane
-
-    export type Any = Event<any>
-    export type AnyType = Type<any>
-
-    export interface Type<T> {
-        name: string,
-        lane: Lane,
-        dispatch(context: Context, data: T): void;
-        getStream(context: Context): Stream<T>;
-    }
-
-    const EventPrototype = {
-        dispatch<T>(this: any, context: Context, data: T) { context.dispatcher.dispatch({ type: this, data }) },
-        getStream(this: any, context: Context) { return context.dispatcher.getStream(this); }
-    }
-
-    export function create<T>(name: string, lane: Dispatcher.Lane): Type<T> {
-        return Object.create(EventPrototype, {
-            name: { writable: false, configurable: false, value: name },
-            lane: { writable: false, configurable: false, value: lane }
-        });
-    }
-}

+ 0 - 59
src/mol-app/service/dispatcher.ts

@@ -1,59 +0,0 @@
-/*
- * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
- *
- * Adapted from LiteMol
- * Copyright (c) 2016 - now David Sehnal, licensed under Apache 2.0, See LICENSE file for more info.
- */
-
-import { Subject } from 'rxjs';
-import { filter } from 'rxjs/operators';
-import { Event } from '../event/event'
-
-export class Dispatcher {
-    LOG_DISPATCH_STREAM = false;
-
-    private lanes: Subject<Event<any>>[] = [];
-    constructor() {
-        for (let i = 0; i <= Dispatcher.Lane.Job; i++) {
-            this.lanes.push(new Subject<Event<any>>());
-        }
-    }
-
-    dispatch<T>(event: Event<T>) {
-        if (this.LOG_DISPATCH_STREAM) console.log(event.type.name, Dispatcher.Lane[event.type.lane], event.data);
-        this.lanes[event.type.lane].next(event);
-    }
-
-    schedule(action: () => void, onError?: (e: string) => void, timeout = 1000 / 31) {
-        return setTimeout(() => {
-            if (onError) {
-                try {
-                    action.call(null)
-                } catch (e) {
-                    onError.call(null, '' + e);
-                }
-            } else {
-                action.call(null);
-            }
-        }, timeout);
-    }
-
-    getStream<T>(type: Event.Type<T>): Event.Stream<T> {
-        return this.lanes[type.lane].pipe(filter(e => e.type === type));
-    }
-
-    finished() {
-        this.lanes.forEach(l => l.complete());
-    }
-}
-
-export namespace Dispatcher {
-    export enum Lane {
-        Slow = 0,
-        Fast = 1,
-        Log = 2,
-        Busy = 3,
-        Transformer = 4,
-        Job = 5
-    }
-}

+ 0 - 132
src/mol-app/service/job.ts

@@ -1,132 +0,0 @@
-/**
- * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
- *
- * Adapted from LiteMol
- * Copyright (c) 2016 - now David Sehnal, licensed under Apache 2.0, See LICENSE file for more info.
- */
-
-import { Context } from '../context/context'
-import { JobEvents } from '../event/basic';
-import { PerformanceMonitor } from 'mol-util/performance-monitor';
-import { formatProgress } from 'mol-util';
-import { Progress, Task } from 'mol-task';
-
-export class Job<T> {
-    private info: Job.Info;
-    get id() { return this.info.id; }
-    get reportTime() { return this.info.reportTime; }
-
-    run(context: Context) {
-        return this.runWithContext(context).result;
-    }
-
-    runWithContext(context: Context): Job.Running<T> {
-        return new Job.Running(context, this.task, this.info);
-    }
-
-    setReportTime(report: boolean) {
-        this.info.reportTime = report;
-        return this;
-    }
-
-    constructor(public name: string, public type: Job.Type, private task: Task<T>) {
-        this.info = {
-            id: serialJobId++,
-            name,
-            type,
-            reportTime: false
-        };
-    }
-}
-
-let serialJobId = 0;
-export namespace Job {
-    export let __DEBUG_MODE__ = false;
-
-    export type Type = 'Normal' | 'Background' | 'Silent';
-
-    export interface Info {
-        id: number,
-        type: Type,
-        name: string,
-        reportTime: boolean
-    }
-
-    export class Running<T> {
-        result: Promise<T>;
-
-        private progressUpdated(progress: Progress) {
-            JobEvents.StateUpdated.dispatch(this.context, {
-                jobId: this.info.id,
-                type: this.info.type,
-                name: this.info.name,
-                message: formatProgress(progress),
-                abort: progress.requestAbort
-            });
-        }
-
-        private resolved() {
-            try {
-                this.context.performance.end('job' + this.info.id);
-                if (this.info.reportTime) {
-                    let time = this.context.performance.time('job' + this.info.id);
-                    if (this.info.type !== 'Silent') this.context.logger.info(`${this.info.name} finished in ${PerformanceMonitor.format(time)}.`)
-                }
-            } finally {
-                JobEvents.Completed.dispatch(this.context, this.info.id);
-            }
-        }
-
-        private rejected(err: any) {
-            this.context.performance.end('job' + this.info.id);
-            this.context.performance.formatTime('job' + this.info.id);
-
-            if (__DEBUG_MODE__) {
-                console.error(err);
-            }
-
-            try {
-                if (this.info.type === 'Silent') {
-                    if (err.warn)  this.context.logger.warning(`Warning (${this.info.name}): ${err.message}`);
-                    else console.error(`Error (${this.info.name})`, err);
-                } else {
-                    if (err.warn) {
-                        this.context.logger.warning(`Warning (${this.info.name}): ${err.message}`);
-                    } else {
-                        let e = '' + err;
-                        if (e.indexOf('Aborted') >= 0) this.context.logger.info(`${this.info.name}: Aborted.`);
-                        else this.context.logger.error(`Error (${this.info.name}): ${err}`);
-                    }
-                }
-            } catch (e) {
-                console.error(e);
-            } finally {
-                JobEvents.Completed.dispatch(this.context, this.info.id);
-            }
-        }
-
-        private run() {
-            JobEvents.Started.dispatch(this.context, this.info);
-            this.context.performance.start('job' + this.info.id);
-
-            this.result = this.task.run((p: Progress) => this.progressUpdated(p), 250)
-            this.result.then(() => this.resolved()).catch(e => this.rejected(e));
-        }
-
-        constructor(private context: Context, private task: Task<T>, private info: Info) {
-            this.run();
-        }
-    }
-
-    export interface State {
-        jobId: number,
-        type: Type,
-        name: string,
-        message: string,
-        abort?: () => void
-    }
-
-    export function create<T>(name: string, type: Type, task: Task<T>) {
-        return new Job<T>(name, type, task);
-    }
-}

+ 0 - 51
src/mol-app/service/logger.ts

@@ -1,51 +0,0 @@
-/*
- * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
- *
- * Adapted from LiteMol
- * Copyright (c) 2016 - now David Sehnal, licensed under Apache 2.0, See LICENSE file for more info.
- */
-
-import { LogEvent } from '../event/basic'
-import { Context } from '../context/context'
-
-export class Logger {
-
-    private log(e: Logger.Entry) {
-        LogEvent.dispatch(this.context, e);
-    }
-
-    message(m: string) {
-        this.log({ type: Logger.EntryType.Message, timestamp: new Date(), message: m });
-    }
-
-    error(m: string) {
-        this.log({ type: Logger.EntryType.Error, timestamp: new Date(), message: m });
-    }
-
-    warning(m: string) {
-        this.log({ type: Logger.EntryType.Warning, timestamp: new Date(), message: m });
-    }
-
-    info(m: string) {
-        this.log({ type: Logger.EntryType.Info, timestamp: new Date(), message: m });
-    }
-
-    constructor(private context: Context) {
-
-    }
-}
-
-export namespace Logger {
-    export enum EntryType {
-        Message,
-        Error,
-        Warning,
-        Info
-    }
-
-    export interface Entry {
-        type: EntryType;
-        timestamp: Date;
-        message: any
-    }
-}

+ 0 - 45
src/mol-app/skin/base.scss

@@ -1,45 +0,0 @@
-
-@font-face {
-    font-family: 'fontello';
-    src: url('./fonts/fontello.eot');
-    src: url('./fonts/fontello.eot#iefix') format('embedded-opentype'),
-         url('./fonts/fontello.woff2') format('woff2'),
-         url('./fonts/fontello.woff') format('woff'),
-         url('./fonts/fontello.ttf') format('truetype'),
-         url('./fonts/fontello.svg#fontello') format('svg');
-    font-weight: normal;
-    font-style: normal;
-}
-
-@import url(https://fonts.googleapis.com/css?family=Source+Sans+Pro:400,400italic,700);
-
-.molstar-plugin {
-    font-family: "Helvetica Neue", "Source Sans Pro", Helvetica, Arial, sans-serif;
-    font-size: 14px;
-    line-height: 1.42857143;
-
-    position: absolute;
-    left: 0;
-    top: 0;
-    right: 0;
-    bottom: 0;
-    @import 'variables';
-
-    // for bootstrap
-    $border-radius-base:        0;
-    $border-radius-large:       0;
-    $border-radius-small:       0;
-
-    @import 'bootstrap';
-
-    @import 'icons';
-    @import 'layout';
-    @import 'ui';
-    @import 'logo';
-
-    .molstar-plugin-content {
-        color: $font-color;
-    }
-
-    background: $default-background;
-}

+ 0 - 25
src/mol-app/skin/bootstrap.scss

@@ -1,25 +0,0 @@
-/*!
- * Bootstrap v3.3.6 (http://getbootstrap.com)
- * Copyright 2011-2015 Twitter, Inc.
- * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
- */
-
-// Core variables and mixins
-@import "bootstrap/variables";
-@import "bootstrap/mixins";
-
-// Reset and dependencies
-@import "bootstrap/normalize";
-
-// Core CSS
-@import "bootstrap/scaffolding";
-@import "bootstrap/type";
-@import "bootstrap/forms";
-@import "bootstrap/buttons";
-
-// Components
-@import "bootstrap/button-groups";
-@import "bootstrap/input-groups";
-
-@import "bootstrap/labels";
-@import "bootstrap/badges";

+ 0 - 68
src/mol-app/skin/bootstrap/badges.scss

@@ -1,68 +0,0 @@
-//
-// Badges
-// --------------------------------------------------
-
-
-// Base class
-.badge {
-    display: inline-block;
-    min-width: 10px;
-    padding: 3px 7px;
-    font-size: $font-size-small;
-    font-weight: $badge-font-weight;
-    color: $badge-color;
-    line-height: $badge-line-height;
-    vertical-align: middle;
-    white-space: nowrap;
-    text-align: center;
-    background-color: $badge-bg;
-    border-radius: $badge-border-radius;
-
-    // Empty badges collapse automatically (not available in IE8)
-    &:empty {
-      display: none;
-    }
-
-    // Quick fix for badges in buttons
-    .molstar-btn & {
-      position: relative;
-      top: -1px;
-    }
-
-    .molstar-btn-xs &,
-    .molstar-btn-group-xs > .molstar-btn & {
-      top: 0;
-      padding: 1px 5px;
-    }
-
-    // [converter] extracted a& to a.badge
-
-    // Account for badges in navs
-    .list-group-item.active > &,
-    .nav-pills > .active > a > & {
-      color: $badge-active-color;
-      background-color: $badge-active-bg;
-    }
-
-    .list-group-item > & {
-      float: right;
-    }
-
-    .list-group-item > & + & {
-      margin-right: 5px;
-    }
-
-    .nav-pills > li > a > & {
-      margin-left: 3px;
-    }
-  }
-
-  // Hover state, but only for links
-  a.badge {
-    &:hover,
-    &:focus {
-      color: $badge-link-hover-color;
-      text-decoration: none;
-      cursor: pointer;
-    }
-  }

+ 0 - 244
src/mol-app/skin/bootstrap/button-groups.scss

@@ -1,244 +0,0 @@
-//
-// Button groups
-// --------------------------------------------------
-
-// Make the div behave like a button
-.molstar-btn-group,
-.molstar-btn-group-vertical {
-  position: relative;
-  display: inline-block;
-  vertical-align: middle; // match .molstar-btn alignment given font-size hack above
-  > .molstar-btn {
-    position: relative;
-    float: left;
-    // Bring the "active" button to the front
-    &:hover,
-    &:focus,
-    &:active,
-    &.active {
-      z-index: 2;
-    }
-  }
-}
-
-// Prevent double borders when buttons are next to each other
-.molstar-btn-group {
-  .molstar-btn + .molstar-btn,
-  .molstar-btn + .molstar-btn-group,
-  .molstar-btn-group + .molstar-btn,
-  .molstar-btn-group + .molstar-btn-group {
-    margin-left: -1px;
-  }
-}
-
-// Optional: Group multiple button groups together for a toolbar
-.molstar-btn-toolbar {
-  margin-left: -5px; // Offset the first child's margin
-  @include clearfix;
-
-  .molstar-btn,
-  .molstar-btn-group,
-  .input-group {
-    float: left;
-  }
-  > .molstar-btn,
-  > .molstar-btn-group,
-  > .input-group {
-    margin-left: 5px;
-  }
-}
-
-.molstar-btn-group > .molstar-btn:not(:first-child):not(:last-child):not(.dropdown-toggle) {
-  border-radius: 0;
-}
-
-// Set corners individual because sometimes a single button can be in a .molstar-btn-group and we need :first-child and :last-child to both match
-.molstar-btn-group > .molstar-btn:first-child {
-  margin-left: 0;
-  &:not(:last-child):not(.dropdown-toggle) {
-    @include border-right-radius(0);
-  }
-}
-// Need .dropdown-toggle since :last-child doesn't apply given a .dropdown-menu immediately after it
-.molstar-btn-group > .molstar-btn:last-child:not(:first-child),
-.molstar-btn-group > .dropdown-toggle:not(:first-child) {
-  @include border-left-radius(0);
-}
-
-// Custom edits for including molstar-btn-groups within molstar-btn-groups (useful for including dropdown buttons within a molstar-btn-group)
-.molstar-btn-group > .molstar-btn-group {
-  float: left;
-}
-.molstar-btn-group > .molstar-btn-group:not(:first-child):not(:last-child) > .molstar-btn {
-  border-radius: 0;
-}
-.molstar-btn-group > .molstar-btn-group:first-child:not(:last-child) {
-  > .molstar-btn:last-child,
-  > .dropdown-toggle {
-    @include border-right-radius(0);
-  }
-}
-.molstar-btn-group > .molstar-btn-group:last-child:not(:first-child) > .molstar-btn:first-child {
-  @include border-left-radius(0);
-}
-
-// On active and open, don't show outline
-.molstar-btn-group .dropdown-toggle:active,
-.molstar-btn-group.open .dropdown-toggle {
-  outline: 0;
-}
-
-
-// Sizing
-//
-// Remix the default button sizing classes into new ones for easier manipulation.
-
-.molstar-btn-group-xs > .molstar-btn { @extend .molstar-btn-xs; }
-.molstar-btn-group-sm > .molstar-btn { @extend .molstar-btn-sm; }
-.molstar-btn-group-lg > .molstar-btn { @extend .molstar-btn-lg; }
-
-
-// Split button dropdowns
-// ----------------------
-
-// Give the line between buttons some depth
-.molstar-btn-group > .molstar-btn + .dropdown-toggle {
-  padding-left: 8px;
-  padding-right: 8px;
-}
-.molstar-btn-group > .molstar-btn-lg + .dropdown-toggle {
-  padding-left: 12px;
-  padding-right: 12px;
-}
-
-// The clickable button for toggling the menu
-// Remove the gradient and set the same inset shadow as the :active state
-.molstar-btn-group.open .dropdown-toggle {
-  @include box-shadow(inset 0 3px 5px rgba(0,0,0,.125));
-
-  // Show no shadow for `.molstar-btn-link` since it has no other button styles.
-  &.molstar-btn-link {
-    @include box-shadow(none);
-  }
-}
-
-
-// Reposition the caret
-.molstar-btn .caret {
-  margin-left: 0;
-}
-// Carets in other button sizes
-.molstar-btn-lg .caret {
-  border-width: $caret-width-large $caret-width-large 0;
-  border-bottom-width: 0;
-}
-// Upside down carets for .dropup
-.dropup .molstar-btn-lg .caret {
-  border-width: 0 $caret-width-large $caret-width-large;
-}
-
-
-// Vertical button groups
-// ----------------------
-
-.molstar-btn-group-vertical {
-  > .molstar-btn,
-  > .molstar-btn-group,
-  > .molstar-btn-group > .molstar-btn {
-    display: block;
-    float: none;
-    width: 100%;
-    max-width: 100%;
-  }
-
-  // Clear floats so dropdown menus can be properly placed
-  > .molstar-btn-group {
-    @include clearfix;
-    > .molstar-btn {
-      float: none;
-    }
-  }
-
-  > .molstar-btn + .molstar-btn,
-  > .molstar-btn + .molstar-btn-group,
-  > .molstar-btn-group + .molstar-btn,
-  > .molstar-btn-group + .molstar-btn-group {
-    margin-top: -1px;
-    margin-left: 0;
-  }
-}
-
-.molstar-btn-group-vertical > .molstar-btn {
-  &:not(:first-child):not(:last-child) {
-    border-radius: 0;
-  }
-  &:first-child:not(:last-child) {
-    @include border-top-radius($molstar-btn-border-radius-base);
-    @include border-bottom-radius(0);
-  }
-  &:last-child:not(:first-child) {
-    @include border-top-radius(0);
-    @include border-bottom-radius($molstar-btn-border-radius-base);
-  }
-}
-.molstar-btn-group-vertical > .molstar-btn-group:not(:first-child):not(:last-child) > .molstar-btn {
-  border-radius: 0;
-}
-.molstar-btn-group-vertical > .molstar-btn-group:first-child:not(:last-child) {
-  > .molstar-btn:last-child,
-  > .dropdown-toggle {
-    @include border-bottom-radius(0);
-  }
-}
-.molstar-btn-group-vertical > .molstar-btn-group:last-child:not(:first-child) > .molstar-btn:first-child {
-  @include border-top-radius(0);
-}
-
-
-// Justified button groups
-// ----------------------
-
-.molstar-btn-group-justified {
-  display: table;
-  width: 100%;
-  table-layout: fixed;
-  border-collapse: separate;
-  > .molstar-btn,
-  > .molstar-btn-group {
-    float: none;
-    display: table-cell;
-    width: 1%;
-  }
-  > .molstar-btn-group .molstar-btn {
-    width: 100%;
-  }
-
-  > .molstar-btn-group .dropdown-menu {
-    left: auto;
-  }
-}
-
-
-// Checkbox and radio options
-//
-// In order to support the browser's form validation feedback, powered by the
-// `required` attribute, we have to "hide" the inputs via `clip`. We cannot use
-// `display: none;` or `visibility: hidden;` as that also hides the popover.
-// Simply visually hiding the inputs via `opacity` would leave them clickable in
-// certain cases which is prevented by using `clip` and `pointer-events`.
-// This way, we ensure a DOM element is visible to position the popover from.
-//
-// See https://github.com/twbs/bootstrap/pull/12794 and
-// https://github.com/twbs/bootstrap/pull/14559 for more information.
-
-[data-toggle="buttons"] {
-  > .molstar-btn,
-  > .molstar-btn-group > .molstar-btn {
-    input[type="radio"],
-    input[type="checkbox"] {
-      position: absolute;
-      clip: rect(0,0,0,0);
-      pointer-events: none;
-    }
-  }
-}

+ 0 - 168
src/mol-app/skin/bootstrap/buttons.scss

@@ -1,168 +0,0 @@
-//
-// Buttons
-// --------------------------------------------------
-
-
-// Base styles
-// --------------------------------------------------
-
-.molstar-btn {
-    display: inline-block;
-    margin-bottom: 0; // For input.molstar-btn
-    font-weight: $molstar-btn-font-weight;
-    text-align: center;
-    vertical-align: middle;
-    touch-action: manipulation;
-    cursor: pointer;
-    background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214
-    border: 1px solid transparent;
-    white-space: nowrap;
-    @include button-size($padding-base-vertical, $padding-base-horizontal, $font-size-base, $line-height-base, $molstar-btn-border-radius-base);
-    @include user-select(none);
-
-    &,
-    &:active,
-    &.active {
-      &:focus,
-      &.focus {
-        @include tab-focus;
-      }
-    }
-
-    &:hover,
-    &:focus,
-    &.focus {
-      color: $molstar-btn-default-color;
-      text-decoration: none;
-    }
-
-    &:active,
-    &.active {
-      outline: 0;
-      background-image: none;
-      @include box-shadow(inset 0 3px 5px rgba(0,0,0,.125));
-    }
-
-    &.disabled,
-    &[disabled],
-    fieldset[disabled] & {
-      cursor: $cursor-disabled;
-      @include opacity(.65);
-      @include box-shadow(none);
-    }
-
-    // [converter] extracted a& to a.molstar-btn
-  }
-
-  a.molstar-btn {
-    &.disabled,
-    fieldset[disabled] & {
-      pointer-events: none; // Future-proof disabling of clicks on `<a>` elements
-    }
-  }
-
-
-  // Alternate buttons
-  // --------------------------------------------------
-
-  .molstar-btn-default {
-    @include button-variant($molstar-btn-default-color, $molstar-btn-default-bg, $molstar-btn-default-border);
-  }
-  .molstar-btn-primary {
-    @include button-variant($molstar-btn-primary-color, $molstar-btn-primary-bg, $molstar-btn-primary-border);
-  }
-  // Success appears as green
-  .molstar-btn-success {
-    @include button-variant($molstar-btn-success-color, $molstar-btn-success-bg, $molstar-btn-success-border);
-  }
-  // Info appears as blue-green
-  .molstar-btn-info {
-    @include button-variant($molstar-btn-info-color, $molstar-btn-info-bg, $molstar-btn-info-border);
-  }
-  // Warning appears as orange
-  .molstar-btn-warning {
-    @include button-variant($molstar-btn-warning-color, $molstar-btn-warning-bg, $molstar-btn-warning-border);
-  }
-  // Danger and error appear as red
-  .molstar-btn-danger {
-    @include button-variant($molstar-btn-danger-color, $molstar-btn-danger-bg, $molstar-btn-danger-border);
-  }
-
-
-  // Link buttons
-  // -------------------------
-
-  // Make a button look and behave like a link
-  .molstar-btn-link {
-    color: $link-color;
-    font-weight: normal;
-    border-radius: 0;
-
-    &,
-    &:active,
-    &.active,
-    &[disabled],
-    fieldset[disabled] & {
-      background-color: transparent;
-      @include box-shadow(none);
-    }
-    &,
-    &:hover,
-    &:focus,
-    &:active {
-      border-color: transparent;
-    }
-    &:hover,
-    &:focus {
-      color: $link-hover-color;
-      text-decoration: $link-hover-decoration;
-      background-color: transparent;
-    }
-    &[disabled],
-    fieldset[disabled] & {
-      &:hover,
-      &:focus {
-        color: $molstar-btn-link-disabled-color;
-        text-decoration: none;
-      }
-    }
-  }
-
-
-  // Button Sizes
-  // --------------------------------------------------
-
-  .molstar-btn-lg {
-    // line-height: ensure even-numbered height of button next to large input
-    @include button-size($padding-large-vertical, $padding-large-horizontal, $font-size-large, $line-height-large, $molstar-btn-border-radius-large);
-  }
-  .molstar-btn-sm {
-    // line-height: ensure proper height of button next to small input
-    @include button-size($padding-small-vertical, $padding-small-horizontal, $font-size-small, $line-height-small, $molstar-btn-border-radius-small);
-  }
-  .molstar-btn-xs {
-    @include button-size($padding-xs-vertical, $padding-xs-horizontal, $font-size-small, $line-height-small, $molstar-btn-border-radius-small);
-  }
-
-
-  // Block button
-  // --------------------------------------------------
-
-  .molstar-btn-block {
-    display: block;
-    width: 100%;
-  }
-
-  // Vertically space out multiple block buttons
-  .molstar-btn-block + .molstar-btn-block {
-    margin-top: 5px;
-  }
-
-  // Specificity overrides
-  input[type="submit"],
-  input[type="reset"],
-  input[type="button"] {
-    &.molstar-btn-block {
-      width: 100%;
-    }
-  }

+ 0 - 617
src/mol-app/skin/bootstrap/forms.scss

@@ -1,617 +0,0 @@
-//
-// Forms
-// --------------------------------------------------
-
-
-// Normalize non-controls
-//
-// Restyle and baseline non-control form elements.
-
-fieldset {
-    padding: 0;
-    margin: 0;
-    border: 0;
-    // Chrome and Firefox set a `min-width: min-content;` on fieldsets,
-    // so we reset that to ensure it behaves more like a standard block element.
-    // See https://github.com/twbs/bootstrap/issues/12359.
-    min-width: 0;
-  }
-
-  legend {
-    display: block;
-    width: 100%;
-    padding: 0;
-    margin-bottom: $line-height-computed;
-    font-size: ($font-size-base * 1.5);
-    line-height: inherit;
-    color: $legend-color;
-    border: 0;
-    border-bottom: 1px solid $legend-border-color;
-  }
-
-  label {
-    display: inline-block;
-    max-width: 100%; // Force IE8 to wrap long content (see https://github.com/twbs/bootstrap/issues/13141)
-    margin-bottom: 5px;
-    font-weight: bold;
-  }
-
-
-  // Normalize form controls
-  //
-  // While most of our form styles require extra classes, some basic normalization
-  // is required to ensure optimum display with or without those classes to better
-  // address browser inconsistencies.
-
-  // Override content-box in Normalize (* isn't specific enough)
-  input[type="search"] {
-    @include box-sizing(border-box);
-  }
-
-  // Position radios and checkboxes better
-  input[type="radio"],
-  input[type="checkbox"] {
-    margin: 4px 0 0;
-    margin-top: 1px \9; // IE8-9
-    line-height: normal;
-  }
-
-  input[type="file"] {
-    display: block;
-  }
-
-  // Make range inputs behave like textual form controls
-  input[type="range"] {
-    display: block;
-    width: 100%;
-  }
-
-  // Make multiple select elements height not fixed
-  select[multiple],
-  select[size] {
-    height: auto;
-  }
-
-  // Focus for file, radio, and checkbox
-  input[type="file"]:focus,
-  input[type="radio"]:focus,
-  input[type="checkbox"]:focus {
-    @include tab-focus;
-  }
-
-  // Adjust output element
-  output {
-    display: block;
-    padding-top: ($padding-base-vertical + 1);
-    font-size: $font-size-base;
-    line-height: $line-height-base;
-    color: $input-color;
-  }
-
-
-  // Common form controls
-  //
-  // Shared size and type resets for form controls. Apply `.molstar-form-control` to any
-  // of the following form controls:
-  //
-  // select
-  // textarea
-  // input[type="text"]
-  // input[type="password"]
-  // input[type="datetime"]
-  // input[type="datetime-local"]
-  // input[type="date"]
-  // input[type="month"]
-  // input[type="time"]
-  // input[type="week"]
-  // input[type="number"]
-  // input[type="email"]
-  // input[type="url"]
-  // input[type="search"]
-  // input[type="tel"]
-  // input[type="color"]
-
-  .molstar-form-control {
-    display: block;
-    width: 100%;
-    height: $input-height-base; // Make inputs at least the height of their button counterpart (base line-height + padding + border)
-    padding: $padding-base-vertical $padding-base-horizontal;
-    font-size: $font-size-base;
-    line-height: $line-height-base;
-    color: $input-color;
-    background-color: $input-bg;
-    background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214
-    border: 1px solid $input-border;
-    border-radius: $input-border-radius; // Note: This has no effect on <select>s in some browsers, due to the limited stylability of <select>s in CSS.
-    //@include box-shadow(none);//inset 0 1px 1px rgba(0,0,0,.075));
-    //@include transition(border-color ease-in-out .15s, box-shadow ease-in-out .15s);
-
-    // Customize the `:focus` state to imitate native WebKit styles.
-    @include molstar-form-control-focus;
-
-    // Placeholder
-    @include placeholder;
-
-    // Unstyle the caret on `<select>`s in IE10+.
-    &::-ms-expand {
-      border: 0;
-      background-color: transparent;
-    }
-
-    // Disabled and read-only inputs
-    //
-    // HTML5 says that controls under a fieldset > legend:first-child won't be
-    // disabled if the fieldset is disabled. Due to implementation difficulty, we
-    // don't honor that edge case; we style them as disabled anyway.
-    &[disabled],
-    &[readonly],
-    fieldset[disabled] & {
-      background-color: $input-bg-disabled;
-      opacity: 1; // iOS fix for unreadable disabled content; see https://github.com/twbs/bootstrap/issues/11655
-    }
-
-    &[disabled],
-    fieldset[disabled] & {
-      cursor: $cursor-disabled;
-    }
-
-    // [converter] extracted textarea& to textarea.molstar-form-control
-  }
-
-  // Reset height for `textarea`s
-  textarea.molstar-form-control {
-    height: auto;
-  }
-
-
-  // Search inputs in iOS
-  //
-  // This overrides the extra rounded corners on search inputs in iOS so that our
-  // `.molstar-form-control` class can properly style them. Note that this cannot simply
-  // be added to `.molstar-form-control` as it's not specific enough. For details, see
-  // https://github.com/twbs/bootstrap/issues/11586.
-
-  input[type="search"] {
-    -webkit-appearance: none;
-  }
-
-
-  // Special styles for iOS temporal inputs
-  //
-  // In Mobile Safari, setting `display: block` on temporal inputs causes the
-  // text within the input to become vertically misaligned. As a workaround, we
-  // set a pixel line-height that matches the given height of the input, but only
-  // for Safari. See https://bugs.webkit.org/show_bug.cgi?id=139848
-  //
-  // Note that as of 8.3, iOS doesn't support `datetime` or `week`.
-
-  @media screen and (-webkit-min-device-pixel-ratio: 0) {
-    input[type="date"],
-    input[type="time"],
-    input[type="datetime-local"],
-    input[type="month"] {
-      &.molstar-form-control {
-        line-height: $input-height-base;
-      }
-
-      &.input-sm,
-      .input-group-sm & {
-        line-height: $input-height-small;
-      }
-
-      &.input-lg,
-      .input-group-lg & {
-        line-height: $input-height-large;
-      }
-    }
-  }
-
-
-  // Form groups
-  //
-  // Designed to help with the organization and spacing of vertical forms. For
-  // horizontal forms, use the predefined grid classes.
-
-  .form-group {
-    margin-bottom: $form-group-margin-bottom;
-  }
-
-
-  // Checkboxes and radios
-  //
-  // Indent the labels to position radios/checkboxes as hanging controls.
-
-  .radio,
-  .checkbox {
-    position: relative;
-    display: block;
-    margin-top: 10px;
-    margin-bottom: 10px;
-
-    label {
-      min-height: $line-height-computed; // Ensure the input doesn't jump when there is no text
-      padding-left: 20px;
-      margin-bottom: 0;
-      font-weight: normal;
-      cursor: pointer;
-    }
-  }
-  .radio input[type="radio"],
-  .radio-inline input[type="radio"],
-  .checkbox input[type="checkbox"],
-  .checkbox-inline input[type="checkbox"] {
-    position: absolute;
-    margin-left: -20px;
-    margin-top: 4px \9;
-  }
-
-  .radio + .radio,
-  .checkbox + .checkbox {
-    margin-top: -5px; // Move up sibling radios or checkboxes for tighter spacing
-  }
-
-  // Radios and checkboxes on same line
-  .radio-inline,
-  .checkbox-inline {
-    position: relative;
-    display: inline-block;
-    padding-left: 20px;
-    margin-bottom: 0;
-    vertical-align: middle;
-    font-weight: normal;
-    cursor: pointer;
-  }
-  .radio-inline + .radio-inline,
-  .checkbox-inline + .checkbox-inline {
-    margin-top: 0;
-    margin-left: 10px; // space out consecutive inline controls
-  }
-
-  // Apply same disabled cursor tweak as for inputs
-  // Some special care is needed because <label>s don't inherit their parent's `cursor`.
-  //
-  // Note: Neither radios nor checkboxes can be readonly.
-  input[type="radio"],
-  input[type="checkbox"] {
-    &[disabled],
-    &.disabled,
-    fieldset[disabled] & {
-      cursor: $cursor-disabled;
-    }
-  }
-  // These classes are used directly on <label>s
-  .radio-inline,
-  .checkbox-inline {
-    &.disabled,
-    fieldset[disabled] & {
-      cursor: $cursor-disabled;
-    }
-  }
-  // These classes are used on elements with <label> descendants
-  .radio,
-  .checkbox {
-    &.disabled,
-    fieldset[disabled] & {
-      label {
-        cursor: $cursor-disabled;
-      }
-    }
-  }
-
-
-  // Static form control text
-  //
-  // Apply class to a `p` element to make any string of text align with labels in
-  // a horizontal form layout.
-
-  .molstar-form-control-static {
-    // Size it appropriately next to real form controls
-    padding-top: ($padding-base-vertical + 1);
-    padding-bottom: ($padding-base-vertical + 1);
-    // Remove default margin from `p`
-    margin-bottom: 0;
-    min-height: ($line-height-computed + $font-size-base);
-
-    &.input-lg,
-    &.input-sm {
-      padding-left: 0;
-      padding-right: 0;
-    }
-  }
-
-
-  // Form control sizing
-  //
-  // Build on `.molstar-form-control` with modifier classes to decrease or increase the
-  // height and font-size of form controls.
-  //
-  // The `.form-group-* molstar-form-control` variations are sadly duplicated to avoid the
-  // issue documented in https://github.com/twbs/bootstrap/issues/15074.
-
-  @include input-size('.input-sm', $input-height-small, $padding-small-vertical, $padding-small-horizontal, $font-size-small, $line-height-small, $input-border-radius-small);
-  .form-group-sm {
-    .molstar-form-control {
-      height: $input-height-small;
-      padding: $padding-small-vertical $padding-small-horizontal;
-      font-size: $font-size-small;
-      line-height: $line-height-small;
-      border-radius: $input-border-radius-small;
-    }
-    select.molstar-form-control {
-      height: $input-height-small;
-      line-height: $input-height-small;
-    }
-    textarea.molstar-form-control,
-    select[multiple].molstar-form-control {
-      height: auto;
-    }
-    .molstar-form-control-static {
-      height: $input-height-small;
-      min-height: ($line-height-computed + $font-size-small);
-      padding: ($padding-small-vertical + 1) $padding-small-horizontal;
-      font-size: $font-size-small;
-      line-height: $line-height-small;
-    }
-  }
-
-  @include input-size('.input-lg', $input-height-large, $padding-large-vertical, $padding-large-horizontal, $font-size-large, $line-height-large, $input-border-radius-large);
-  .form-group-lg {
-    .molstar-form-control {
-      height: $input-height-large;
-      padding: $padding-large-vertical $padding-large-horizontal;
-      font-size: $font-size-large;
-      line-height: $line-height-large;
-      border-radius: $input-border-radius-large;
-    }
-    select.molstar-form-control {
-      height: $input-height-large;
-      line-height: $input-height-large;
-    }
-    textarea.molstar-form-control,
-    select[multiple].molstar-form-control {
-      height: auto;
-    }
-    .molstar-form-control-static {
-      height: $input-height-large;
-      min-height: ($line-height-computed + $font-size-large);
-      padding: ($padding-large-vertical + 1) $padding-large-horizontal;
-      font-size: $font-size-large;
-      line-height: $line-height-large;
-    }
-  }
-
-
-  // Form control feedback states
-  //
-  // Apply contextual and semantic states to individual form controls.
-
-  .has-feedback {
-    // Enable absolute positioning
-    position: relative;
-
-    // Ensure icons don't overlap text
-    .molstar-form-control {
-      padding-right: ($input-height-base * 1.25);
-    }
-  }
-  // Feedback icon (requires .glyphicon classes)
-  .molstar-form-control-feedback {
-    position: absolute;
-    top: 0;
-    right: 0;
-    z-index: 2; // Ensure icon is above input groups
-    display: block;
-    width: $input-height-base;
-    height: $input-height-base;
-    line-height: $input-height-base;
-    text-align: center;
-    pointer-events: none;
-  }
-  .input-lg + .molstar-form-control-feedback,
-  .input-group-lg + .molstar-form-control-feedback,
-  .form-group-lg .molstar-form-control + .molstar-form-control-feedback {
-    width: $input-height-large;
-    height: $input-height-large;
-    line-height: $input-height-large;
-  }
-  .input-sm + .molstar-form-control-feedback,
-  .input-group-sm + .molstar-form-control-feedback,
-  .form-group-sm .molstar-form-control + .molstar-form-control-feedback {
-    width: $input-height-small;
-    height: $input-height-small;
-    line-height: $input-height-small;
-  }
-
-  // Feedback states
-  .has-success {
-    @include molstar-form-control-validation($state-success-text, $state-success-text, $state-success-bg);
-  }
-  .has-warning {
-    @include molstar-form-control-validation($state-warning-text, $state-warning-text, $state-warning-bg);
-  }
-  .has-error {
-    @include molstar-form-control-validation($state-danger-text, $state-danger-text, $state-danger-bg);
-  }
-
-  // Reposition feedback icon if input has visible label above
-  .has-feedback label {
-
-    & ~ .molstar-form-control-feedback {
-      top: ($line-height-computed + 5); // Height of the `label` and its margin
-    }
-    &.sr-only ~ .molstar-form-control-feedback {
-      top: 0;
-    }
-  }
-
-
-  // Help text
-  //
-  // Apply to any element you wish to create light text for placement immediately
-  // below a form control. Use for general help, formatting, or instructional text.
-
-  .help-block {
-    display: block; // account for any element using help-block
-    margin-top: 5px;
-    margin-bottom: 10px;
-    color: lighten($text-color, 25%); // lighten the text some for contrast
-  }
-
-
-  // Inline forms
-  //
-  // Make forms appear inline(-block) by adding the `.form-inline` class. Inline
-  // forms begin stacked on extra small (mobile) devices and then go inline when
-  // viewports reach <768px.
-  //
-  // Requires wrapping inputs and labels with `.form-group` for proper display of
-  // default HTML form controls and our custom form controls (e.g., input groups).
-  //
-  // Heads up! This is mixin-ed into `.navbar-form` in navbars.less.
-
-  // [converter] extracted from `.form-inline` for libsass compatibility
-  @mixin form-inline {
-
-    // Kick in the inline
-    @media (min-width: $screen-sm-min) {
-      // Inline-block all the things for "inline"
-      .form-group {
-        display: inline-block;
-        margin-bottom: 0;
-        vertical-align: middle;
-      }
-
-      // In navbar-form, allow folks to *not* use `.form-group`
-      .molstar-form-control {
-        display: inline-block;
-        width: auto; // Prevent labels from stacking above inputs in `.form-group`
-        vertical-align: middle;
-      }
-
-      // Make static controls behave like regular ones
-      .molstar-form-control-static {
-        display: inline-block;
-      }
-
-      .input-group {
-        display: inline-table;
-        vertical-align: middle;
-
-        .input-group-addon,
-        .input-group-molstar-btn,
-        .molstar-form-control {
-          width: auto;
-        }
-      }
-
-      // Input groups need that 100% width though
-      .input-group > .molstar-form-control {
-        width: 100%;
-      }
-
-      .control-label {
-        margin-bottom: 0;
-        vertical-align: middle;
-      }
-
-      // Remove default margin on radios/checkboxes that were used for stacking, and
-      // then undo the floating of radios and checkboxes to match.
-      .radio,
-      .checkbox {
-        display: inline-block;
-        margin-top: 0;
-        margin-bottom: 0;
-        vertical-align: middle;
-
-        label {
-          padding-left: 0;
-        }
-      }
-      .radio input[type="radio"],
-      .checkbox input[type="checkbox"] {
-        position: relative;
-        margin-left: 0;
-      }
-
-      // Re-override the feedback icon.
-      .has-feedback .molstar-form-control-feedback {
-        top: 0;
-      }
-    }
-  }
-  // [converter] extracted as `@mixin form-inline` for libsass compatibility
-  .form-inline {
-    @include form-inline;
-  }
-
-
-
-  // Horizontal forms
-  //
-  // Horizontal forms are built on grid classes and allow you to create forms with
-  // labels on the left and inputs on the right.
-
-  .form-horizontal {
-
-    // Consistent vertical alignment of radios and checkboxes
-    //
-    // Labels also get some reset styles, but that is scoped to a media query below.
-    .radio,
-    .checkbox,
-    .radio-inline,
-    .checkbox-inline {
-      margin-top: 0;
-      margin-bottom: 0;
-      padding-top: ($padding-base-vertical + 1); // Default padding plus a border
-    }
-    // Account for padding we're adding to ensure the alignment and of help text
-    // and other content below items
-    .radio,
-    .checkbox {
-      min-height: ($line-height-computed + ($padding-base-vertical + 1));
-    }
-
-    // Make form groups behave like rows
-    .form-group {
-      @include make-row;
-    }
-
-    // Reset spacing and right align labels, but scope to media queries so that
-    // labels on narrow viewports stack the same as a default form example.
-    @media (min-width: $screen-sm-min) {
-      .control-label {
-        text-align: right;
-        margin-bottom: 0;
-        padding-top: ($padding-base-vertical + 1); // Default padding plus a border
-      }
-    }
-
-    // Validation states
-    //
-    // Reposition the icon because it's now within a grid column and columns have
-    // `position: relative;` on them. Also accounts for the grid gutter padding.
-    .has-feedback .molstar-form-control-feedback {
-      right: floor(($grid-gutter-width / 2));
-    }
-
-    // Form group sizes
-    //
-    // Quick utility class for applying `.input-lg` and `.input-sm` styles to the
-    // inputs and labels within a `.form-group`.
-    .form-group-lg {
-      @media (min-width: $screen-sm-min) {
-        .control-label {
-          padding-top: ($padding-large-vertical + 1);
-          font-size: $font-size-large;
-        }
-      }
-    }
-    .form-group-sm {
-      @media (min-width: $screen-sm-min) {
-        .control-label {
-          padding-top: ($padding-small-vertical + 1);
-          font-size: $font-size-small;
-        }
-      }
-    }
-  }

+ 0 - 171
src/mol-app/skin/bootstrap/input-groups.scss

@@ -1,171 +0,0 @@
-//
-// Input groups
-// --------------------------------------------------
-
-// Base styles
-// -------------------------
-.input-group {
-    position: relative; // For dropdowns
-    display: table;
-    border-collapse: separate; // prevent input groups from inheriting border styles from table cells when placed within a table
-
-    // Undo padding and float of grid classes
-    &[class*="col-"] {
-      float: none;
-      padding-left: 0;
-      padding-right: 0;
-    }
-
-    .molstar-form-control {
-      // Ensure that the input is always above the *appended* addon button for
-      // proper border colors.
-      position: relative;
-      z-index: 2;
-
-      // IE9 fubars the placeholder attribute in text inputs and the arrows on
-      // select elements in input groups. To fix it, we float the input. Details:
-      // https://github.com/twbs/bootstrap/issues/11561#issuecomment-28936855
-      float: left;
-
-      width: 100%;
-      margin-bottom: 0;
-
-      &:focus {
-        z-index: 3;
-      }
-    }
-  }
-
-  // Sizing options
-  //
-  // Remix the default form control sizing classes into new ones for easier
-  // manipulation.
-
-  .input-group-lg > .molstar-form-control,
-  .input-group-lg > .input-group-addon,
-  .input-group-lg > .input-group-molstar-btn > .molstar-btn {
-    @extend .input-lg;
-  }
-  .input-group-sm > .molstar-form-control,
-  .input-group-sm > .input-group-addon,
-  .input-group-sm > .input-group-molstar-btn > .molstar-btn {
-    @extend .input-sm;
-  }
-
-
-  // Display as table-cell
-  // -------------------------
-  .input-group-addon,
-  .input-group-molstar-btn,
-  .input-group .molstar-form-control {
-    display: table-cell;
-
-    &:not(:first-child):not(:last-child) {
-      border-radius: 0;
-    }
-  }
-  // Addon and addon wrapper for buttons
-  .input-group-addon,
-  .input-group-molstar-btn {
-    width: 1%;
-    white-space: nowrap;
-    vertical-align: middle; // Match the inputs
-  }
-
-  // Text input groups
-  // -------------------------
-  .input-group-addon {
-    padding: $padding-base-vertical $padding-base-horizontal;
-    font-size: $font-size-base;
-    font-weight: normal;
-    line-height: 1;
-    color: $input-color;
-    text-align: center;
-    background-color: $input-group-addon-bg;
-    border: 1px solid $input-group-addon-border-color;
-    border-radius: $input-border-radius;
-
-    // Sizing
-    &.input-sm {
-      padding: $padding-small-vertical $padding-small-horizontal;
-      font-size: $font-size-small;
-      border-radius: $input-border-radius-small;
-    }
-    &.input-lg {
-      padding: $padding-large-vertical $padding-large-horizontal;
-      font-size: $font-size-large;
-      border-radius: $input-border-radius-large;
-    }
-
-    // Nuke default margins from checkboxes and radios to vertically center within.
-    input[type="radio"],
-    input[type="checkbox"] {
-      margin-top: 0;
-    }
-  }
-
-  // Reset rounded corners
-  .input-group .molstar-form-control:first-child,
-  .input-group-addon:first-child,
-  .input-group-molstar-btn:first-child > .molstar-btn,
-  .input-group-molstar-btn:first-child > .molstar-btn-group > .molstar-btn,
-  .input-group-molstar-btn:first-child > .dropdown-toggle,
-  .input-group-molstar-btn:last-child > .molstar-btn:not(:last-child):not(.dropdown-toggle),
-  .input-group-molstar-btn:last-child > .molstar-btn-group:not(:last-child) > .molstar-btn {
-    @include border-right-radius(0);
-  }
-  .input-group-addon:first-child {
-    border-right: 0;
-  }
-  .input-group .molstar-form-control:last-child,
-  .input-group-addon:last-child,
-  .input-group-molstar-btn:last-child > .molstar-btn,
-  .input-group-molstar-btn:last-child > .molstar-btn-group > .molstar-btn,
-  .input-group-molstar-btn:last-child > .dropdown-toggle,
-  .input-group-molstar-btn:first-child > .molstar-btn:not(:first-child),
-  .input-group-molstar-btn:first-child > .molstar-btn-group:not(:first-child) > .molstar-btn {
-    @include border-left-radius(0);
-  }
-  .input-group-addon:last-child {
-    border-left: 0;
-  }
-
-  // Button input groups
-  // -------------------------
-  .input-group-molstar-btn {
-    position: relative;
-    // Jankily prevent input button groups from wrapping with `white-space` and
-    // `font-size` in combination with `inline-block` on buttons.
-    font-size: 0;
-    white-space: nowrap;
-
-    // Negative margin for spacing, position for bringing hovered/focused/actived
-    // element above the siblings.
-    > .molstar-btn {
-      position: relative;
-      + .molstar-btn {
-        margin-left: -1px;
-      }
-      // Bring the "active" button to the front
-      &:hover,
-      &:focus,
-      &:active {
-        z-index: 2;
-      }
-    }
-
-    // Negative margin to only have a 1px border between the two
-    &:first-child {
-      > .molstar-btn,
-      > .molstar-btn-group {
-        margin-right: -1px;
-      }
-    }
-    &:last-child {
-      > .molstar-btn,
-      > .molstar-btn-group {
-        z-index: 2;
-        margin-left: -1px;
-      }
-    }
-  }

+ 0 - 66
src/mol-app/skin/bootstrap/labels.scss

@@ -1,66 +0,0 @@
-//
-// Labels
-// --------------------------------------------------
-
-.label {
-    display: inline;
-    padding: .2em .6em .3em;
-    font-size: 75%;
-    font-weight: bold;
-    line-height: 1;
-    color: $label-color;
-    text-align: center;
-    white-space: nowrap;
-    vertical-align: baseline;
-    border-radius: .25em;
-
-    // [converter] extracted a& to a.label
-
-    // Empty labels collapse automatically (not available in IE8)
-    &:empty {
-      display: none;
-    }
-
-    // Quick fix for labels in buttons
-    .molstar-btn & {
-      position: relative;
-      top: -1px;
-    }
-  }
-
-  // Add hover effects, but only for links
-  a.label {
-    &:hover,
-    &:focus {
-      color: $label-link-hover-color;
-      text-decoration: none;
-      cursor: pointer;
-    }
-  }
-
-  // Colors
-  // Contextual variations (linked labels get darker on :hover)
-
-  .label-default {
-    @include label-variant($label-default-bg);
-  }
-
-  .label-primary {
-    @include label-variant($label-primary-bg);
-  }
-
-  .label-success {
-    @include label-variant($label-success-bg);
-  }
-
-  .label-info {
-    @include label-variant($label-info-bg);
-  }
-
-  .label-warning {
-    @include label-variant($label-warning-bg);
-  }
-
-  .label-danger {
-    @include label-variant($label-danger-bg);
-  }

+ 0 - 40
src/mol-app/skin/bootstrap/mixins.scss

@@ -1,40 +0,0 @@
-// Mixins
-// --------------------------------------------------
-
-// Utilities
-// @import "mixins/hide-text";
-@import "mixins/opacity";
-@import "mixins/image";
-@import "mixins/labels";
-// @import "mixins/reset-filter";
-// @import "mixins/resize";
-// @import "mixins/responsive-visibility";
-// @import "mixins/size";
-@import "mixins/tab-focus";
-// @import "mixins/reset-text";
-@import "mixins/text-emphasis";
-@import "mixins/text-overflow";
-@import "mixins/vendor-prefixes";
-
-// Components
-// @import "mixins/alerts";
-@import "mixins/buttons";
-// @import "mixins/panels";
-// @import "mixins/pagination";
-// @import "mixins/list-group";
-// @import "mixins/nav-divider";
-@import "mixins/forms";
-// @import "mixins/progress-bar";
-// @import "mixins/table-row";
-
-// Skins
-@import "mixins/background-variant";
-@import "mixins/border-radius";
-// @import "mixins/gradients";
-
-// Layout
-@import "mixins/clearfix";
-// @import "mixins/center-block";
-// @import "mixins/nav-vertical-align";
-// @import "mixins/grid-framework";
-@import "mixins/grid";

+ 0 - 12
src/mol-app/skin/bootstrap/mixins/background-variant.scss

@@ -1,12 +0,0 @@
-// Contextual backgrounds
-
-// [converter] $parent hack
-@mixin bg-variant($parent, $color) {
-    #{$parent} {
-        background-color: $color;
-    }
-    a#{$parent}:hover,
-    a#{$parent}:focus {
-        background-color: darken($color, 10%);
-    }
-}

+ 0 - 18
src/mol-app/skin/bootstrap/mixins/border-radius.scss

@@ -1,18 +0,0 @@
-// Single side border-radius
-
-@mixin border-top-radius($radius) {
-    border-top-right-radius: $radius;
-    border-top-left-radius: $radius;
-}
-@mixin border-right-radius($radius) {
-    border-bottom-right-radius: $radius;
-    border-top-right-radius: $radius;
-}
-@mixin border-bottom-radius($radius) {
-    border-bottom-right-radius: $radius;
-    border-bottom-left-radius: $radius;
-}
-@mixin border-left-radius($radius) {
-    border-bottom-left-radius: $radius;
-    border-top-left-radius: $radius;
-}

+ 0 - 65
src/mol-app/skin/bootstrap/mixins/buttons.scss

@@ -1,65 +0,0 @@
-// Button variants
-//
-// Easily pump out default styles, as well as :hover, :focus, :active,
-// and disabled options for all buttons
-
-@mixin button-variant($color, $background, $border) {
-    color: $color;
-    background-color: $background;
-    border-color: $border;
-
-    &:focus,
-    &.focus {
-      color: $color;
-      background-color: darken($background, 10%);
-          border-color: darken($border, 25%);
-    }
-    &:hover {
-      color: $color;
-      background-color: darken($background, 10%);
-          border-color: darken($border, 12%);
-    }
-    &:active,
-    &.active,
-    .open > &.dropdown-toggle {
-      color: $color;
-      background-color: darken($background, 10%);
-          border-color: darken($border, 12%);
-
-      &:hover,
-      &:focus,
-      &.focus {
-        color: $color;
-        background-color: darken($background, 17%);
-            border-color: darken($border, 25%);
-      }
-    }
-    &:active,
-    &.active,
-    .open > &.dropdown-toggle {
-      background-image: none;
-    }
-    &.disabled,
-    &[disabled],
-    fieldset[disabled] & {
-      &:hover,
-      &:focus,
-      &.focus {
-        background-color: $background;
-            border-color: $border;
-      }
-    }
-
-    .badge {
-      color: $background;
-      background-color: $color;
-    }
-  }
-
-  // Button sizes
-  @mixin button-size($padding-vertical, $padding-horizontal, $font-size, $line-height, $border-radius) {
-    padding: $padding-vertical $padding-horizontal;
-    font-size: $font-size;
-    line-height: $line-height;
-    border-radius: $border-radius;
-  }

+ 0 - 22
src/mol-app/skin/bootstrap/mixins/clearfix.scss

@@ -1,22 +0,0 @@
-// Clearfix
-//
-// For modern browsers
-// 1. The space content is one way to avoid an Opera bug when the
-//    contenteditable attribute is included anywhere else in the document.
-//    Otherwise it causes space to appear at the top and bottom of elements
-//    that are clearfixed.
-// 2. The use of `table` rather than `block` is only necessary if using
-//    `:before` to contain the top-margins of child elements.
-//
-// Source: http://nicolasgallagher.com/micro-clearfix-hack/
-
-@mixin clearfix() {
-    &:before,
-    &:after {
-        content: " "; // 1
-        display: table; // 2
-    }
-    &:after {
-        clear: both;
-    }
-}

+ 0 - 88
src/mol-app/skin/bootstrap/mixins/forms.scss

@@ -1,88 +0,0 @@
-// Form validation states
-//
-// Used in forms.less to generate the form validation CSS for warnings, errors,
-// and successes.
-
-@mixin molstar-form-control-validation($text-color: #555, $border-color: #ccc, $background-color: #f5f5f5) {
-    // Color the label and help text
-    .help-block,
-    .control-label,
-    .radio,
-    .checkbox,
-    .radio-inline,
-    .checkbox-inline,
-    &.radio label,
-    &.checkbox label,
-    &.radio-inline label,
-    &.checkbox-inline label  {
-      color: $text-color;
-    }
-    // Set the border and box shadow on specific inputs to match
-    .molstar-form-control {
-      border-color: $border-color;
-      @include box-shadow(inset 0 1px 1px rgba(0,0,0,.075)); // Redeclare so transitions work
-      &:focus {
-        border-color: darken($border-color, 10%);
-        $shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 6px lighten($border-color, 20%);
-        @include box-shadow($shadow);
-      }
-    }
-    // Set validation states also for addons
-    .input-group-addon {
-      color: $text-color;
-      border-color: $border-color;
-      background-color: $background-color;
-    }
-    // Optional feedback icon
-    .molstar-form-control-feedback {
-      color: $text-color;
-    }
-  }
-
-
-  // Form control focus state
-  //
-  // Generate a customized focus state and for any input with the specified color,
-  // which defaults to the `$input-border-focus` variable.
-  //
-  // We highly encourage you to not customize the default value, but instead use
-  // this to tweak colors on an as-needed basis. This aesthetic change is based on
-  // WebKit's default styles, but applicable to a wider range of browsers. Its
-  // usability and accessibility should be taken into account with any change.
-  //
-  // Example usage: change the default blue border and shadow to white for better
-  // contrast against a dark gray background.
-  @mixin molstar-form-control-focus($color: $input-border-focus) {
-    $color-rgba: rgba(red($color), green($color), blue($color), .6);
-    &:focus {
-      border-color: $color;
-      outline: 0;
-      @include box-shadow(inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px $color-rgba);
-    }
-  }
-
-  // Form control sizing
-  //
-  // Relative text size, padding, and border-radii changes for form controls. For
-  // horizontal sizing, wrap controls in the predefined grid classes. `<select>`
-  // element gets special love because it's special, and that's a fact!
-  // [converter] $parent hack
-  @mixin input-size($parent, $input-height, $padding-vertical, $padding-horizontal, $font-size, $line-height, $border-radius) {
-    #{$parent} {
-      height: $input-height;
-      padding: $padding-vertical $padding-horizontal;
-      font-size: $font-size;
-      line-height: $line-height;
-      border-radius: $border-radius;
-    }
-
-    select#{$parent} {
-      height: $input-height;
-      line-height: $input-height;
-    }
-
-    textarea#{$parent},
-    select[multiple]#{$parent} {
-      height: auto;
-    }
-  }

+ 0 - 122
src/mol-app/skin/bootstrap/mixins/grid.scss

@@ -1,122 +0,0 @@
-// Grid system
-//
-// Generate semantic grid columns with these mixins.
-
-// Centered container element
-@mixin container-fixed($gutter: $grid-gutter-width) {
-    margin-right: auto;
-    margin-left: auto;
-    padding-left:  floor(($gutter / 2));
-    padding-right: ceil(($gutter / 2));
-    @include clearfix;
-  }
-
-  // Creates a wrapper for a series of columns
-  @mixin make-row($gutter: $grid-gutter-width) {
-    margin-left:  ceil(($gutter / -2));
-    margin-right: floor(($gutter / -2));
-    @include clearfix;
-  }
-
-  // Generate the extra small columns
-  @mixin make-xs-column($columns, $gutter: $grid-gutter-width) {
-    position: relative;
-    float: left;
-    width: percentage(($columns / $grid-columns));
-    min-height: 1px;
-    padding-left:  ($gutter / 2);
-    padding-right: ($gutter / 2);
-  }
-  @mixin make-xs-column-offset($columns) {
-    margin-left: percentage(($columns / $grid-columns));
-  }
-  @mixin make-xs-column-push($columns) {
-    left: percentage(($columns / $grid-columns));
-  }
-  @mixin make-xs-column-pull($columns) {
-    right: percentage(($columns / $grid-columns));
-  }
-
-  // Generate the small columns
-  @mixin make-sm-column($columns, $gutter: $grid-gutter-width) {
-    position: relative;
-    min-height: 1px;
-    padding-left:  ($gutter / 2);
-    padding-right: ($gutter / 2);
-
-    @media (min-width: $screen-sm-min) {
-      float: left;
-      width: percentage(($columns / $grid-columns));
-    }
-  }
-  @mixin make-sm-column-offset($columns) {
-    @media (min-width: $screen-sm-min) {
-      margin-left: percentage(($columns / $grid-columns));
-    }
-  }
-  @mixin make-sm-column-push($columns) {
-    @media (min-width: $screen-sm-min) {
-      left: percentage(($columns / $grid-columns));
-    }
-  }
-  @mixin make-sm-column-pull($columns) {
-    @media (min-width: $screen-sm-min) {
-      right: percentage(($columns / $grid-columns));
-    }
-  }
-
-  // Generate the medium columns
-  @mixin make-md-column($columns, $gutter: $grid-gutter-width) {
-    position: relative;
-    min-height: 1px;
-    padding-left:  ($gutter / 2);
-    padding-right: ($gutter / 2);
-
-    @media (min-width: $screen-md-min) {
-      float: left;
-      width: percentage(($columns / $grid-columns));
-    }
-  }
-  @mixin make-md-column-offset($columns) {
-    @media (min-width: $screen-md-min) {
-      margin-left: percentage(($columns / $grid-columns));
-    }
-  }
-  @mixin make-md-column-push($columns) {
-    @media (min-width: $screen-md-min) {
-      left: percentage(($columns / $grid-columns));
-    }
-  }
-  @mixin make-md-column-pull($columns) {
-    @media (min-width: $screen-md-min) {
-      right: percentage(($columns / $grid-columns));
-    }
-  }
-
-  // Generate the large columns
-  @mixin make-lg-column($columns, $gutter: $grid-gutter-width) {
-    position: relative;
-    min-height: 1px;
-    padding-left:  ($gutter / 2);
-    padding-right: ($gutter / 2);
-
-    @media (min-width: $screen-lg-min) {
-      float: left;
-      width: percentage(($columns / $grid-columns));
-    }
-  }
-  @mixin make-lg-column-offset($columns) {
-    @media (min-width: $screen-lg-min) {
-      margin-left: percentage(($columns / $grid-columns));
-    }
-  }
-  @mixin make-lg-column-push($columns) {
-    @media (min-width: $screen-lg-min) {
-      left: percentage(($columns / $grid-columns));
-    }
-  }
-  @mixin make-lg-column-pull($columns) {
-    @media (min-width: $screen-lg-min) {
-      right: percentage(($columns / $grid-columns));
-    }
-  }

+ 0 - 33
src/mol-app/skin/bootstrap/mixins/image.scss

@@ -1,33 +0,0 @@
-// Image Mixins
-// - Responsive image
-// - Retina image
-
-
-// Responsive image
-//
-// Keep images from scaling beyond the width of their parents.
-@mixin img-responsive($display: block) {
-    display: $display;
-    max-width: 100%; // Part 1: Set a maximum relative to the parent
-    height: auto; // Part 2: Scale the height according to the width, otherwise you get stretching
-}
-
-
-// Retina image
-//
-// Short retina mixin for setting background-image and -size. Note that the
-// spelling of `min--moz-device-pixel-ratio` is intentional.
-@mixin img-retina($file-1x, $file-2x, $width-1x, $height-1x) {
-    background-image: url(if($bootstrap-sass-asset-helper, twbs-image-path("#{$file-1x}"), "#{$file-1x}"));
-
-    @media
-    only screen and (-webkit-min-device-pixel-ratio: 2),
-    only screen and (   min--moz-device-pixel-ratio: 2),
-    only screen and (     -o-min-device-pixel-ratio: 2/1),
-    only screen and (        min-device-pixel-ratio: 2),
-    only screen and (                min-resolution: 192dpi),
-    only screen and (                min-resolution: 2dppx) {
-      background-image: url(if($bootstrap-sass-asset-helper, twbs-image-path("#{$file-2x}"), "#{$file-2x}"));
-      background-size: $width-1x $height-1x;
-    }
-}

+ 0 - 12
src/mol-app/skin/bootstrap/mixins/labels.scss

@@ -1,12 +0,0 @@
-// Labels
-
-@mixin label-variant($color) {
-    background-color: $color;
-
-    &[href] {
-        &:hover,
-        &:focus {
-            background-color: darken($color, 10%);
-        }
-    }
-}

+ 0 - 8
src/mol-app/skin/bootstrap/mixins/opacity.scss

@@ -1,8 +0,0 @@
-// Opacity
-
-@mixin opacity($opacity) {
-    opacity: $opacity;
-    // IE8 filter
-    $opacity-ie: ($opacity * 100);
-    filter: alpha(opacity=$opacity-ie);
-}

+ 0 - 9
src/mol-app/skin/bootstrap/mixins/tab-focus.scss

@@ -1,9 +0,0 @@
-// WebKit-style focus
-
-@mixin tab-focus() {
-    // Default
-    outline: thin dotted;
-    // WebKit
-    outline: 5px auto -webkit-focus-ring-color;
-    outline-offset: -2px;
-}

+ 0 - 12
src/mol-app/skin/bootstrap/mixins/text-emphasis.scss

@@ -1,12 +0,0 @@
-// Typography
-
-// [converter] $parent hack
-@mixin text-emphasis-variant($parent, $color) {
-    #{$parent} {
-      color: $color;
-    }
-    a#{$parent}:hover,
-    a#{$parent}:focus {
-      color: darken($color, 10%);
-    }
-}

+ 0 - 8
src/mol-app/skin/bootstrap/mixins/text-overflow.scss

@@ -1,8 +0,0 @@
-// Text overflow
-// Requires inline-block or block for proper styling
-
-@mixin text-overflow() {
-    overflow: hidden;
-    text-overflow: ellipsis;
-    white-space: nowrap;
-}

+ 0 - 222
src/mol-app/skin/bootstrap/mixins/vendor-prefixes.scss

@@ -1,222 +0,0 @@
-// Vendor Prefixes
-//
-// All vendor mixins are deprecated as of v3.2.0 due to the introduction of
-// Autoprefixer in our Gruntfile. They have been removed in v4.
-
-// - Animations
-// - Backface visibility
-// - Box shadow
-// - Box sizing
-// - Content columns
-// - Hyphens
-// - Placeholder text
-// - Transformations
-// - Transitions
-// - User Select
-
-
-// Animations
-@mixin animation($animation) {
-    -webkit-animation: $animation;
-         -o-animation: $animation;
-            animation: $animation;
-  }
-  @mixin animation-name($name) {
-    -webkit-animation-name: $name;
-            animation-name: $name;
-  }
-  @mixin animation-duration($duration) {
-    -webkit-animation-duration: $duration;
-            animation-duration: $duration;
-  }
-  @mixin animation-timing-function($timing-function) {
-    -webkit-animation-timing-function: $timing-function;
-            animation-timing-function: $timing-function;
-  }
-  @mixin animation-delay($delay) {
-    -webkit-animation-delay: $delay;
-            animation-delay: $delay;
-  }
-  @mixin animation-iteration-count($iteration-count) {
-    -webkit-animation-iteration-count: $iteration-count;
-            animation-iteration-count: $iteration-count;
-  }
-  @mixin animation-direction($direction) {
-    -webkit-animation-direction: $direction;
-            animation-direction: $direction;
-  }
-  @mixin animation-fill-mode($fill-mode) {
-    -webkit-animation-fill-mode: $fill-mode;
-            animation-fill-mode: $fill-mode;
-  }
-
-  // Backface visibility
-  // Prevent browsers from flickering when using CSS 3D transforms.
-  // Default value is `visible`, but can be changed to `hidden`
-
-  @mixin backface-visibility($visibility) {
-    -webkit-backface-visibility: $visibility;
-       -moz-backface-visibility: $visibility;
-            backface-visibility: $visibility;
-  }
-
-  // Drop shadows
-  //
-  // Note: Deprecated `.box-shadow()` as of v3.1.0 since all of Bootstrap's
-  // supported browsers that have box shadow capabilities now support it.
-
-  @mixin box-shadow($shadow...) {
-    -webkit-box-shadow: $shadow; // iOS <4.3 & Android <4.1
-            box-shadow: $shadow;
-  }
-
-  // Box sizing
-  @mixin box-sizing($boxmodel) {
-    -webkit-box-sizing: $boxmodel;
-       -moz-box-sizing: $boxmodel;
-            box-sizing: $boxmodel;
-  }
-
-  // CSS3 Content Columns
-  @mixin content-columns($column-count, $column-gap: $grid-gutter-width) {
-    -webkit-column-count: $column-count;
-       -moz-column-count: $column-count;
-            column-count: $column-count;
-    -webkit-column-gap: $column-gap;
-       -moz-column-gap: $column-gap;
-            column-gap: $column-gap;
-  }
-
-  // Optional hyphenation
-  @mixin hyphens($mode: auto) {
-    word-wrap: break-word;
-    -webkit-hyphens: $mode;
-       -moz-hyphens: $mode;
-        -ms-hyphens: $mode; // IE10+
-         -o-hyphens: $mode;
-            hyphens: $mode;
-  }
-
-  // Placeholder text
-  @mixin placeholder($color: $input-color-placeholder) {
-    // Firefox
-    &::-moz-placeholder {
-      color: $color;
-      opacity: 1; // Override Firefox's unusual default opacity; see https://github.com/twbs/bootstrap/pull/11526
-    }
-    &:-ms-input-placeholder { color: $color; } // Internet Explorer 10+
-    &::-webkit-input-placeholder  { color: $color; } // Safari and Chrome
-  }
-
-  // Transformations
-  @mixin scale($ratio...) {
-    -webkit-transform: scale($ratio);
-        -ms-transform: scale($ratio); // IE9 only
-         -o-transform: scale($ratio);
-            transform: scale($ratio);
-  }
-
-  @mixin scaleX($ratio) {
-    -webkit-transform: scaleX($ratio);
-        -ms-transform: scaleX($ratio); // IE9 only
-         -o-transform: scaleX($ratio);
-            transform: scaleX($ratio);
-  }
-  @mixin scaleY($ratio) {
-    -webkit-transform: scaleY($ratio);
-        -ms-transform: scaleY($ratio); // IE9 only
-         -o-transform: scaleY($ratio);
-            transform: scaleY($ratio);
-  }
-  @mixin skew($x, $y) {
-    -webkit-transform: skewX($x) skewY($y);
-        -ms-transform: skewX($x) skewY($y); // See https://github.com/twbs/bootstrap/issues/4885; IE9+
-         -o-transform: skewX($x) skewY($y);
-            transform: skewX($x) skewY($y);
-  }
-  @mixin translate($x, $y) {
-    -webkit-transform: translate($x, $y);
-        -ms-transform: translate($x, $y); // IE9 only
-         -o-transform: translate($x, $y);
-            transform: translate($x, $y);
-  }
-  @mixin translate3d($x, $y, $z) {
-    -webkit-transform: translate3d($x, $y, $z);
-            transform: translate3d($x, $y, $z);
-  }
-  @mixin rotate($degrees) {
-    -webkit-transform: rotate($degrees);
-        -ms-transform: rotate($degrees); // IE9 only
-         -o-transform: rotate($degrees);
-            transform: rotate($degrees);
-  }
-  @mixin rotateX($degrees) {
-    -webkit-transform: rotateX($degrees);
-        -ms-transform: rotateX($degrees); // IE9 only
-         -o-transform: rotateX($degrees);
-            transform: rotateX($degrees);
-  }
-  @mixin rotateY($degrees) {
-    -webkit-transform: rotateY($degrees);
-        -ms-transform: rotateY($degrees); // IE9 only
-         -o-transform: rotateY($degrees);
-            transform: rotateY($degrees);
-  }
-  @mixin perspective($perspective) {
-    -webkit-perspective: $perspective;
-       -moz-perspective: $perspective;
-            perspective: $perspective;
-  }
-  @mixin perspective-origin($perspective) {
-    -webkit-perspective-origin: $perspective;
-       -moz-perspective-origin: $perspective;
-            perspective-origin: $perspective;
-  }
-  @mixin transform-origin($origin) {
-    -webkit-transform-origin: $origin;
-       -moz-transform-origin: $origin;
-        -ms-transform-origin: $origin; // IE9 only
-            transform-origin: $origin;
-  }
-
-
-  // Transitions
-
-  @mixin transition($transition...) {
-    -webkit-transition: $transition;
-         -o-transition: $transition;
-            transition: $transition;
-  }
-  @mixin transition-property($transition-property...) {
-    -webkit-transition-property: $transition-property;
-            transition-property: $transition-property;
-  }
-  @mixin transition-delay($transition-delay) {
-    -webkit-transition-delay: $transition-delay;
-            transition-delay: $transition-delay;
-  }
-  @mixin transition-duration($transition-duration...) {
-    -webkit-transition-duration: $transition-duration;
-            transition-duration: $transition-duration;
-  }
-  @mixin transition-timing-function($timing-function) {
-    -webkit-transition-timing-function: $timing-function;
-            transition-timing-function: $timing-function;
-  }
-  @mixin transition-transform($transition...) {
-    -webkit-transition: -webkit-transform $transition;
-       -moz-transition: -moz-transform $transition;
-         -o-transition: -o-transform $transition;
-            transition: transform $transition;
-  }
-
-
-  // User select
-  // For selecting text on the page
-
-  @mixin user-select($select) {
-    -webkit-user-select: $select;
-       -moz-user-select: $select;
-        -ms-user-select: $select; // IE10+
-            user-select: $select;
-  }

+ 0 - 424
src/mol-app/skin/bootstrap/normalize.scss

@@ -1,424 +0,0 @@
-/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */
-
-//
-// 1. Set default font family to sans-serif.
-// 2. Prevent iOS and IE text size adjust after device orientation change,
-//    without disabling user zoom.
-//
-
-html {
-    font-family: sans-serif; // 1
-    -ms-text-size-adjust: 100%; // 2
-    -webkit-text-size-adjust: 100%; // 2
-  }
-
-  //
-  // Remove default margin.
-  //
-
-  body {
-    margin: 0;
-  }
-
-  // HTML5 display definitions
-  // ==========================================================================
-
-  //
-  // Correct `block` display not defined for any HTML5 element in IE 8/9.
-  // Correct `block` display not defined for `details` or `summary` in IE 10/11
-  // and Firefox.
-  // Correct `block` display not defined for `main` in IE 11.
-  //
-
-  article,
-  aside,
-  details,
-  figcaption,
-  figure,
-  footer,
-  header,
-  hgroup,
-  main,
-  menu,
-  nav,
-  section,
-  summary {
-    display: block;
-  }
-
-  //
-  // 1. Correct `inline-block` display not defined in IE 8/9.
-  // 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera.
-  //
-
-  audio,
-  canvas,
-  progress,
-  video {
-    display: inline-block; // 1
-    vertical-align: baseline; // 2
-  }
-
-  //
-  // Prevent modern browsers from displaying `audio` without controls.
-  // Remove excess height in iOS 5 devices.
-  //
-
-  audio:not([controls]) {
-    display: none;
-    height: 0;
-  }
-
-  //
-  // Address `[hidden]` styling not present in IE 8/9/10.
-  // Hide the `template` element in IE 8/9/10/11, Safari, and Firefox < 22.
-  //
-
-  [hidden],
-  template {
-    display: none;
-  }
-
-  // Links
-  // ==========================================================================
-
-  //
-  // Remove the gray background color from active links in IE 10.
-  //
-
-  a {
-    background-color: transparent;
-  }
-
-  //
-  // Improve readability of focused elements when they are also in an
-  // active/hover state.
-  //
-
-  a:active,
-  a:hover {
-    outline: 0;
-  }
-
-  // Text-level semantics
-  // ==========================================================================
-
-  //
-  // Address styling not present in IE 8/9/10/11, Safari, and Chrome.
-  //
-
-  abbr[title] {
-    border-bottom: 1px dotted;
-  }
-
-  //
-  // Address style set to `bolder` in Firefox 4+, Safari, and Chrome.
-  //
-
-  b,
-  strong {
-    font-weight: bold;
-  }
-
-  //
-  // Address styling not present in Safari and Chrome.
-  //
-
-  dfn {
-    font-style: italic;
-  }
-
-  //
-  // Address variable `h1` font-size and margin within `section` and `article`
-  // contexts in Firefox 4+, Safari, and Chrome.
-  //
-
-  h1 {
-    font-size: 2em;
-    margin: 0.67em 0;
-  }
-
-  //
-  // Address styling not present in IE 8/9.
-  //
-
-  mark {
-    background: #ff0;
-    color: #000;
-  }
-
-  //
-  // Address inconsistent and variable font size in all browsers.
-  //
-
-  small {
-    font-size: 80%;
-  }
-
-  //
-  // Prevent `sub` and `sup` affecting `line-height` in all browsers.
-  //
-
-  sub,
-  sup {
-    font-size: 75%;
-    line-height: 0;
-    position: relative;
-    vertical-align: baseline;
-  }
-
-  sup {
-    top: -0.5em;
-  }
-
-  sub {
-    bottom: -0.25em;
-  }
-
-  // Embedded content
-  // ==========================================================================
-
-  //
-  // Remove border when inside `a` element in IE 8/9/10.
-  //
-
-  img {
-    border: 0;
-  }
-
-  //
-  // Correct overflow not hidden in IE 9/10/11.
-  //
-
-  svg:not(:root) {
-    overflow: hidden;
-  }
-
-  // Grouping content
-  // ==========================================================================
-
-  //
-  // Address margin not present in IE 8/9 and Safari.
-  //
-
-  figure {
-    margin: 1em 40px;
-  }
-
-  //
-  // Address differences between Firefox and other browsers.
-  //
-
-  hr {
-    box-sizing: content-box;
-    height: 0;
-  }
-
-  //
-  // Contain overflow in all browsers.
-  //
-
-  pre {
-    overflow: auto;
-  }
-
-  //
-  // Address odd `em`-unit font size rendering in all browsers.
-  //
-
-  code,
-  kbd,
-  pre,
-  samp {
-    font-family: monospace, monospace;
-    font-size: 1em;
-  }
-
-  // Forms
-  // ==========================================================================
-
-  //
-  // Known limitation: by default, Chrome and Safari on OS X allow very limited
-  // styling of `select`, unless a `border` property is set.
-  //
-
-  //
-  // 1. Correct color not being inherited.
-  //    Known issue: affects color of disabled elements.
-  // 2. Correct font properties not being inherited.
-  // 3. Address margins set differently in Firefox 4+, Safari, and Chrome.
-  //
-
-  button,
-  input,
-  optgroup,
-  select,
-  textarea {
-    color: inherit; // 1
-    font: inherit; // 2
-    margin: 0; // 3
-  }
-
-  //
-  // Address `overflow` set to `hidden` in IE 8/9/10/11.
-  //
-
-  button {
-    overflow: visible;
-  }
-
-  //
-  // Address inconsistent `text-transform` inheritance for `button` and `select`.
-  // All other form control elements do not inherit `text-transform` values.
-  // Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera.
-  // Correct `select` style inheritance in Firefox.
-  //
-
-  button,
-  select {
-    text-transform: none;
-  }
-
-  //
-  // 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`
-  //    and `video` controls.
-  // 2. Correct inability to style clickable `input` types in iOS.
-  // 3. Improve usability and consistency of cursor style between image-type
-  //    `input` and others.
-  //
-
-  button,
-  html input[type="button"], // 1
-  input[type="reset"],
-  input[type="submit"] {
-    -webkit-appearance: button; // 2
-    cursor: pointer; // 3
-  }
-
-  //
-  // Re-set default cursor for disabled elements.
-  //
-
-  button[disabled],
-  html input[disabled] {
-    cursor: default;
-  }
-
-  //
-  // Remove inner padding and border in Firefox 4+.
-  //
-
-  button::-moz-focus-inner,
-  input::-moz-focus-inner {
-    border: 0;
-    padding: 0;
-  }
-
-  //
-  // Address Firefox 4+ setting `line-height` on `input` using `!important` in
-  // the UA stylesheet.
-  //
-
-  input {
-    line-height: normal;
-  }
-
-  //
-  // It's recommended that you don't attempt to style these elements.
-  // Firefox's implementation doesn't respect box-sizing, padding, or width.
-  //
-  // 1. Address box sizing set to `content-box` in IE 8/9/10.
-  // 2. Remove excess padding in IE 8/9/10.
-  //
-
-  input[type="checkbox"],
-  input[type="radio"] {
-    box-sizing: border-box; // 1
-    padding: 0; // 2
-  }
-
-  //
-  // Fix the cursor style for Chrome's increment/decrement buttons. For certain
-  // `font-size` values of the `input`, it causes the cursor style of the
-  // decrement button to change from `default` to `text`.
-  //
-
-  input[type="number"]::-webkit-inner-spin-button,
-  input[type="number"]::-webkit-outer-spin-button {
-    height: auto;
-  }
-
-  //
-  // 1. Address `appearance` set to `searchfield` in Safari and Chrome.
-  // 2. Address `box-sizing` set to `border-box` in Safari and Chrome.
-  //
-
-  input[type="search"] {
-    -webkit-appearance: textfield; // 1
-    box-sizing: content-box; //2
-  }
-
-  //
-  // Remove inner padding and search cancel button in Safari and Chrome on OS X.
-  // Safari (but not Chrome) clips the cancel button when the search input has
-  // padding (and `textfield` appearance).
-  //
-
-  input[type="search"]::-webkit-search-cancel-button,
-  input[type="search"]::-webkit-search-decoration {
-    -webkit-appearance: none;
-  }
-
-  //
-  // Define consistent border, margin, and padding.
-  //
-
-  fieldset {
-    border: 1px solid #c0c0c0;
-    margin: 0 2px;
-    padding: 0.35em 0.625em 0.75em;
-  }
-
-  //
-  // 1. Correct `color` not being inherited in IE 8/9/10/11.
-  // 2. Remove padding so people aren't caught out if they zero out fieldsets.
-  //
-
-  legend {
-    border: 0; // 1
-    padding: 0; // 2
-  }
-
-  //
-  // Remove default vertical scrollbar in IE 8/9/10/11.
-  //
-
-  textarea {
-    overflow: auto;
-  }
-
-  //
-  // Don't inherit the `font-weight` (applied by a rule above).
-  // NOTE: the default cannot safely be changed in Chrome and Safari on OS X.
-  //
-
-  optgroup {
-    font-weight: bold;
-  }
-
-  // Tables
-  // ==========================================================================
-
-  //
-  // Remove most spacing between table cells.
-  //
-
-  table {
-    border-collapse: collapse;
-    border-spacing: 0;
-  }
-
-  td,
-  th {
-    padding: 0;
-  }

+ 0 - 161
src/mol-app/skin/bootstrap/scaffolding.scss

@@ -1,161 +0,0 @@
-//
-// Scaffolding
-// --------------------------------------------------
-
-
-// Reset the box-sizing
-//
-// Heads up! This reset may cause conflicts with some third-party widgets.
-// For recommendations on resolving such conflicts, see
-// http://getbootstrap.com/getting-started/#third-box-sizing
-* {
-    @include box-sizing(border-box);
-  }
-  *:before,
-  *:after {
-    @include box-sizing(border-box);
-  }
-
-
-  // Body reset
-
-  html {
-    font-size: 10px;
-    -webkit-tap-highlight-color: rgba(0,0,0,0);
-  }
-
-  body {
-    font-family: $font-family-base;
-    font-size: $font-size-base;
-    line-height: $line-height-base;
-    color: $text-color;
-    background-color: $body-bg;
-  }
-
-  // Reset fonts for relevant elements
-  input,
-  button,
-  select,
-  textarea {
-    font-family: inherit;
-    font-size: inherit;
-    line-height: inherit;
-  }
-
-
-  // Links
-
-  a {
-    color: $link-color;
-    text-decoration: none;
-
-    &:hover,
-    &:focus {
-      color: $link-hover-color;
-      text-decoration: $link-hover-decoration;
-    }
-
-    &:focus {
-      @include tab-focus;
-    }
-  }
-
-
-  // Figures
-  //
-  // We reset this here because previously Normalize had no `figure` margins. This
-  // ensures we don't break anyone's use of the element.
-
-  figure {
-    margin: 0;
-  }
-
-
-  // Images
-
-  img {
-    vertical-align: middle;
-  }
-
-  // Responsive images (ensure images don't scale beyond their parents)
-  .img-responsive {
-    @include img-responsive;
-  }
-
-  // Rounded corners
-  .img-rounded {
-    border-radius: $border-radius-large;
-  }
-
-  // Image thumbnails
-  //
-  // Heads up! This is mixin-ed into thumbnails.less for `.thumbnail`.
-  .img-thumbnail {
-    padding: $thumbnail-padding;
-    line-height: $line-height-base;
-    background-color: $thumbnail-bg;
-    border: 1px solid $thumbnail-border;
-    border-radius: $thumbnail-border-radius;
-    @include transition(all .2s ease-in-out);
-
-    // Keep them at most 100% wide
-    @include img-responsive(inline-block);
-  }
-
-  // Perfect circle
-  .img-circle {
-    border-radius: 50%; // set radius in percents
-  }
-
-
-  // Horizontal rules
-
-  hr {
-    margin-top:    $line-height-computed;
-    margin-bottom: $line-height-computed;
-    border: 0;
-    border-top: 1px solid $hr-border;
-  }
-
-
-  // Only display content to screen readers
-  //
-  // See: http://a11yproject.com/posts/how-to-hide-content/
-
-  .sr-only {
-    position: absolute;
-    width: 1px;
-    height: 1px;
-    margin: -1px;
-    padding: 0;
-    overflow: hidden;
-    clip: rect(0,0,0,0);
-    border: 0;
-  }
-
-  // Use in conjunction with .sr-only to only display content when it's focused.
-  // Useful for "Skip to main content" links; see http://www.w3.org/TR/2013/NOTE-WCAG20-TECHS-20130905/G1
-  // Credit: HTML5 Boilerplate
-
-  .sr-only-focusable {
-    &:active,
-    &:focus {
-      position: static;
-      width: auto;
-      height: auto;
-      margin: 0;
-      overflow: visible;
-      clip: auto;
-    }
-  }
-
-
-  // iOS "clickable elements" fix for role="button"
-  //
-  // Fixes "clickability" issue (and more generally, the firing of events such as focus as well)
-  // for traditionally non-focusable elements with role="button"
-  // see https://developer.mozilla.org/en-US/docs/Web/Events/click#Safari_Mobile
-
-  [role="button"] {
-    cursor: pointer;
-  }

+ 0 - 298
src/mol-app/skin/bootstrap/type.scss

@@ -1,298 +0,0 @@
-//
-// Typography
-// --------------------------------------------------
-
-
-// Headings
-// -------------------------
-
-h1, h2, h3, h4, h5, h6,
-.h1, .h2, .h3, .h4, .h5, .h6 {
-  font-family: $headings-font-family;
-  font-weight: $headings-font-weight;
-  line-height: $headings-line-height;
-  color: $headings-color;
-
-  small,
-  .small {
-    font-weight: normal;
-    line-height: 1;
-    color: $headings-small-color;
-  }
-}
-
-h1, .h1,
-h2, .h2,
-h3, .h3 {
-  margin-top: $line-height-computed;
-  margin-bottom: ($line-height-computed / 2);
-
-  small,
-  .small {
-    font-size: 65%;
-  }
-}
-h4, .h4,
-h5, .h5,
-h6, .h6 {
-  margin-top: ($line-height-computed / 2);
-  margin-bottom: ($line-height-computed / 2);
-
-  small,
-  .small {
-    font-size: 75%;
-  }
-}
-
-h1, .h1 { font-size: $font-size-h1; }
-h2, .h2 { font-size: $font-size-h2; }
-h3, .h3 { font-size: $font-size-h3; }
-h4, .h4 { font-size: $font-size-h4; }
-h5, .h5 { font-size: $font-size-h5; }
-h6, .h6 { font-size: $font-size-h6; }
-
-
-// Body text
-// -------------------------
-
-p {
-  margin: 0 0 ($line-height-computed / 2);
-}
-
-.lead {
-  margin-bottom: $line-height-computed;
-  font-size: floor(($font-size-base * 1.15));
-  font-weight: 300;
-  line-height: 1.4;
-
-  @media (min-width: $screen-sm-min) {
-    font-size: ($font-size-base * 1.5);
-  }
-}
-
-
-// Emphasis & misc
-// -------------------------
-
-// Ex: (12px small font / 14px base font) * 100% = about 85%
-small,
-.small {
-  font-size: floor((100% * $font-size-small / $font-size-base));
-}
-
-mark,
-.mark {
-  background-color: $state-warning-bg;
-  padding: .2em;
-}
-
-// Alignment
-.text-left           { text-align: left; }
-.text-right          { text-align: right; }
-.text-center         { text-align: center; }
-.text-justify        { text-align: justify; }
-.text-nowrap         { white-space: nowrap; }
-
-// Transformation
-.text-lowercase      { text-transform: lowercase; }
-.text-uppercase      { text-transform: uppercase; }
-.text-capitalize     { text-transform: capitalize; }
-
-// Contextual colors
-.text-muted {
-  color: $text-muted;
-}
-
-@include text-emphasis-variant('.text-primary', $brand-primary);
-
-@include text-emphasis-variant('.text-success', $state-success-text);
-
-@include text-emphasis-variant('.text-info', $state-info-text);
-
-@include text-emphasis-variant('.text-warning', $state-warning-text);
-
-@include text-emphasis-variant('.text-danger', $state-danger-text);
-
-// Contextual backgrounds
-// For now we'll leave these alongside the text classes until v4 when we can
-// safely shift things around (per SemVer rules).
-.bg-primary {
-  // Given the contrast here, this is the only class to have its color inverted
-  // automatically.
-  color: #fff;
-}
-@include bg-variant('.bg-primary', $brand-primary);
-
-@include bg-variant('.bg-success', $state-success-bg);
-
-@include bg-variant('.bg-info', $state-info-bg);
-
-@include bg-variant('.bg-warning', $state-warning-bg);
-
-@include bg-variant('.bg-danger', $state-danger-bg);
-
-
-// Page header
-// -------------------------
-
-.page-header {
-  padding-bottom: (($line-height-computed / 2) - 1);
-  margin: ($line-height-computed * 2) 0 $line-height-computed;
-  border-bottom: 1px solid $page-header-border-color;
-}
-
-
-// Lists
-// -------------------------
-
-// Unordered and Ordered lists
-ul,
-ol {
-  margin-top: 0;
-  margin-bottom: ($line-height-computed / 2);
-  ul,
-  ol {
-    margin-bottom: 0;
-  }
-}
-
-// List options
-
-// [converter] extracted from `.lm-list-unstyled` for libsass compatibility
-@mixin lm-list-unstyled {
-  padding-left: 0;
-  list-style: none;
-}
-// [converter] extracted as `@mixin lm-list-unstyled` for libsass compatibility
-.lm-list-unstyled {
-  @include lm-list-unstyled;
-}
-
-
-// Inline turns list items into inline-block
-.list-inline {
-  @include lm-list-unstyled;
-  margin-left: -5px;
-
-  > li {
-    display: inline-block;
-    padding-left: 5px;
-    padding-right: 5px;
-  }
-}
-
-// Description Lists
-dl {
-  margin-top: 0; // Remove browser default
-  margin-bottom: $line-height-computed;
-}
-dt,
-dd {
-  line-height: $line-height-base;
-}
-dt {
-  font-weight: bold;
-}
-dd {
-  margin-left: 0; // Undo browser default
-}
-
-// Horizontal description lists
-//
-// Defaults to being stacked without any of the below styles applied, until the
-// grid breakpoint is reached (default of ~768px).
-
-.dl-horizontal {
-  dd {
-    @include clearfix; // Clear the floated `dt` if an empty `dd` is present
-  }
-
-  @media (min-width: $dl-horizontal-breakpoint) {
-    dt {
-      float: left;
-      width: ($dl-horizontal-offset - 20);
-      clear: left;
-      text-align: right;
-      @include text-overflow;
-    }
-    dd {
-      margin-left: $dl-horizontal-offset;
-    }
-  }
-}
-
-
-// Misc
-// -------------------------
-
-// Abbreviations and acronyms
-abbr[title],
-// Add data-* attribute to help out our tooltip plugin, per https://github.com/twbs/bootstrap/issues/5257
-abbr[data-original-title] {
-  cursor: help;
-  border-bottom: 1px dotted $abbr-border-color;
-}
-.initialism {
-  font-size: 90%;
-  @extend .text-uppercase;
-}
-
-// Blockquotes
-blockquote {
-  padding: ($line-height-computed / 2) $line-height-computed;
-  margin: 0 0 $line-height-computed;
-  font-size: $blockquote-font-size;
-  border-left: 5px solid $blockquote-border-color;
-
-  p,
-  ul,
-  ol {
-    &:last-child {
-      margin-bottom: 0;
-    }
-  }
-
-  // Note: Deprecated small and .small as of v3.1.0
-  // Context: https://github.com/twbs/bootstrap/issues/11660
-  footer,
-  small,
-  .small {
-    display: block;
-    font-size: 80%; // back to default font-size
-    line-height: $line-height-base;
-    color: $blockquote-small-color;
-
-    &:before {
-      content: '\2014 \00A0'; // em dash, nbsp
-    }
-  }
-}
-
-// Opposite alignment of blockquote
-//
-// Heads up: `blockquote.pull-right` has been deprecated as of v3.1.0.
-.blockquote-reverse,
-blockquote.pull-right {
-  padding-right: 15px;
-  padding-left: 0;
-  border-right: 5px solid $blockquote-border-color;
-  border-left: 0;
-  text-align: right;
-
-  // Account for citation
-  footer,
-  small,
-  .small {
-    &:before { content: ''; }
-    &:after {
-      content: '\00A0 \2014'; // nbsp, em dash
-    }
-  }
-}
-
-// Addresses
-address {
-  margin-bottom: $line-height-computed;
-  font-style: normal;
-  line-height: $line-height-base;
-}

+ 0 - 353
src/mol-app/skin/bootstrap/variables.scss

@@ -1,353 +0,0 @@
-//== Colors
-//
-//## Gray and brand colors for use across Bootstrap.
-
-$gray-base:              #000 !default;
-$gray-darker:            lighten($gray-base, 13.5%) !default; // #222
-$gray-dark:              lighten($gray-base, 20%) !default;   // #333
-$gray:                   lighten($gray-base, 33.5%) !default; // #555
-$gray-light:             lighten($gray-base, 46.7%) !default; // #777
-$gray-lighter:           lighten($gray-base, 93.5%) !default; // #eee
-
-$brand-primary:         darken(#428bca, 6.5%) !default; // #337ab7
-$brand-success:         #5cb85c !default;
-$brand-info:            #5bc0de !default;
-$brand-warning:         #f0ad4e !default;
-$brand-danger:          #d9534f !default;
-
-
-//== Scaffolding
-//
-//## Settings for some of the most global styles.
-
-//** Background color for `<body>`.
-$body-bg:               #fff !default;
-//** Global text color on `<body>`.
-$text-color:            $gray-dark !default;
-
-//** Global textual link color.
-$link-color:            $brand-primary !default;
-//** Link hover color set via `darken()` function.
-$link-hover-color:      darken($link-color, 15%) !default;
-//** Link hover decoration.
-$link-hover-decoration: underline !default;
-
-
-//== Typography
-//
-//## Font, line-height, and color for body text, headings, and more.
-
-$font-family-sans-serif:  "Helvetica Neue", Helvetica, Arial, sans-serif !default;
-$font-family-serif:       Georgia, "Times New Roman", Times, serif !default;
-//** Default monospace fonts for `<code>`, `<kbd>`, and `<pre>`.
-$font-family-monospace:   Menlo, Monaco, Consolas, "Courier New", monospace !default;
-$font-family-base:        $font-family-sans-serif !default;
-
-$font-size-base:          14px !default;
-$font-size-large:         ceil(($font-size-base * 1.25)) !default; // ~18px
-$font-size-small:         ceil(($font-size-base * 0.85)) !default; // ~12px
-
-$font-size-h1:            floor(($font-size-base * 2.6)) !default; // ~36px
-$font-size-h2:            floor(($font-size-base * 2.15)) !default; // ~30px
-$font-size-h3:            ceil(($font-size-base * 1.7)) !default; // ~24px
-$font-size-h4:            ceil(($font-size-base * 1.25)) !default; // ~18px
-$font-size-h5:            $font-size-base !default;
-$font-size-h6:            ceil(($font-size-base * 0.85)) !default; // ~12px
-
-//** Unit-less `line-height` for use in components like buttons.
-$line-height-base:        1.428571429 !default; // 20/14
-//** Computed "line-height" (`font-size` * `line-height`) for use with `margin`, `padding`, etc.
-$line-height-computed:    floor(($font-size-base * $line-height-base)) !default; // ~20px
-
-//** By default, this inherits from the `<body>`.
-$headings-font-family:    inherit !default;
-$headings-font-weight:    500 !default;
-$headings-line-height:    1.1 !default;
-$headings-color:          inherit !default;
-
-
-//== Components
-//
-//## Define common padding and border radius sizes and more. Values based on 14px text and 1.428 line-height (~20px to start).
-
-$padding-base-vertical:     6px !default;
-$padding-base-horizontal:   12px !default;
-
-$padding-large-vertical:    10px !default;
-$padding-large-horizontal:  16px !default;
-
-$padding-small-vertical:    5px !default;
-$padding-small-horizontal:  10px !default;
-
-$padding-xs-vertical:       1px !default;
-$padding-xs-horizontal:     5px !default;
-
-$line-height-large:         1.3333333 !default; // extra decimals for Win 8.1 Chrome
-$line-height-small:         1.5 !default;
-
-$border-radius-base:        4px !default;
-$border-radius-large:       6px !default;
-$border-radius-small:       3px !default;
-
-//** Global color for active items (e.g., navs or dropdowns).
-$component-active-color:    #fff !default;
-//** Global background color for active items (e.g., navs or dropdowns).
-$component-active-bg:       $brand-primary !default;
-
-//** Width of the `border` for generating carets that indicator dropdowns.
-$caret-width-base:          4px !default;
-//** Carets increase slightly in size for larger components.
-$caret-width-large:         5px !default;
-
-
-//== Buttons
-//
-//## For each of Bootstrap's buttons, define text, background and border color.
-
-$molstar-btn-font-weight:                normal !default;
-
-$molstar-btn-default-color:              #333 !default;
-$molstar-btn-default-bg:                 #fff !default;
-$molstar-btn-default-border:             #ccc !default;
-
-$molstar-btn-primary-color:              #fff !default;
-$molstar-btn-primary-bg:                 $brand-primary !default;
-$molstar-btn-primary-border:             darken($molstar-btn-primary-bg, 5%) !default;
-
-$molstar-btn-success-color:              #fff !default;
-$molstar-btn-success-bg:                 $brand-success !default;
-$molstar-btn-success-border:             darken($molstar-btn-success-bg, 5%) !default;
-
-$molstar-btn-info-color:                 #fff !default;
-$molstar-btn-info-bg:                    $brand-info !default;
-$molstar-btn-info-border:                darken($molstar-btn-info-bg, 5%) !default;
-
-$molstar-btn-warning-color:              #fff !default;
-$molstar-btn-warning-bg:                 $brand-warning !default;
-$molstar-btn-warning-border:             darken($molstar-btn-warning-bg, 5%) !default;
-
-$molstar-btn-danger-color:               #fff !default;
-$molstar-btn-danger-bg:                  $brand-danger !default;
-$molstar-btn-danger-border:              darken($molstar-btn-danger-bg, 5%) !default;
-
-$molstar-btn-link-disabled-color:        $gray-light !default;
-
-// Allows for customizing button radius independently from global border radius
-$molstar-btn-border-radius-base:         $border-radius-base !default;
-$molstar-btn-border-radius-large:        $border-radius-large !default;
-$molstar-btn-border-radius-small:        $border-radius-small !default;
-
-
-//== Media queries breakpoints
-//
-//## Define the breakpoints at which your layout will change, adapting to different screen sizes.
-
-// Extra small screen / phone
-//** Deprecated `$screen-xs` as of v3.0.1
-$screen-xs:                  480px !default;
-//** Deprecated `$screen-xs-min` as of v3.2.0
-$screen-xs-min:              $screen-xs !default;
-//** Deprecated `$screen-phone` as of v3.0.1
-$screen-phone:               $screen-xs-min !default;
-
-// Small screen / tablet
-//** Deprecated `$screen-sm` as of v3.0.1
-$screen-sm:                  768px !default;
-$screen-sm-min:              $screen-sm !default;
-//** Deprecated `$screen-tablet` as of v3.0.1
-$screen-tablet:              $screen-sm-min !default;
-
-// Medium screen / desktop
-//** Deprecated `$screen-md` as of v3.0.1
-$screen-md:                  992px !default;
-$screen-md-min:              $screen-md !default;
-//** Deprecated `$screen-desktop` as of v3.0.1
-$screen-desktop:             $screen-md-min !default;
-
-// Large screen / wide desktop
-//** Deprecated `$screen-lg` as of v3.0.1
-$screen-lg:                  1200px !default;
-$screen-lg-min:              $screen-lg !default;
-//** Deprecated `$screen-lg-desktop` as of v3.0.1
-$screen-lg-desktop:          $screen-lg-min !default;
-
-// So media queries don't overlap when required, provide a maximum
-$screen-xs-max:              ($screen-sm-min - 1) !default;
-$screen-sm-max:              ($screen-md-min - 1) !default;
-$screen-md-max:              ($screen-lg-min - 1) !default;
-
-
-//== Grid system
-//
-//## Define your custom responsive grid.
-
-//** Number of columns in the grid.
-$grid-columns:              12 !default;
-//** Padding between columns. Gets divided in half for the left and right.
-$grid-gutter-width:         30px !default;
-// Navbar collapse
-//** Point at which the navbar becomes uncollapsed.
-$grid-float-breakpoint:     $screen-sm-min !default;
-//** Point at which the navbar begins collapsing.
-$grid-float-breakpoint-max: ($grid-float-breakpoint - 1) !default;
-
-
-//== Forms
-//
-//##
-
-//** `<input>` background color
-$input-bg:                       #fff !default;
-//** `<input disabled>` background color
-$input-bg-disabled:              $gray-lighter !default;
-
-//** Text color for `<input>`s
-$input-color:                    $gray !default;
-//** `<input>` border color
-$input-border:                   #ccc !default;
-
-// TODO: Rename `$input-border-radius` to `$input-border-radius-base` in v4
-//** Default `.lm-form-control` border radius
-// This has no effect on `<select>`s in some browsers, due to the limited stylability of `<select>`s in CSS.
-$input-border-radius:            $border-radius-base !default;
-//** Large `.lm-form-control` border radius
-$input-border-radius-large:      $border-radius-large !default;
-//** Small `.lm-form-control` border radius
-$input-border-radius-small:      $border-radius-small !default;
-
-//** Border color for inputs on focus
-$input-border-focus:             #66afe9 !default;
-
-//** Placeholder text color
-$input-color-placeholder:        #999 !default;
-
-//** Default `.lm-form-control` height
-$input-height-base:              ($line-height-computed + ($padding-base-vertical * 2) + 2) !default;
-//** Large `.lm-form-control` height
-$input-height-large:             (ceil($font-size-large * $line-height-large) + ($padding-large-vertical * 2) + 2) !default;
-//** Small `.lm-form-control` height
-$input-height-small:             (floor($font-size-small * $line-height-small) + ($padding-small-vertical * 2) + 2) !default;
-
-//** `.form-group` margin
-$form-group-margin-bottom:       15px !default;
-
-$legend-color:                   $gray-dark !default;
-$legend-border-color:            #e5e5e5 !default;
-
-//** Background color for textual input addons
-$input-group-addon-bg:           $gray-lighter !default;
-//** Border color for textual input addons
-$input-group-addon-border-color: $input-border !default;
-
-//** Disabled cursor for form controls and buttons.
-$cursor-disabled:                not-allowed !default;
-
-
-//== Thumbnails
-//
-//##
-
-//** Padding around the thumbnail image
-$thumbnail-padding:           4px !default;
-//** Thumbnail background color
-$thumbnail-bg:                $body-bg !default;
-//** Thumbnail border color
-$thumbnail-border:            #ddd !default;
-//** Thumbnail border radius
-$thumbnail-border-radius:     $border-radius-base !default;
-
-//** Custom text color for thumbnail captions
-$thumbnail-caption-color:     $text-color !default;
-//** Padding around the thumbnail caption
-$thumbnail-caption-padding:   9px !default;
-
-
-//== Type
-//
-//##
-
-//** Horizontal offset for forms and lists.
-$component-offset-horizontal: 180px !default;
-//** Text muted color
-$text-muted:                  $gray-light !default;
-//** Abbreviations and acronyms border color
-$abbr-border-color:           $gray-light !default;
-//** Headings small color
-$headings-small-color:        $gray-light !default;
-//** Blockquote small color
-$blockquote-small-color:      $gray-light !default;
-//** Blockquote font size
-$blockquote-font-size:        ($font-size-base * 1.25) !default;
-//** Blockquote border color
-$blockquote-border-color:     $gray-lighter !default;
-//** Page header border color
-$page-header-border-color:    $gray-lighter !default;
-//** Width of horizontal description list titles
-$dl-horizontal-offset:        $component-offset-horizontal !default;
-//** Point at which .dl-horizontal becomes horizontal
-$dl-horizontal-breakpoint:    $grid-float-breakpoint !default;
-//** Horizontal line color.
-$hr-border:                   $gray-lighter !default;
-
-
-//== Form states and alerts
-//
-//## Define colors for form feedback states and, by default, alerts.
-
-$state-success-text:             #3c763d !default;
-$state-success-bg:               #dff0d8 !default;
-$state-success-border:           darken(adjust-hue($state-success-bg, -10), 5%) !default;
-
-$state-info-text:                #31708f !default;
-$state-info-bg:                  #d9edf7 !default;
-$state-info-border:              darken(adjust-hue($state-info-bg, -10), 7%) !default;
-
-$state-warning-text:             #8a6d3b !default;
-$state-warning-bg:               #fcf8e3 !default;
-$state-warning-border:           darken(adjust-hue($state-warning-bg, -10), 5%) !default;
-
-$state-danger-text:              #a94442 !default;
-$state-danger-bg:                #f2dede !default;
-$state-danger-border:            darken(adjust-hue($state-danger-bg, -10), 5%) !default;
-
-
-//== Labels
-//
-//##
-
-//** Default label background color
-$label-default-bg:            $gray-light !default;
-//** Primary label background color
-$label-primary-bg:            $brand-primary !default;
-//** Success label background color
-$label-success-bg:            $brand-success !default;
-//** Info label background color
-$label-info-bg:               $brand-info !default;
-//** Warning label background color
-$label-warning-bg:            $brand-warning !default;
-//** Danger label background color
-$label-danger-bg:             $brand-danger !default;
-
-//** Default label text color
-$label-color:                 #fff !default;
-//** Default text color of a linked label
-$label-link-hover-color:      #fff !default;
-
-
-//== Badges
-//
-//##
-
-$badge-color:                 #fff !default;
-//** Linked badge text color on hover
-$badge-link-hover-color:      #fff !default;
-$badge-bg:                    $gray-light !default;
-
-//** Badge text color in active nav link
-$badge-active-color:          $link-color !default;
-//** Badge background color in active nav link
-$badge-active-bg:             #fff !default;
-
-$badge-font-weight:           bold !default;
-$badge-line-height:           1 !default;
-$badge-border-radius:         10px !default;

+ 0 - 24
src/mol-app/skin/colors/blue.scss

@@ -1,24 +0,0 @@
-$default-background:         #2D3E50;
-$font-color:                 #EDF1F2;
-$hover-font-color:           #3B9AD9;
-$entity-current-font-color:  #FFFFFF;
-$lm-btn-remove-background:      #BF3A31;
-$lm-btn-remove-hover-font-color:#ffffff;
-$lm-btn-commit-on-font-color:   #ffffff;
-$entity-badge-font-color:    #ccd4e0;
-
-// used in LOG
-$log-message:          #0CCA5D;
-$log-info:             #5E3673;
-$log-warning:          #FCC937;
-$log-error:            #FD354B;
-
-$logo-background: rgba(0,0,0,0.75);
-
-@function color-lower-contrast($color, $amount) {
-    @return darken($color, $amount);
-}
-
-@function color-increase-contrast($color, $amount) {
-    @return lighten($color, $amount);
-}

+ 0 - 22
src/mol-app/skin/colors/dark.scss

@@ -1,22 +0,0 @@
-$default-background:         #111318;
-$font-color:                 #ccd4e0;
-$hover-font-color:           #51A2FB;
-$entity-current-font-color:  #68BEFD;
-$molstar-btn-remove-background:      #DE0A28;
-$molstar-btn-remove-hover-font-color:#F2F4F7;
-$molstar-btn-commit-on-font-color:   #68BEFD;
-$entity-badge-font-color:    #ccd4e0;
-
-// used in LOG
-$log-message:          #0CCA5D;
-$log-info:             #5E3673;
-$log-warning:          #FCC937;
-$log-error:            #FD354B;
-
-@function color-lower-contrast($color, $amount) {
-    @return darken($color, $amount);
-}
-
-@function color-increase-contrast($color, $amount) {
-    @return lighten($color, $amount);
-}

+ 0 - 30
src/mol-app/skin/colors/light.scss

@@ -1,30 +0,0 @@
-// this is complement of the dark theme
-
-@function compl($color) {
-    @return rgb(255 - red($color), 255 - green($color), 255 - blue($color));
-}
-
-$default-background:         compl(#111318);
-$font-color:                 compl(#ccd4e0);
-$hover-font-color:           compl(#51A2FB);
-$entity-current-font-color:  compl(#68BEFD);
-$molstar-btn-commit-on-font-color:   compl(#68BEFD);
-$entity-badge-font-color:    lighten(#ccd4e0,10%);
-$molstar-btn-remove-background:      #DE0A28;
-$molstar-btn-remove-hover-font-color:#F2F4F7;
-
-// used in LOG
-$log-message:          #0CCA5D;
-$log-info:             #5E3673;
-$log-warning:          #FCC937;
-$log-error:            #FD354B;
-
-$logo-background: rgba(204,201,193,0.85);
-
-@function color-lower-contrast($color, $amount) {
-    @return lighten($color, $amount);
-}
-
-@function color-increase-contrast($color, $amount) {
-    @return darken($color, $amount);
-}

+ 0 - 144
src/mol-app/skin/components/controls-base.scss

@@ -1,144 +0,0 @@
-.molstar-btn {
-    padding: 0 $control-spacing;
-    line-height: $row-height;
-    border: none;
-    -moz-box-sizing: border-box;
-    box-sizing: border-box;
-}
-
-.molstar-btn, .molstar-btn:active, .molstar-btn-link:focus, .molstar-btn:hover {
-    outline: none !important;
-}
-
-.molstar-btn-icon {
-    height: $row-height;
-    width: $row-height;
-    line-height: $row-height;
-    padding: 0;
-    text-align: center;
-}
-
-.molstar-btn-link {
-    .molstar-icon {
-        font-size: 100%;
-    }
-}
-
-.molstar-btn-link, .molstar-btn-link:active, .molstar-btn-link:focus {
-    color: $molstar-btn-link-font-color;
-    text-decoration: none;
-}
-
-.molstar-btn-link:hover {
-    color: $hover-font-color;
-    text-decoration: none;
-}
-
-.molstar-btn-link-toggle-on {
-    color: $molstar-btn-link-toggle-on-font-color;
-}
-
-.molstar-btn-link-toggle-off, .molstar-btn-link-toggle-off:active, .molstar-btn-link-toggle-off:focus {
-    color: $molstar-btn-link-toggle-off-font-color;
-}
-
-.molstar-btn-link-toggle-off:hover,  .molstar-btn-link-toggle-on:hover {
-    color: $hover-font-color;
-}
-
-@mixin molstar-btn($name, $font, $bg) {
-    .molstar-btn-#{$name}, .molstar-btn-#{$name}:active, .molstar-btn-#{$name}:focus {
-        color: $font;
-        background: $bg;
-    }
-    .molstar-btn-#{$name}:hover {
-        color: $hover-font-color;
-        background: color-lower-contrast($bg, 2.5%);
-    }
-
-    .molstar-btn-#{$name}[disabled], .molstar-btn-#{$name}[disabled]:hover,
-    .molstar-btn-#{$name}[disabled]:active, .molstar-btn-#{$name}[disabled]:focus {
-        color: color-lower-contrast($font, 1%);
-    }
-}
-
-@include molstar-btn('remove', $molstar-btn-remove-font-color, $molstar-btn-remove-background);
-@include molstar-btn('action', $font-color, $molstar-btn-action-background);
-@include molstar-btn('commit-on', $molstar-btn-commit-on-font-color, $molstar-btn-commit-on-background);
-@include molstar-btn('commit-off', $molstar-btn-commit-off-font-color, $molstar-btn-commit-off-background);
-
-.molstar-btn-remove:hover {
-    color: $molstar-btn-remove-hover-font-color;
-}
-.molstar-btn-commit-on:hover {
-	color: $molstar-btn-commit-on-hover-font-color;
-}
-
-.molstar-btn-action {
-    height: $row-height;
-    line-height: $row-height;
-}
-
-.molstar-form-control {
-    width: 100%;
-    background: $molstar-form-control-background;
-    color: $font-color;
-    border: none !important;
-    padding: 0 $control-spacing;
-    line-height: $row-height - 2px;
-    height: $row-height;
-    -webkit-appearance: none;
-    -moz-appearance: none;
-    appearance: none;
-    box-shadow: none !important;
-
-    &:hover {
-        color: $hover-font-color;
-        background-color: color-increase-contrast($molstar-form-control-background, 5%);
-        border: none;
-        outline-offset: -1px;
-        outline: 1px solid color-increase-contrast($molstar-form-control-background, 20%);
-    }
-
-    &:active, &:focus {
-        color: $font-color;
-        background-color: $molstar-form-control-background;
-        border: none;
-        outline-offset: 0;
-        outline: none;
-    }
-}
-
-.molstar-btn-commit {
-    text-align: right;
-    padding-top: 0;
-    padding-bottom: 0;
-    padding-right: $control-spacing;
-    padding-left: 0;
-    line-height: $row-height;
-    border: none;
-    overflow: hidden;
-
-    .molstar-icon {
-        display: block-inline;
-        line-height: $row-height;
-        margin-right: $control-spacing;
-        width: $row-height;
-        text-align: center;
-        float: left;
-    }
-}
-
-select.molstar-form-control {
-    background: none;
-    background-color: $molstar-form-control-background;
-    background-size: 8px 12px;
-    background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAUCAMAAACzvE1FAAAADFBMVEUzMzMzMzMzMzMzMzMKAG/3AAAAA3RSTlMAf4C/aSLHAAAAPElEQVR42q3NMQ4AIAgEQTn//2cLdRKppSGzBYwzVXvznNWs8C58CiussPJj8h6NwgorrKRdTvuV9v16Afn0AYFOB7aYAAAAAElFTkSuQmCC);
-    background-repeat: no-repeat;
-    background-position: right $control-spacing top (($row-height - 12px) / 2);
-}
-
-select.molstar-form-control:-moz-focusring {
-    color: transparent;
-    text-shadow: 0 0 0 $font-color;
-}

+ 0 - 197
src/mol-app/skin/components/controls.scss

@@ -1,197 +0,0 @@
-
-.molstar-control-row {
-    position: relative;
-    height: $row-height;
-    background: $default-background;
-    margin-top: 1px;
-
-    > span {
-        line-height: $row-height;
-        display: block;
-        width: $control-label-width + $control-spacing;
-        text-align: right;
-        padding: 0 $control-spacing;
-        color: color-lower-contrast($font-color, 15%);
-
-        @include non-selectable;
-    }
-
-    select, button, input[type=text] {
-        @extend .molstar-form-control;
-    }
-
-    button {
-        @extend .molstar-btn;
-        @extend .molstar-btn-block;
-    }
-
-    > div:nth-child(2) {
-        background: $molstar-form-control-background;
-        position: absolute;
-        left: $control-label-width + $control-spacing;
-        top: 0;
-        right: 0;
-        bottom: 0;
-    }
-}
-
-.molstar-control-group {
-    position: relative;
-}
-
-.molstar-toggle-button {
-    .molstar-icon {
-        display: inline-block;
-        margin-right: 6px;
-    }
-
-    > div > button:hover {
-        border-color: color-increase-contrast($molstar-form-control-background, 5%) !important;
-        border: none;
-        outline-offset: -1px  !important;
-        outline: 1px solid color-increase-contrast($molstar-form-control-background, 20%) !important;
-    }
-}
-
-.molstar-slider {
-    > div {
-        > div:first-child {
-            position: absolute;
-            top: 0;
-            left: 0;
-            bottom: 0;
-            right: 0;
-            width: 100%;
-            padding-right: 50px;
-            display: table;
-
-            > div {
-                height: $row-height;
-                display: table-cell;
-                vertical-align: middle;
-                padding: 0 ($control-spacing + 4px);
-            }
-        }
-        > div:last-child {
-            position: absolute;
-            height: $row-height;
-            right: 0;
-            width: 50px;
-            top: 0;
-            bottom: 0;
-        }
-    }
-
-    input[type=text] {
-        text-align: right;
-    }
-
-    input[type=range] {
-        width: 100%;
-    }
-}
-
-.molstar-toggle-color-picker {
-    button {
-        border: $control-spacing solid $molstar-form-control-background !important;
-        margin: 0;
-        text-align: center;
-        padding-right: $control-spacing;
-        padding-left: $control-spacing;
-
-        &:hover {
-            border-color: color-increase-contrast($molstar-form-control-background, 5%) !important;
-            border: none;
-            outline-offset: -1px  !important;
-            outline: 1px solid color-increase-contrast($molstar-form-control-background, 20%) !important;
-        }
-    }
-
-    .molstar-color-picker {
-        position: absolute;
-        z-index: 100000;
-        background: $default-background;
-        border-top: 1px solid $default-background;
-        padding-bottom: $control-spacing / 2;
-        width: 100%;
-
-        // input[type=text] {
-        //     background: $molstar-form-control-background !important;
-        // }
-    }
-}
-
-.molstar-toggle-color-picker-above {
-    .molstar-color-picker {
-        top: -2 * 32px - 16px - $control-spacing / 2;
-        height: 2 * 32px + 16px + $control-spacing / 2;
-    }
-}
-
-.molstar-toggle-color-picker-below {
-    .molstar-color-picker {
-        top: $row-height;
-        height: 2 * 32px + 16px;
-    }
-}
-
-
-.molstar-control-subgroup {
-    margin-top: 1px;
-
-    .molstar-control-row {
-        margin-left: $control-spacing !important;
-        > span {
-            width: $control-label-width !important;
-        }
-
-        > div:nth-child(2) {
-            left: $control-label-width !important;
-        }
-    }
-}
-
-.molstar-conrol-group-expander {
-    display: block;
-    position: absolute;
-    line-height: $row-height;
-    padding: 0;
-    left: 0;
-    top: 0;
-    width: $control-label-width + $control-spacing;
-    text-align: left;
-
-    .molstar-icon {
-        line-height: $row-height - 3;
-        width: $row-height - 1;
-        text-align: center;
-        display: inline-block;
-        font-size: 100%;
-    }
-}
-
-.molstar-plugin-layout_controls {
-    position: absolute;
-    left: $control-spacing;
-    top: $control-spacing;
-}
-
-.molstar-plugin-layout_controls > button:first-child {
-    margin-right: 6px;
-}
-
-.molstar-empty-control {
-    display: none;
-}
-
-.molstar-control .molstar-btn-block {
-    margin-bottom: 0px;
-    margin-top: 0px;
-}
-
-.molstar-row-text {
-    > div {
-        line-height: $row-height;
-        text-align: center;
-    }
-}

+ 0 - 225
src/mol-app/skin/components/entity.scss

@@ -1,225 +0,0 @@
-
-
-.molstar-entity-tree {
-    overflow: hidden;
-    position: absolute;
-    bottom: 0;
-    left: 0;
-    right: 0;
-    top: 0;
-    padding-top: $control-spacing;
-    background: $control-background;
-
-    .molstar-entity-tree-children {
-        overflow-x: hidden;
-        overflow-y: auto;
-        position: absolute;
-        bottom: 0;
-        left: 0;
-        right: 0;
-        top: $row-height + $control-spacing + 1;
-        padding: $control-spacing 0;
-    }
-}
-
-.molstar-entity-store-header {
-    height: $row-height + 1;
-    position: relative;
-
-    > span {
-        margin-left: 6px;
-        display: inline-block;
-        line-height: $row-height;
-        font-weight: bold;
-
-        @include non-selectable
-    }
-
-    button {
-        display: block !important;
-        height: $row-height !important;
-        margin: 0 !important;
-        line-height: $row-height !important;
-        border: none !important;
-        position: absolute;
-        top: 0;
-    }
-
-    border-bottom: 1px solid $border-color;
-}
-
-.molstar-entity-store-root {
-    overflow-x: hidden;
-    overflow-y: auto;
-    position: absolute;
-    bottom: 0;
-    left: 0;
-    top: $row-height + 1;
-    right: 0;
-}
-
-.molstar-entity-tree-entry {
-    height: $row-height + 1;
-    position: relative;
-    border-bottom: 1px solid $control-background;
-}
-
-.molstar-entity-tree-entry-current {
-    background: color-lower-contrast($default-background, 4%) !important;
-
-    .molstar-entity-tree-entry-label {
-        color: $entity-current-font-color;
-        font-weight: bold;
-        .molstar-entity-tree-entry-label-tag {
-            font-weight: normal;
-        }
-        &:hover {
-            color: $hover-font-color;
-        }
-    }
-}
-
-.molstar-entity-tree-entry-current-path {
-    background: color-lower-contrast($default-background, 2%) !important;
-    .molstar-entity-tree-entry-label {
-        color: color-lower-contrast($entity-current-font-color, 5%);
-        &:hover {
-            color: $hover-font-color;
-        }
-    }
-}
-
-.molstar-entity-tree-entry button, .molstar-entity-tree-entry > div {
-    display: block !important;
-    height: $row-height !important;
-    margin: 0 !important;
-    line-height: $row-height !important;
-    border: none !important;
-    position: absolute;
-    top: 0;
-}
-
-
-.molstar-entity-tree-entry-toggle-group {
-    width: $row-height;
-    height: $row-height;
-    padding: 0;
-    left: 0;
-}
-
-.molstar-entity-tree-entry-toggle-visible {
-    width: $row-height;
-    right: 0; //$row-height + 6;
-    padding: 0 !important;
-    font-size: 80%;
-}
-
-.molstar-entity-tree-entry-toggle-visible-full, .molstar-entity-tree-entry-toggle-visible-full:focus, .molstar-entity-tree-entry-toggle-visible-full:active {
-    color: $entity-color-fully-visible;
-}
-
-.molstar-entity-tree-entry-toggle-visible-partial, .molstar-entity-tree-entry-toggle-visible-partial:focus, .molstar-entity-tree-entry-toggle-visible-partial:active {
-    color: $entity-color-partialy-visible;
-}
-
-.molstar-entity-tree-entry-toggle-visible-none, .molstar-entity-tree-entry-toggle-visible-none:focus, .molstar-entity-tree-entry-toggle-visible-none:active {
-    //background: transparent !important;
-    color: $entity-color-not-visible;
-}
-
-.molstar-entity-tree-entry-remove {
-    width: $row-height;
-    height: $row-height;
-    right: $row-height;
-    padding: 0 !important;
-    text-align: center;
-    font-size: 80%;
-    color: color-lower-contrast($font-color, 66%)
-}
-
-.molstar-entity-tree-entry-body {
-    position: absolute;
-    left: $row-height;
-    border-radius: 0 0 0 $entity-subtree-offset;
-    right: 0;
-    background: $default-background;
-}
-
-.molstar-entity-tree-entry .molstar-entity-badge {
-    width: $row-height;
-    position: absolute;
-    height: $row-height;
-    left: 0;
-    top: 0;
-    border-radius: 0 $entity-subtree-offset 0 $entity-subtree-offset;
-}
-
-.molstar-entity-tree-entry-label-wrap {
-    right: 2 * $row-height;
-    overflow: hidden;
-    left: $row-height;
-    height: $row-height;
-    position: absolute;
-}
-
-.molstar-entity-tree-entry-label {
-    position: absolute;
-    right: 0;
-    top: 0;
-    left: 0;
-    text-align: left !important;
-    width: 100%;
-    padding: 0 $control-spacing !important;
-}
-
-.molstar-entity-tree-entry-label-tag {
-    color: $entity-tag-color;
-    font-size: 70%;
-    display: inline-block;
-    margin-left: 6px;
-}
-
-
-.molstar-entity-tree-children-wrap {
-    padding-left: $entity-subtree-offset;
-}
-
-.molstar-entity-tree-root {
-    > .molstar-entity-tree-entry {
-        .molstar-entity-badge {
-            border-top-right-radius: 0;
-        }
-        .molstar-entity-tree-entry-label {
-            font-weight: bold;
-        }
-        .molstar-entity-tree-entry-toggle-group {
-            display: none !important;
-        }
-        .molstar-entity-tree-entry-body {
-            left: $row-height - $entity-subtree-offset !important;
-        }
-        background: $default-background;
-        border-bottom: 1px solid $border-color;
-    }
-
-    > .molstar-entity-tree-children-wrap {
-       margin-top: $control-spacing;
-       padding-left: 0 !important;
-    }
-}
-
-.molstar-panel {
-    .molstar-entity-tree-entry-toggle-visible {
-        position: absolute;
-        top: 0;
-        right: 0;
-        height: $row-height;
-        font-size: 100%;
-
-        background: $default-background; //color-increase-contrast($default-background, 4%);
-    }
-
-    // .molstar-entity-tree-entry-toggle-visible-full {
-    //     background: color-increase-contrast($default-background, 8%);
-    // }
-}

+ 0 - 28
src/mol-app/skin/components/help.scss

@@ -1,28 +0,0 @@
-
-.molstar-help-row {
-    position: relative;
-    height: $row-height;
-    background: $default-background;
-    margin-top: 1px;
-    display: table;
-    width: 100%;
-
-    > span {
-        width: $control-label-width + $control-spacing;
-        text-align: right;
-        padding: $info-vertical-padding $control-spacing;
-        color: color-lower-contrast($font-color, 15%);
-        display: table-cell;
-        font-weight: bold;
-
-        @include non-selectable;
-    }
-
-    > div {
-        background: $molstar-form-control-background;
-        position: relative;
-        padding: $info-vertical-padding $control-spacing;
-        display: table-cell;
-        color: color-lower-contrast($font-color, 15%);
-    }
-}

+ 0 - 131
src/mol-app/skin/components/jobs.scss

@@ -1,131 +0,0 @@
-.molstar-job-state {
-
-    line-height: $row-height;
-    //height: $row-height;
-    //position: relative;
-    //margin-top: 1px;
-
-    > span {
-        @include non-selectable;
-        //display: inline-block;
-        //padding: 0 $control-spacing;
-    }
-
-    // > button {
-    //     margin-top: -2px;
-    //     float: left;
-    //     display: block;
-    //     line-height: $row-height;
-    //     height: $row-height;
-    // }
-}
-
-/* overlay */
-
-.molstar-overlay {
-    position: absolute;
-    top: 0;
-    left: 0;
-    bottom: 0;
-    right: 0;
-    z-index: 1000;
-
-    .molstar-overlay-background {
-        position: absolute;
-        top: 0;
-        left: 0;
-        bottom: 0;
-        right: 0;
-        background: transparent;
-        //background: black;
-        //opacity: 0.5;
-    }
-
-    .molstar-overlay-content-wrap {
-        position: absolute;
-        top: 0;
-        left: 0;
-        bottom: 0;
-        right: 0;
-        display: block;
-        width: 100%;
-        height: 100%;
-    }
-
-    .molstar-overlay-content {
-        text-align: center;
-
-        > div {
-
-            padding-top: 2 * $row-height;
-
-            .molstar-job-state {
-                $size: $row-height;
-                text-align: center;
-
-                > div {
-                    height: $size;
-                    margin-top: $control-spacing;
-                    position: relative;
-                    text-align: center;
-                    width: 100%;
-
-                    > div {
-                        height: $size;
-                        line-height: $size;
-                        display: inline-block;
-                        background: $default-background;
-                        padding: 0 ($control-spacing);
-                        font-weight: bold;
-                        @include non-selectable;
-                    }
-
-                    > button {
-                        display: inline-block;
-                        margin-top: -3px;
-                        font-size: 140%;
-                    }
-                }
-            }
-        }
-    }
-}
-
-/* background */
-
-.molstar-background-jobs {
-    position: absolute;
-    left: 0;
-    bottom: 0;
-    z-index: 1000;
-
-    .molstar-job-state {
-        $size: $row-height;
-
-        > div {
-            height: $size;
-            margin-top: 1px;
-            position: relative;
-            width: 100%;
-            background: $default-background;
-
-            > div {
-                height: $size;
-                line-height: $size;
-                display: inline-block;
-                padding: 0 ($control-spacing);
-                @include non-selectable;
-            }
-
-            > button {
-                display: inline-block;
-                margin-top: -3px;
-                font-size: 140%;
-            }
-        }
-    }
-}
-
-// .molstar-background-jobs .molstar-job-state {
-//     color:
-// }

+ 0 - 97
src/mol-app/skin/components/log.scss

@@ -1,97 +0,0 @@
-
-.molstar-log-wrap {
-    position: absolute;
-    right: 0;
-    top: 0;
-    left: 0;
-    bottom: 0;
-    overflow: hidden;
-}
-
-.molstar-log {
-    position: absolute;
-    right: -20px;
-    top: 0;
-    left: 0;
-    bottom: 0;
-    overflow-y: scroll;
-    overflow-x: hidden;
-    font-size: 90%;
-    background: $control-background;
-}
-
-.molstar-log {
-    ul {
-        padding: 0;
-        margin: 0;
-    }
-
-    color: $log-font-color;
-
-    li {
-        clear: both;
-        margin: 0;
-        background: $default-background;
-        position: relative;
-
-        &:not(:last-child) {
-            border-bottom: 1px solid $border-color;
-        }
-    }
-
-
-    .molstar-log-entry {
-        margin-left: $control-label-width;
-        background: color-lower-contrast($control-background, 5%);
-        padding: $info-vertical-padding ($control-spacing + 15px) $info-vertical-padding $control-spacing ;
-    }
-
-    .molstar-log-timestamp {
-        padding: ($info-vertical-padding + 1) $control-spacing ($info-vertical-padding - 1) $control-spacing;
-        float: left;
-        text-align: right;
-        width: $control-label-width;
-        color: $log-timestamp-font-color;
-        //vertical-align: baseline;
-        //line-height: $row-height;
-        font-size: 90%;
-    }
-
-    .molstar-log-timestamp small {
-        font-size: 90%;
-    }
-}
-
-// .molstar-log hr {
-//     border-color: $separator-color;
-//     margin: 3px 3px 0 5px;
-// }
-
-.molstar-log .label {
-    margin-top: -3px;
-    font-size: 7pt;
-}
-
-.molstar-log-entry-badge {
-    position: absolute;
-    left: 0;
-    top: 0;
-    bottom: 0;
-    width: 6px;
-}
-
-.molstar-log-entry-message {
-    background: $log-message;
-}
-
-.molstar-log-entry-info {
-    background: $log-info;
-}
-
-.molstar-log-entry-error {
-    background: $log-error;
-}
-
-.molstar-log-entry-warning {
-    background: $log-warning;
-}

+ 0 - 69
src/mol-app/skin/components/misc.scss

@@ -1,69 +0,0 @@
-.molstar-description {
-    padding: $control-spacing;
-    font-size: 85%;
-    background: $default-background;
-    text-align: center;
-    //font-style: italic;
-
-    -webkit-user-select: none; /* Chrome/Safari */
-    -moz-user-select: none; /* Firefox */
-    -ms-user-select: none; /* IE10+ */
-
-    /* Rules below not implemented in browsers yet */
-    -o-user-select: none;
-    user-select: none;
-
-    font-weight: light;
-
-    cursor: default;
-}
-
-.molstar-description:not(:first-child) {
-    border-top: 1px solid $control-background;
-}
-
-.molstar-color-picker input {
-    color: black !important;
-}
-
-.molstar-no-webgl {
-    position: absolute;
-    width: 100%;
-    height: 100%;
-    left: 0;
-    top: 0;
-    display: table;
-    text-align: center;
-
-    > div {
-        b {
-            font-size: 120%;
-        }
-        display: table-cell;
-        vertical-align: middle;
-        text-align: center;
-        width: 100%;
-        height: 100%;
-    }
-}
-
-.molstar-loader-molstar-btn-file {
-    position: relative;
-    overflow: hidden;
-}
-
-.molstar-loader-molstar-btn-file input[type=file] {
-    position: absolute;
-    top: 0;
-    right: 0;
-    min-width: 100%;
-    min-height: 100%;
-    font-size: 100px;
-    text-align: right;
-    filter: alpha(opacity=0);
-    opacity: 0;
-    outline: none;
-    background: white;
-    cursor: inherit;
-    display: block;
-}

+ 0 - 142
src/mol-app/skin/components/panel.scss

@@ -1,142 +0,0 @@
-.molstar-panel-header .molstar-panel-expander {
-    display: block;
-    width: 100%;
-    text-align: left;
-}
-
-.molstar-panel-header {
-
-    //border-bottom-width: 1px;
-    //border-bottom-style: solid;
-    height: $row-height;
-    border-color: $border-color;
-    position: relative;
-
-    //border-radius: $control-spacing 0 0 0;
-
-    .molstar-panel-expander-wrapper {
-
-        position: absolute;
-        top: 0;
-        left: 0;
-        right: 2 * $row-height;
-
-        button {
-            // width: 100%;
-
-            display: block;
-            width: 100%;
-            text-align: left;
-
-            height: $row-height;
-            line-height: $row-height;
-            border: none;
-            font-weight: bold;
-            //color: $panel-header-font-color;
-            padding-left: 0;
-            background: color-lower-contrast($default-background, 4%);
-            //text-align: right!important;
-
-            .molstar-icon {
-                display: inline-block;
-                margin-right: $control-spacing;
-                width: $row-height;
-                text-align: center;
-            }
-
-            &:hover {
-                background: color-lower-contrast($default-background, 4%);
-            }
-        }
-    }
-
-    .molstar-panel-description-standalone {
-        > .molstar-icon {
-            margin-left: $row-height;
-        }
-
-        width: 2 * $row-height;
-    }
-
-    .molstar-panel-description-with-action {
-        width: $row-height;
-        margin-right: $row-height;
-    }
-
-    .molstar-panel-description {
-        color: $font-color;
-        float: right;
-        background: color-lower-contrast($default-background, 4%);
-        //margin-right: $row-height;
-
-        > .molstar-icon {
-            display: block;
-            width: $row-height;
-            height: $row-height;
-            line-height: $row-height;
-            text-align: center;
-            font-size: 70%;
-            cursor: default;
-            background: color-lower-contrast($default-background, 4%);
-            color: color-lower-contrast($font-color, 66%);
-        }
-
-        .molstar-panel-description-content {
-            @include non-selectable;
-
-            color: $font-color;
-            display: none;
-            position: absolute;
-            left: 0;
-            width: 100%;
-            background: color-increase-contrast($molstar-form-control-background, 20%);
-            min-height: $row-height;
-            z-index: 1000000;
-            padding: $info-vertical-padding  $control-spacing $info-vertical-padding ($row-height + $control-spacing);
-            text-align: left;
-            //border-bottom: 1px solid color-lower-contrast($default-background, 4%);
-
-            > .molstar-icon {
-                position: absolute;
-                width: $row-height;
-                height: $row-height;
-                line-height: $row-height;
-                text-align: center;
-                font-size: 80%;
-                cursor: default;
-                top: 0;
-                left: 0;
-            }
-        }
-
-        &:hover {
-            color: $hover-font-color;
-            > .molstar-icon {
-                color: $hover-font-color;
-            }
-            .molstar-panel-description-content {
-                display: block;
-            }
-        }
-    }
-}
-
-.molstar-panel-body {
-    background: $control-background;
-}
-
-.molstar-panel {
-    margin-bottom: $control-spacing;
-}
-
-.molstar-transform-view {
-    padding-top: $control-spacing;
-}
-
-.molstar-expandable-group-color-stripe {
-    position: absolute;
-    left: 0;
-    top: $row-height - 2px;
-    width: $control-label-width + $control-spacing;
-    height: 2px;
-}

+ 0 - 9
src/mol-app/skin/components/sequence-view.scss

@@ -1,9 +0,0 @@
-.molstar-sequence-view-wrap {
-    position: absolute;
-    right: 0;
-    top: 0;
-    left: 0;
-    bottom: 0;
-    overflow: hidden;
-    overflow-x: scroll;
-}

+ 0 - 164
src/mol-app/skin/components/slider.scss

@@ -1,164 +0,0 @@
-@mixin borderBox {
-    box-sizing: border-box;
-    -webkit-tap-highlight-color: rgba(0, 0, 0, 0); //  remove tap highlight color for mobile safari
-
-    * {
-      box-sizing: border-box;
-      -webkit-tap-highlight-color: rgba(0, 0, 0, 0); //  remove tap highlight color for mobile safari
-    }
-  }
-
-  .molstar-slider-base {
-    position: relative;
-    height: 14px;
-    padding: 5px 0;
-    width: 100%;
-    border-radius: $slider-border-radius-base;
-    @include borderBox;
-
-    &-rail {
-      position: absolute;
-      width: 100%;
-      background-color: $border-color;
-      height: 4px;
-      border-radius: 2px;
-    }
-
-    &-track {
-      position: absolute;
-      left: 0;
-      height: 4px;
-      border-radius: $slider-border-radius-base;
-      background-color: tint($font-color, 60%);
-    }
-
-    &-handle {
-      position: absolute;
-      margin-left: -11px;
-      margin-top: -9px;
-      width: 22px;
-      height: 22px;
-      cursor: pointer;
-      border-radius: 50%;
-      background-color: $font-color;
-      border: 4px solid $border-color;
-
-      &:hover {
-        background-color: $hover-font-color;
-      }
-    }
-
-    &-mark {
-      position: absolute;
-      top: 18px;
-      left: 0;
-      width: 100%;
-      font-size: 12px;
-    }
-
-    &-mark-text {
-      position: absolute;
-      display: inline-block;
-      vertical-align: middle;
-      text-align: center;
-      cursor: pointer;
-      color: #999;
-
-      &-active {
-        color: #666;
-      }
-    }
-
-    &-step {
-      position: absolute;
-      width: 100%;
-      height: 4px;
-      background: transparent;
-    }
-
-    &-dot {
-      position: absolute;
-      bottom: -2px;
-      margin-left: -4px;
-      width: 8px;
-      height: 8px;
-      border: 2px solid #e9e9e9;
-      background-color: #fff;
-      cursor: pointer;
-      border-radius: 50%;
-      vertical-align: middle;
-      &:first-child {
-        margin-left: -4px;
-      }
-      &:last-child {
-        margin-left: -4px;
-      }
-      &-active {
-        border-color: tint($font-color, 50%);
-      }
-    }
-
-    &-disabled {
-      background-color: #e9e9e9;
-
-      .molstar-slider-base-track {
-        background-color: $slider-disabledColor;
-      }
-
-      .molstar-slider-base-handle, .molstar-slider-base-dot {
-        border-color: $slider-disabledColor;
-        background-color: #fff;
-        cursor: not-allowed;
-      }
-
-      .molstar-slider-base-mark-text, .molstar-slider-base-dot {
-        cursor: not-allowed!important;
-      }
-    }
-  }
-
-  .molstar-slider-base-vertical {
-    width: 14px;
-    height: 100%;
-    padding: 0 5px;
-
-    .molstar-slider-base {
-      &-rail {
-        height: 100%;
-        width: 4px;
-      }
-
-      &-track {
-        left: 5px;
-        bottom: 0;
-        width: 4px;
-      }
-
-      &-handle {
-        margin-left: -5px;
-        margin-bottom: -7px;
-      }
-
-      &-mark {
-        top: 0;
-        left: 18px;
-        height: 100%;
-      }
-
-      &-step {
-        height: 100%;
-        width: 4px;
-      }
-
-      &-dot {
-        left: 2px;
-        margin-bottom: -4px;
-        &:first-child {
-          margin-bottom: -4px;
-        }
-        &:last-child {
-          margin-bottom: -4px;
-        }
-      }
-    }
-  }

+ 0 - 93
src/mol-app/skin/components/viewport.scss

@@ -1,93 +0,0 @@
-
-.molstar-viewport {
-    position: absolute;
-    left: 0;
-    top: 0;
-    right: 0;
-    bottom: 0;
-    background: black;
-
-    .molstar-btn-link {
-        background: rgba(0,0,0,0.2);
-    }
-
-}
-
-.molstar-viewport-expanded {
-    position: fixed;
-    z-index: 1000;
-}
-
-.molstar-viewport-container {
-    position: absolute;
-    left: 0;
-    top: 0;
-    right: 0;
-    bottom: 0;
-    -webkit-user-select: none;
-    -webkit-tap-highlight-color: rgba(0,0,0,0);
-    -webkit-touch-callout: none;
-}
-
-.molstar-viewport-controls {
-    position: absolute;
-    right: $control-spacing;
-    top: $control-spacing;
-}
-
-.molstar-viewport-controls-buttons {
-    text-align: right;
-
-    > button {
-        padding: 0;
-        text-align: center;
-        width: $row-height;
-    }
-
-    > button:last-child {
-        margin-left: $control-spacing;
-    }
-
-    .molstar-btn-link, .molstar-btn-link-toggle-on {
-        color: #eee;
-    }
-
-    .molstar-btn-link-toggle-off {
-        color: $molstar-btn-link-toggle-off-font-color;
-    }
-
-    .molstar-btn-link:hover {
-        color: $hover-font-color;
-    }
-}
-
-.molstar-viewport-controls-scene-options {
-    width: 290px;
-    background: $control-background;
-}
-
-/* highlight */
-
-.molstar-highlight-info {
-
-    color: $highlight-info-font-color;
-    padding: $info-vertical-padding $control-spacing;
-    background: $default-background; //$highlight-info-background;
-
-    position: absolute;
-    top: $control-spacing;
-    left: $control-spacing;
-    text-align: left;
-    min-height: $row-height;
-    max-width: 95%;
-
-    //border-bottom-right-radius: 6px;
-    z-index: 10000;
-    @include non-selectable;
-}
-
-.molstar-highlight-info-additional {
-    font-size: 85%;
-    display: inline-block;
-    color: $highlight-info-additional-font-color;
-}

BIN
src/mol-app/skin/fonts/fontello.eot


+ 0 - 442
src/mol-app/skin/fonts/fontello.svg

@@ -1,442 +0,0 @@
-<?xml version="1.0" standalone="no"?>
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
-<svg xmlns="http://www.w3.org/2000/svg">
-<metadata>Copyright (C) 2016 by original authors @ fontello.com</metadata>
-<defs>
-<font id="fontello" horiz-adv-x="1000" >
-<font-face font-family="fontello" font-weight="400" font-stretch="normal" units-per-em="1000" ascent="850" descent="-150" />
-<missing-glyph horiz-adv-x="1000" />
-<glyph glyph-name="palette" unicode="&#xe800;" d="M857 622q72-48 101-110t20-104-35-48q-16-4-54 10t-80 10-80-46q-30-46-21-75t34-65 23-50q-2-26-36-63t-126-74-216-37q-186 0-291 101t-95 245q8 118 104 235t216 151q290 84 536-80z m-318-466q30 0 52 22t22 54-22 53-52 21q-32 0-54-21t-22-53 22-54 54-22z" horiz-adv-x="980" />
-
-<glyph glyph-name="search" unicode="&#xe803;" d="M772 78q30-34 6-62l-46-46q-36-32-68 0l-190 190q-74-42-156-42-128 0-223 95t-95 223 90 219 218 91 224-95 96-223q0-88-46-162z m-678 358q0-88 68-156t156-68 151 63 63 153q0 88-68 155t-156 67-151-63-63-151z" horiz-adv-x="789" />
-
-<glyph glyph-name="flashlight" unicode="&#xe804;" d="M807 706q62-62 85-130t-5-92l-134-134q-16-16-62-26t-96-4l-408-408q-18-18-57-6t-75 50q-36 36-49 74t5 56l408 408q-6 50 4 96t26 62l136 136q24 28 92 4t130-86z m-448-408q32-32 80 14 46 46 14 82-14 14-38 10t-44-24-23-43 11-39z m336 298q30-30 68-50t62-25 28-1q2 4-4 27t-26 60-50 67-66 50-59 26-27 2 1-28 25-62 48-66z" horiz-adv-x="902" />
-
-<glyph glyph-name="mail" unicode="&#xe805;" d="M30 586q-32 18-28 40 2 14 26 14l846 0q38 0 20-32-8-14-24-22-14-6-192-102t-182-98q-16-10-46-10-28 0-46 10-4 2-182 98t-192 102z m850-100q20 10 20-10l0-368q0-16-17-32t-33-16l-800 0q-16 0-33 16t-17 32l0 368q0 20 20 10l384-200q18-10 46-10t46 10z" horiz-adv-x="900" />
-
-<glyph glyph-name="heart" unicode="&#xe806;" d="M790 644q70-64 70-156t-70-158l-360-330-360 330q-70 66-70 158t70 156q62 58 151 58t153-58l56-52 58 52q62 58 150 58t152-58z" horiz-adv-x="860" />
-
-<glyph glyph-name="heart-empty" unicode="&#xe807;" d="M790 642q70-64 70-156t-70-156l-360-330-360 330q-70 64-70 156t70 156q64 58 152 58t150-58l58-52 56 52q64 58 152 58t152-58z m-54-260q42 40 42 104 0 66-38 100-38 38-102 38-52 0-104-48l-104-92-106 92q-48 48-102 48-64 0-104-38-38-36-38-100 0-66 44-104l306-286z" horiz-adv-x="860" />
-
-<glyph glyph-name="star" unicode="&#xe808;" d="M440 790l120-336 320 0-262-196 94-348-272 208-272-208 94 348-262 196 320 0z" horiz-adv-x="880" />
-
-<glyph glyph-name="star-empty" unicode="&#xe809;" d="M880 454l-262-196 94-348-272 208-272-208 94 348-262 196 320 0 120 336 120-336 320 0z m-440-238l150-124-62 178 144 114-176-4-56 202-54-202-176 4 142-114-62-178z" horiz-adv-x="880" />
-
-<glyph glyph-name="user" unicode="&#xe80a;" d="M736 128q204-72 204-122l0-106-940 0 0 106q0 50 204 122 94 34 128 69t34 95q0 22-22 49t-32 73q-2 12-9 18t-14 8-14 17-9 43q0 16 5 26t9 12l4 4q-8 50-12 88-4 54 41 112t157 58 158-58 40-112l-12-88q18-8 18-42-2-28-9-43t-14-17-14-8-9-18q-8-48-31-74t-23-48q0-60 35-95t127-69z" horiz-adv-x="940" />
-
-<glyph glyph-name="users" unicode="&#xe80b;" d="M1000-90l-224 0 0 150q0 54-30 81t-154 89q40 30 40 84 0 16-13 33t-19 51q-2 8-14 16t-14 42q0 24 12 30-6 34-8 60-4 38 23 78t95 40 96-40 24-78l-8-60q12-6 12-30-2-34-14-42t-14-16q-6-34-19-51t-13-33q0-42 21-66t77-48q112-46 130-80 6-8 9-61t5-101l0-48z m-488 262q182-78 182-124l0-138-694 0 0 184q0 44 84 78 76 32 104 64t28 88q0 20-19 44t-25 68q-2 10-18 22t-20 56q0 14 3 23t7 13l4 2q-6 46-10 82-4 50 33 103t127 53 127-53 33-103l-10-82q14-8 14-38-4-44-20-56t-18-22q-6-44-25-68t-19-44q0-56 28-88t104-64z" horiz-adv-x="1000" />
-
-<glyph glyph-name="user-add" unicode="&#xe80c;" d="M620 128q180-64 180-122l0-106-800 0 0 202q36 14 82 26 94 34 129 69t35 95q0 22-23 48t-31 74q-2 12-23 25t-25 61q0 16 5 26t9 12l4 4q-8 50-12 88-6 54 40 112t160 58 160-58 42-112l-14-88q18-8 18-42-2-28-9-43t-14-17-14-8-9-18q-10-46-33-73t-23-49q0-60 36-95t130-69z m230 272l150 0 0-100-150 0 0-150-100 0 0 150-150 0 0 100 150 0 0 150 100 0 0-150z" horiz-adv-x="1000" />
-
-<glyph glyph-name="video" unicode="&#xe80d;" d="M980 600l-100 0 0-100 100 0 0-100-100 0 0-100 100 0 0-100-100 0 0-100 100 0 0-60q0-16-12-28t-28-12l-900 0q-16 0-28 12t-12 28l0 60 100 0 0 100-100 0 0 100 100 0 0 100-100 0 0 100 100 0 0 100-100 0 0 60q0 18 12 29t28 11l900 0q16 0 28-11t12-29l0-60z m-600-400l250 150-250 150 0-300z" horiz-adv-x="980" />
-
-<glyph glyph-name="picture" unicode="&#xe80e;" d="M856 518l-100 0-124 150-214-150-180 0q-52 0-90-39t-38-91l0-160-108 296q-10 38 22 52l680 248q36 10 50-24z m106-90q16 0 27-12t11-28l0-472q0-16-11-28t-27-12l-724 0q-16 0-27 12t-11 28l0 472q0 16 11 28t27 12l724 0z m-56-452l0 162-72 160-166-60-130-132-138 170-92-214 0-86 598 0z" horiz-adv-x="1000" />
-
-<glyph glyph-name="camera" unicode="&#xe80f;" d="M500 450q64 0 107-44t43-106-44-106-106-44-106 44-44 106 44 106 106 44z m400 150q42 0 71-29t29-71l0-450q0-40-29-70t-71-30l-800 0q-40 0-70 30t-30 70l0 450q0 42 30 71t70 29l120 0q28 0 40 30l30 92q10 28 40 28l340 0q30 0 40-28l30-92q12-30 40-30l120 0z m-400-550q104 0 177 73t73 177-73 177-177 73-177-73-73-177 73-177 177-73z m366 380q14 0 24 11t10 25-10 24-24 10q-36 0-36-34 0-16 11-26t25-10z" horiz-adv-x="1000" />
-
-<glyph glyph-name="layout" unicode="&#xe810;" d="M170 650q80 0 80-80l0-90q0-80-80-80l-90 0q-80 0-80 80l0 90q0 80 80 80l90 0z m350 0q80 0 80-80l0-90q0-80-80-80l-90 0q-80 0-80 80l0 90q0 80 80 80l90 0z m-350-350q80 0 80-80l0-90q0-80-80-80l-90 0q-80 0-80 80l0 90q0 80 80 80l90 0z m350 0q80 0 80-80l0-90q0-80-80-80l-90 0q-80 0-80 80l0 90q0 80 80 80l90 0z" horiz-adv-x="600" />
-
-<glyph glyph-name="menu" unicode="&#xe811;" d="M650 400q22 0 36-15t14-35-15-35-35-15l-600 0q-20 0-35 15t-15 35 14 35 36 15l600 0z m-600 100q-20 0-35 15t-15 35 14 35 36 15l600 0q22 0 36-15t14-35-15-35-35-15l-600 0z m600-300q22 0 36-15t14-35-15-35-35-15l-600 0q-20 0-35 15t-15 35 14 35 36 15l600 0z" horiz-adv-x="700" />
-
-<glyph glyph-name="check" unicode="&#xe812;" d="M249 0q-34 0-56 28l-180 236q-16 24-12 52t26 46 51 14 47-28l118-154 296 474q16 24 43 30t53-8q24-16 30-43t-8-53l-350-560q-20-32-56-32z" horiz-adv-x="667" />
-
-<glyph glyph-name="cancel" unicode="&#xe813;" d="M452 194q18-18 18-43t-18-43q-18-16-43-16t-43 16l-132 152-132-152q-18-16-43-16t-43 16q-16 18-16 43t16 43l138 156-138 158q-16 18-16 43t16 43q18 16 43 16t43-16l132-152 132 152q18 16 43 16t43-16q18-18 18-43t-18-43l-138-158z" horiz-adv-x="470" />
-
-<glyph glyph-name="cancel-circled" unicode="&#xe814;" d="M420 770q174 0 297-123t123-297-123-297-297-123-297 123-123 297 123 297 297 123z m86-420l154 154-86 86-154-152-152 152-88-86 154-154-154-152 88-86 152 152 154-152 86 86z" horiz-adv-x="840" />
-
-<glyph glyph-name="cancel-squared" unicode="&#xe815;" d="M700 750q42 0 71-29t29-71l0-600q0-40-29-70t-71-30l-600 0q-40 0-70 30t-30 70l0 600q0 42 30 71t70 29l600 0z m-146-638l86 86-154 152 154 154-86 86-154-152-152 152-88-86 154-154-154-152 88-86 152 152z" horiz-adv-x="800" />
-
-<glyph glyph-name="plus" unicode="&#xe816;" d="M550 400q30 0 30-50t-30-50l-210 0 0-210q0-30-50-30t-50 30l0 210-210 0q-30 0-30 50t30 50l210 0 0 210q0 30 50 30t50-30l0-210 210 0z" horiz-adv-x="580" />
-
-<glyph glyph-name="plus-circled" unicode="&#xe817;" d="M420 770q174 0 297-123t123-297-123-297-297-123-297 123-123 297 123 297 297 123z m52-470l200 0 0 102-200 0 0 202-102 0 0-202-202 0 0-102 202 0 0-202 102 0 0 202z" horiz-adv-x="840" />
-
-<glyph glyph-name="plus-squared" unicode="&#xe818;" d="M700 750q42 0 71-29t29-71l0-600q0-40-29-70t-71-30l-600 0q-40 0-70 30t-30 70l0 600q0 42 30 71t70 29l600 0z m-50-450l0 100-200 0 0 200-100 0 0-200-200 0 0-100 200 0 0-200 100 0 0 200 200 0z" horiz-adv-x="800" />
-
-<glyph glyph-name="minus" unicode="&#xe819;" d="M550 400q30 0 30-50t-30-50l-520 0q-30 0-30 50t30 50l520 0z" horiz-adv-x="580" />
-
-<glyph glyph-name="minus-circled" unicode="&#xe81a;" d="M420 770q174 0 297-123t123-297-123-297-297-123-297 123-123 297 123 297 297 123z m252-368l-504 0 0-102 504 0 0 102z" horiz-adv-x="840" />
-
-<glyph glyph-name="minus-squared" unicode="&#xe81b;" d="M700 750q42 0 71-29t29-71l0-600q0-40-29-70t-71-30l-600 0q-40 0-70 30t-30 70l0 600q0 42 30 71t70 29l600 0z m-50-450l0 100-500 0 0-100 500 0z" horiz-adv-x="800" />
-
-<glyph glyph-name="help" unicode="&#xe81c;" d="M494 740q86-62 86-184 0-64-42-124-12-20-88-80l-46-30q-40-34-48-60-6-16-8-44 0-14-16-14l-128 0q-16 0-16 12 4 98 28 124 16 22 48 48t56 42l24 14q22 16 34 34 28 44 28 70 0 40-26 78-28 36-92 36-68 0-94-44-28-42-28-92l-166 0q6 162 114 232 70 42 166 42 130 0 214-60z m-216-636q44 0 73-30t27-74q-2-46-32-73t-74-25q-44 0-73 29t-27 75 32 73 74 25z" horiz-adv-x="580" />
-
-<glyph glyph-name="help-circled" unicode="&#xe81d;" d="M454 810q190 2 326-130t140-322q2-190-131-327t-323-141q-190-2-327 131t-139 323q-4 190 130 327t324 139z m-2-740q30 0 49 19t19 47q2 30-17 49t-49 19l-2 0q-28 0-47-18t-21-46q0-30 19-49t47-21l2 0z m166 328q26 34 26 78 0 78-54 116-52 38-134 38-64 0-104-26-68-42-72-146l0-4 110 0 0 4q0 26 16 54 16 24 54 24 40 0 52-20 16-20 16-44 0-18-16-40-8-12-20-20l-6-4q-6-4-16-11t-20-15-21-17-17-17q-14-20-18-78l0-8 108 0 0 4q0 12 4 28 6 20 28 36l28 18q46 34 56 50z" horiz-adv-x="920" />
-
-<glyph glyph-name="info" unicode="&#xe81e;" d="M352 850q48 0 74-27t26-69q0-50-39-88t-95-38q-48 0-74 26t-24 72q0 46 35 85t97 39z m-206-1000q-100 0-54 178l60 254q14 56 0 56-12 0-54-18t-72-38l-26 44q90 78 189 126t151 48q78 0 36-162l-70-266q-16-64 6-64 44 0 118 60l30-40q-84-86-175-132t-139-46z" horiz-adv-x="460" />
-
-<glyph glyph-name="info-circled" unicode="&#xe81f;" d="M454 810q190 2 326-130t140-322q2-190-131-327t-323-141q-190-2-327 131t-139 323q-4 190 130 327t324 139z m52-152q-42 0-65-24t-23-50q-2-28 15-44t49-16q38 0 61 22t23 54q0 58-60 58z m-120-594q30 0 84 26t106 78l-18 24q-48-36-72-36-14 0-4 38l42 160q26 96-22 96-30 0-89-29t-115-75l16-26q52 34 74 34 12 0 0-34l-36-152q-26-104 34-104z" horiz-adv-x="920" />
-
-<glyph glyph-name="back" unicode="&#xe820;" d="M750 540q40 0 70-29t30-71l0-290q0-40-30-70t-70-30l-690 0 0 140 650 0 0 210-500 0 0-110-210 180 210 180 0-110 540 0z" horiz-adv-x="850" />
-
-<glyph glyph-name="home" unicode="&#xe821;" d="M888 336q16-16 11-27t-27-11l-84 0 0-310q0-14-1-21t-8-13-23-6l-204 0 0 310-204 0 0-310-194 0q-28 0-35 10t-7 30l0 310-84 0q-22 0-27 11t11 27l400 402q16 16 38 16t38-16z" horiz-adv-x="900" />
-
-<glyph glyph-name="link" unicode="&#xe822;" d="M294 116q14 14 34 14t36-14q32-34 0-70l-42-40q-56-56-132-56-78 0-134 56t-56 132q0 78 56 134l148 148q70 68 144 77t128-43q16-16 16-36t-16-36q-36-32-70 0-50 48-132-34l-148-146q-26-26-26-64t26-62q26-26 63-26t63 26z m450 574q56-56 56-132 0-78-56-134l-158-158q-74-72-150-72-62 0-112 50-14 14-14 34t14 36q14 14 35 14t35-14q50-48 122 24l158 156q28 28 28 64 0 38-28 62-24 26-56 31t-60-21l-50-50q-16-14-36-14t-34 14q-34 34 0 70l50 50q54 54 127 51t129-61z" horiz-adv-x="800" />
-
-<glyph glyph-name="attach" unicode="&#xe823;" d="M244-140q-102 0-170 72-72 70-74 166t84 190l496 496q80 80 174 54 44-12 79-47t47-79q26-96-54-176l-474-474q-40-40-88-46-48-4-80 28-30 24-27 74t47 92l332 334q24 26 50 0t0-50l-332-332q-44-44-20-70 12-8 24-6 24 4 46 26l474 474q50 50 34 108-16 60-76 76-54 14-108-36l-494-494q-66-76-64-143t52-117q50-48 117-50t141 62l496 494q24 24 50 0 26-22 0-48l-496-496q-82-82-186-82z" horiz-adv-x="939" />
-
-<glyph glyph-name="lock" unicode="&#xe824;" d="M640 476q20 0 40-19t20-41l0-390q0-48-48-66l-60-18q-42-16-96-16l-290 0q-56 0-98 16l-60 18q-48 18-48 66l0 390q0 22 15 41t35 19l100 0 0 70q0 110 51 170t149 60 149-60 51-170l0-70 90 0z m-390 90l0-90 200 0 0 90q0 52-27 81t-73 29-73-29-27-81z" horiz-adv-x="700" />
-
-<glyph glyph-name="lock-open" unicode="&#xe825;" d="M640 450q20 0 40-20t20-40l0-390q0-20-14-39t-34-25l-60-20q-52-16-96-16l-290 0q-46 0-98 16l-60 20q-20 6-34 25t-14 39l0 390q0 22 15 41t35 19l400 0 0 140q0 110-100 110t-100-110l0-40-100 0 0 20q0 110 51 170t149 60q200 0 200-230l0-120 90 0z" horiz-adv-x="700" />
-
-<glyph glyph-name="eye" unicode="&#xe826;" d="M500 630q92 0 177-25t141-62 99-77 63-71 20-45-20-44-63-71-99-78-141-62-177-25-177 25-141 62-99 78-63 71-20 44 20 45 63 71 99 77 141 62 177 25z m0-494q92 0 157 63t65 151q0 90-65 153t-157 63-157-63-65-153q0-88 65-151t157-63z m0 214q8-8 37-2t50 11 25-9q0-44-33-75t-79-31-78 31-32 75q0 46 32 77t78 31q14 0 10-23t-12-47 2-38z" horiz-adv-x="1000" />
-
-<glyph glyph-name="tag" unicode="&#xe827;" d="M944 830q36-106-8-199t-128-157l18-24q16-28 6-54l-48-158q-12-30-36-46l-464-328q-42-30-64 4l-210 304q-12 18-9 39t21 33l464 328q26 18 54 18l158 0q30 0 48-26l28-40q168 130 114 286-10 28 18 40 32 8 38-20z m-216-468q40 32 34 80l-32-16q-8-4-12-4-18 0-28 18-12 30 16 40l24 14q-48 34-92 0-28-18-34-51t14-61q18-26 51-32t59 12z" horiz-adv-x="960" />
-
-<glyph glyph-name="bookmark" unicode="&#xe828;" d="M310 800q22 0 36-15t14-35l0-850-180 180-180-180 0 850q0 50 40 50l270 0z" horiz-adv-x="360" />
-
-<glyph glyph-name="bookmarks" unicode="&#xe829;" d="M500 850q20 0 35-15t15-35l0-850-150 180 0 620q0 20-15 35t-35 15l-100 0q0 50 40 50l210 0z m-250-150q20 0 35-15t15-35l0-800-150 180-150-180 0 800q0 50 40 50l210 0z" horiz-adv-x="550" />
-
-<glyph glyph-name="flag" unicode="&#xe82a;" d="M874 616q14 6 22-1t0-19q-96-138-164-213t-110-90-73-2-60 37-63 40-93-4-139-86l90-352-100 0-184 720 92 34q90 66 152 86t98 3 64-51 62-71 79-62 129-20 198 51z" horiz-adv-x="900" />
-
-<glyph glyph-name="thumbs-up" unicode="&#xe82b;" d="M582 480q2-6 58-13t108-24 52-47q0-72-61-284t-107-212q-144 0-288 42t-144 88l0 342q0 14 15 34t46 45 53 41 62 43 46 31q50 34 104 100t85 104 41 26q48-76 29-137t-59-119-40-60z m-432-4q14 0 0-14-50-50-50-104l0-318q0-50 52-104 10-10-2-10-26 0-55 8t-62 45-33 99l0 242q0 62 33 100t63 47 54 9z" horiz-adv-x="800" />
-
-<glyph glyph-name="thumbs-down" unicode="&#xe82c;" d="M218 218q-2 6-57 13t-108 24-53 47q0 72 62 285t106 213q144 0 288-43t144-89l0-342q0-10-8-24t-25-30-32-29-42-32-41-29-41-28l-33-22q-50-34-104-100t-85-104-41-26q-48 76-29 137t59 119 40 60z m432 4q-12 0 2 14 48 50 48 104l0 318q0 50-52 104-10 10 2 10 26 0 55-8t62-45 33-99l0-242q0-48-18-81t-45-48-48-21-39-6z" horiz-adv-x="800" />
-
-<glyph glyph-name="download" unicode="&#xe82d;" d="M968 198q18-10 27-32t3-40l-28-154q-4-20-22-33t-40-13l-816 0q-22 0-40 13t-22 33l-28 154q-10 48 32 72l158 108 98 0-170-130 178 0q8 0 12-8l40-110 300 0 40 110q8 8 12 8l178 0-170 130 98 0z m-208 322l-260-244-260 244 166 0 0 256 190 0 0-256 164 0z" horiz-adv-x="1000" />
-
-<glyph glyph-name="upload" unicode="&#xe82e;" d="M500 776l260-244-164 0 0-256-190 0 0 256-166 0z m468-578q18-10 27-32t3-40l-28-154q-4-20-22-33t-40-13l-816 0q-22 0-40 13t-22 33l-28 154q-10 48 32 72l158 108 98 0-170-130 178 0q8 0 12-8l40-110 300 0 40 110q8 8 12 8l178 0-170 130 98 0z" horiz-adv-x="1000" />
-
-<glyph glyph-name="upload-cloud" unicode="&#xe82f;" d="M760 494q100 0 170-68t70-166-70-166-170-68l-190 0 0 190 106 0-176 230-174-230 104 0 0-190-248 0q-74 0-128 52t-54 124q0 74 53 126t129 52q14 0 20-2-2 12-2 38 0 108 78 184t188 76q90 0 160-52t94-134q28 4 40 4z" horiz-adv-x="1000" />
-
-<glyph glyph-name="reply" unicode="&#xe830;" d="M900 10q-86 152-208 197t-330 45l0-218-362 334 362 322 0-192q90 0 168-27t131-70 96-95 69-104 44-95 24-69z" horiz-adv-x="900" />
-
-<glyph glyph-name="reply-all" unicode="&#xe831;" d="M362 556l-212-188 212-196 0-138-362 334 362 322 0-134z m250-58q104 0 182-50t115-122 60-144 27-122l4-50q-86 154-168 198t-220 44l0-218-362 334 362 322 0-192z" horiz-adv-x="1000" />
-
-<glyph glyph-name="forward" unicode="&#xe832;" d="M540 252q-210 0-332-45t-208-197q4 20 13 53t50 117 96 148 156 117 225 53l0 192 360-322-360-334 0 218z" horiz-adv-x="900" />
-
-<glyph glyph-name="quote" unicode="&#xe833;" d="M146 680q146 0 184-146 38-140-40-302-80-168-224-204-32-8-66-8l0 70q112 0 182 108 54 86 26 146-16 36-62 36-60 0-103 44t-43 106 43 106 103 44z m420 0q146 0 184-146 38-140-40-302-80-168-224-204-32-8-66-8l0 70q112 0 182 108 54 86 26 146-16 36-62 36-60 0-103 44t-43 106 43 106 103 44z" horiz-adv-x="762" />
-
-<glyph glyph-name="code" unicode="&#xe834;" d="M380 636q16-14 16-32t-16-30l-246-224 246-226q16-12 16-30t-16-32q-30-30-60 0l-320 288 320 286q30 30 60 0z m302 0l318-286-318-288q-32-30-62 0-32 32 0 62l248 226-248 224q-32 30 0 62 30 30 62 0z" horiz-adv-x="1000" />
-
-<glyph glyph-name="export" unicode="&#xe835;" d="M750 60l0 56 100 82 0-188q0-20-15-35t-35-15l-750 0q-20 0-35 15t-15 35l0 550q0 22 14 36t36 14l288 0q-32-24-59-49t-39-39l-10-12-130 0 0-450 650 0z m-82 348q-166 0-242-41t-160-181q0 8 1 22t9 56 22 79 44 83 70 79 107 56 149 23l0 156 332-250-332-260 0 178z" horiz-adv-x="1000" />
-
-<glyph glyph-name="pencil" unicode="&#xe836;" d="M718 680q32-32 47-64t15-48l0-16-252-252-290-288-238-52 50 240 290 288 252 252q54 12 126-60z m-494-640l24 24q-2 44-52 94-22 22-45 35t-35 13l-14 2-22-24-18-80q28-16 46-34 24-24 36-48z" horiz-adv-x="780" />
-
-<glyph glyph-name="feather" unicode="&#xe837;" d="M60-138q-6-20-26-8-18 8-16 34 4 100 50 226-100 154-52 316 10-32 32-78t44-80 32-30q8 4 0 83t-11 166 25 157q22 44 80 94t104 70q-24-46-33-94t-4-78 21-32q12 0 84 120t106 122q46 4 114-29t82-65q12-24 0-79t-40-83q-44-44-146-62t-114-24q-16-10 12-34 54-48 176-20-56-80-136-114t-132-38-54-10q-4-24 49-54t101-14q-30-56-63-84t-54-35-76-11-85-8z" horiz-adv-x="698" />
-
-<glyph glyph-name="print" unicode="&#xe838;" d="M66 526q-26 0-22 22 4 10 12 14 2 0 49 17t93 32 58 15l44 0 0 150 380 0 0-150 46 0q12 0 57-15t92-32 49-17q18-8 12-26-4-10-20-10l-850 0z m860-56q20 0 37-19t17-41l0-174q0-22-17-41t-37-19l-100 0 44-250-760 0 44 250-98 0q-20 0-38 19t-18 41l0 174q0 22 18 41t38 19l870 0z m-716-444l560 0-70 324-420 0z" horiz-adv-x="980" />
-
-<glyph glyph-name="retweet" unicode="&#xe839;" d="M250 190l272 0 128-140-448 0q-42 0-71 30t-29 70l0 302-102 0 176 198 174-198-100 0 0-262z m650 60l100 0-174-200-176 200 102 0 0 260-274 0-128 140 450 0q40 0 70-29t30-71l0-300z" horiz-adv-x="1000" />
-
-<glyph glyph-name="keyboard" unicode="&#xe83a;" d="M930 650q28 0 49-21t21-49l0-460q0-30-21-50t-49-20l-860 0q-28 0-49 20t-21 50l0 460q0 28 21 49t49 21l860 0z m-380-100l0-100 100 0 0 100-100 0z m150-150l-100 0 0-100 100 0 0 100z m-300 150l0-100 100 0 0 100-100 0z m150-150l-100 0 0-100 100 0 0 100z m-300 150l0-100 100 0 0 100-100 0z m150-150l-100 0 0-100 100 0 0 100z m-300 150l0-100 100 0 0 100-100 0z m150-150l-100 0 0-100 100 0 0 100z m-50-250l0 100-100 0 0-100 100 0z m550 0l0 100-500 0 0-100 500 0z m150 0l0 100-100 0 0-100 100 0z m-150 150l100 0 0 100-100 0 0-100z m150 150l0 100-200 0 0-100 200 0z" horiz-adv-x="1000" />
-
-<glyph glyph-name="comment" unicode="&#xe83b;" d="M700 700q42 0 71-29t29-71l0-350q0-40-29-70t-71-30l-200 0 0-150-200 150-200 0q-40 0-70 30t-30 70l0 350q0 42 30 71t70 29l600 0z" horiz-adv-x="800" />
-
-<glyph glyph-name="chat" unicode="&#xe83c;" d="M290 240l350 0q2 0 6 2l4 0 0-92q0-40-29-70t-71-30l-250 0-150-150 0 150-50 0q-40 0-70 30t-30 70l0 300q0 42 30 71t70 29l190 0 0-310z m610 560q42 0 71-29t29-71l0-300q0-40-29-70t-71-30l-50 0 0-150-150 150-350 0 0 400q0 42 30 71t70 29l450 0z" horiz-adv-x="1000" />
-
-<glyph glyph-name="bell" unicode="&#xe83d;" d="M632 426q16-34 40-52t45-22 44-23 35-55q22-62-74-161t-252-157q-164-58-297-45t-155 75q-20 54 12 111t18 111q-56 192-47 300t113 192q26 22 29 51t29 39q24 8 46-12t56-18q132 2 198-66t160-268z m-186-404q88 32 159 85t100 91 25 50q-8 22-49 33t-124 1-187-48q-102-38-173-87t-94-84-17-53q4-12 50-22t134-4 176 38z m-62 174q8 2 21 7t17 7l2-2q14-40-17-83t-89-63q-96-36-152 14 78 68 218 120z" horiz-adv-x="800" />
-
-<glyph glyph-name="attention" unicode="&#xe83e;" d="M957-24q10-16 0-34-10-16-30-16l-892 0q-18 0-28 16-13 18-2 34l446 782q8 18 30 18t30-18z m-420 50l0 100-110 0 0-100 110 0z m0 174l0 300-110 0 0-300 110 0z" horiz-adv-x="962" />
-
-<glyph glyph-name="alert" unicode="&#xe83f;" d="M885 234q20-16 16-33t-28-23l-78-22q-24-6-40-28t-14-48l4-82q2-24-14-34t-38 0l-86 44q-22 12-47 4t-35-30l-46-88q-12-22-29-23t-33 19l-50 78q-34 48-88 20l-122-70q-22-14-32-6t-2 32l54 164q8 24-4 44t-36 22l-106 12q-24 4-29 18t15 30l86 76q20 16 20 41t-20 41l-86 76q-20 16-16 33t28 23l78 22q24 6 41 28t15 48l-6 82q0 26 15 36t37 0l80-38q24-10 49-2t37 30l46 80q12 22 30 21t30-23l50-86q12-22 35-29t45 7l136 84q22 14 30 6t0-32l-60-170q-10-22 2-41t38-21l114-12q26-2 30-16t-16-30l-86-76q-18-16-18-41t18-41z m-384-92l0 104-100 0 0-104 100 0z m0 160l0 260-100 0 0-260 100 0z" horiz-adv-x="901" />
-
-<glyph glyph-name="vcard" unicode="&#xe840;" d="M900 750q42 0 71-29t29-71l0-600q0-40-29-70t-71-30l-800 0q-40 0-70 30t-30 70l0 600q0 42 30 71t70 29l800 0z m0-700l0 600-800 0 0-600 800 0z m-450 196l0-90-250 0 0 90 250 0z m0 150l0-90-250 0 0 90 250 0z m0 150l0-90-250 0 0 90 250 0z m346-320l4-70-250 0q0 70 6 70 84 22 84 66 0 16-27 56t-27 88q0 110 90 110t90-110q0-48-28-88t-28-56q0-20 21-36t43-22z" horiz-adv-x="1000" />
-
-<glyph glyph-name="address" unicode="&#xe841;" d="M426 800q20 0 20-20l0-860q0-20-20-20l-46 0q-20 0-20 20l0 440-176 0q-16 0-28 6-12 2-26 12l-120 82q-10 6-10 16t10 16l120 82q14 10 26 12 8 4 28 4l176 0 0 190q0 20 20 20l46 0z m564-208q10-6 10-16t-10-16l-118-82q-22-12-26-12-14-6-28-6l-302 0-40 230 342 0q18 0 28-4t26-12z" horiz-adv-x="1000" />
-
-<glyph glyph-name="location" unicode="&#xe842;" d="M250 750q104 0 177-73t73-177q0-106-62-243t-126-223l-62-84q-10 12-27 35t-60 89-76 130-60 147-27 149q0 104 73 177t177 73z m0-388q56 0 96 40t40 96-40 95-96 39-95-39-39-95 39-96 95-40z" horiz-adv-x="500" />
-
-<glyph glyph-name="map" unicode="&#xe843;" d="M984 600q16-10 16-30l0-584q0-20-16-30-8-6-16-6t-18 6l-216 136-216-136q-18-10-34 0l-218 136-216-136q-16-10-34 0-16 10-16 30l0 584q0 20 16 30l234 146q18 10 34 0l216-136 218 136q16 10 32 0z m-750-450l0 506-168-104 0-506z m234-104l0 506-168 104 0-506z m234 104l0 506-170-104 0-506z m232-104l0 506-168 104 0-506z" horiz-adv-x="1000" />
-
-<glyph glyph-name="direction" unicode="&#xe844;" d="M848 768q8-8 11-16t-2-22-10-26-19-39-24-49q-54-112-147-286t-157-292l-66-118-54 380-380 56q442 246 696 368 20 10 48 25t39 20 25 9 23 1 17-11z m-92-96l-304-280 28-234z" horiz-adv-x="860" />
-
-<glyph glyph-name="compass" unicode="&#xe845;" d="M474 830q198 2 340-136t146-336q2-200-136-342t-338-146q-198-2-341 137t-145 337q-4 200 135 342t339 144z m12-858q156 2 266 114t108 270-115 267-269 107q-158-2-267-114t-107-270 114-267 270-107z m-234 154q4 26 12 66t41 128 77 132 125 76 141 42l60 10q-4-26-12-66t-41-128-77-132q-42-42-124-74t-142-42z m180 276q-22-20-22-48t22-50q20-22 49-22t49 22q52 52 88 186-136-36-186-88z" horiz-adv-x="960" />
-
-<glyph glyph-name="cup" unicode="&#xe846;" d="M340 760q152 0 249-41t91-87l-72-594q-2-14-34-36t-97-42-137-20-136 20-97 42-35 36l-72 594q-4 28 36 57t121 50 183 21z m0-216q72 0 137 15t98 33 33 30-33 29-98 32-137 15-137-15-98-32-33-29 33-30 98-33 137-15z" horiz-adv-x="681" />
-
-<glyph glyph-name="trash" unicode="&#xe847;" d="M50 458q122-70 330-70t330 70l-54-486q-2-14-35-36t-100-43-141-21-140 21-100 43-36 36z m488 300q94-18 158-55t64-71l0-10q0-58-112-99t-268-41-268 41-112 99l0 10q0 34 64 71t158 55l42 48q22 26 70 26l92 0q52 0 70-26z m-54-112l84 0q-92 110-104 126-14 16-32 16l-102 0q-22 0-32-16l-106-126 84 0 64 66 82 0z" horiz-adv-x="760" />
-
-<glyph glyph-name="doc" unicode="&#xe848;" d="M600 800q42 0 71-29t29-71l0-700q0-40-29-70t-71-30l-500 0q-40 0-70 30t-30 70l0 700q0 42 30 71t70 29l500 0z m0-800l0 700-500 0 0-700 500 0z" horiz-adv-x="700" />
-
-<glyph glyph-name="docs" unicode="&#xe849;" d="M970 480q38-10 30-46l-150-556q-4-16-18-23t-30-3l-406 110q-16 4-24 18t-4 28l24 92-180-48q-40-10-50 26l-160 602q-10 36 28 48l454 122q16 4 30-3t18-23l66-244z m-888 190l144-542 392 106-144 540z m702-742l132 492-298 82 76-282q10-34-28-46l-196-52-26-102z" horiz-adv-x="1001" />
-
-<glyph glyph-name="doc-landscape" unicode="&#xe84a;" d="M0 600q0 42 30 71t70 29l800 0q42 0 71-29t29-71l0-500q0-40-29-70t-71-30l-800 0q-40 0-70 30t-30 70l0 500z m900 0l-800 0 0-500 800 0 0 500z" horiz-adv-x="1000" />
-
-<glyph glyph-name="doc-text" unicode="&#xe84b;" d="M212 308l0 90 280 0 0-90-280 0z m388 492q42 0 71-29t29-71l0-700q0-40-29-70t-71-30l-500 0q-40 0-70 30t-30 70l0 700q0 42 30 71t70 29l500 0z m0-800l0 700-500 0 0-700 500 0z m-110 592l0-88-280 0 0 88 280 0z m0-392l0-88-280 0 0 88 280 0z" horiz-adv-x="700" />
-
-<glyph glyph-name="doc-text-inv" unicode="&#xe84c;" d="M600 800q42 0 71-29t29-71l0-700q0-40-29-70t-71-30l-500 0q-40 0-70 30t-30 70l0 700q0 42 30 71t70 29l500 0z m-460-208l0-88 420 0 0 88-420 0z m420-480l0 88-420 0 0-88 420 0z m0 196l0 90-418 0 0-90 418 0z" horiz-adv-x="700" />
-
-<glyph glyph-name="newspaper" unicode="&#xe84d;" d="M700 800q42 0 71-29t29-71l0-700q0-40-29-70t-71-30l-600 0q-40 0-70 30t-30 70l0 700q0 42 30 71t70 29l600 0z m0-800l0 700-600 0 0-700 600 0z m-250 250l0-50-250 0 0 50 250 0z m150 200l0-50-200 0 0 50 200 0z m-200 50l0 100 200 0 0-100-200 0z m-50 100l0-200-150 0 0 200 150 0z m-50-250l0-50-100 0 0 50 100 0z m50-50l0 50 250 0 0-50-250 0z m250-150l0-50-400 0 0 50 400 0z m-100 50l0 50 100 0 0-50-100 0z" horiz-adv-x="800" />
-
-<glyph glyph-name="book-open" unicode="&#xe84e;" d="M340 238l0-68-200 80 0 68z m0 208l0-68-200 80 0 68z m538 346q22-12 22-42l0-640q0-34-32-46l-398-160q-8-2-10-2t-5-1-5-1-5 1-5 1l-10 2-398 160q-32 12-32 46l0 640q0 30 22 42 22 16 46 6l382-154 382 154q24 10 46-6z m-478-788l0 560-320 128 0-560z m420 128l0 560-320-128 0-560z m-60 186l0-68-200-80 0 68z m0 208l0-68-200-80 0 68z" horiz-adv-x="900" />
-
-<glyph glyph-name="book" unicode="&#xe84f;" d="M682 594q18-8 18-28l0-562q0-14-12-25t-28-11q-46 0-46 36l0 522q0 12-12 18l-404 216q-32 10-68-10-44-20-56-44l408-228q18-8 18-28l0-550q0-22-18-28-6-4-16-4-14 0-20 4-8 6-202 127t-212 131q-26 18-26 34l-6 524q0 28 14 52 28 46 102 77t116 9z" horiz-adv-x="700" />
-
-<glyph glyph-name="folder" unicode="&#xe850;" d="M954 500q32 0 40-12t6-36l-42-452q-2-24-12-37t-42-13l-806 0q-52 0-56 50l-42 452q-2 24 6 36t40 12l908 0z m-34 110l10-40-846 0 14 132q4 20 20 34t36 14l164 0q52 0 86-34l30-30q32-36 86-36l340 0q20 0 38-12t22-28z" horiz-adv-x="1001" />
-
-<glyph glyph-name="archive" unicode="&#xe851;" d="M840 600l0-50-696 0 0 50q0 22 13 35t25 15l608 0q6 0 14-1t22-14 14-35z m-148 150q6 0 14-1t22-14 14-35l-498 0q0 22 13 35t25 15l410 0z m248-200q34-32 38-46 6-18 0-54l-76-450q-4-22-20-35t-28-15l-710 0q-52 0-60 50-6 26-39 223t-39 227q-10 22-3 44t10 26 21 20l10 10 30 30 0-80 836 0 0 80z m-248-270l0 100-70 0 0-80-260 0 0 80-68 0 0-100q0-50 48-50l300 0q22 0 35 12t13 24z" horiz-adv-x="981" />
-
-<glyph glyph-name="box" unicode="&#xe852;" d="M870 750q12 0 21-9t9-21l0-120-900 0 0 120q0 12 9 21t21 9l840 0z m-820-730l0 530 800 0 0-530q0-30-21-50t-49-20l-660 0q-28 0-49 20t-21 50z m250 430l0-100 300 0 0 100-300 0z" horiz-adv-x="900" />
-
-<glyph glyph-name="rss" unicode="&#xe853;" d="M0 730q314 0 537-223t223-537l-118 0q0 266-188 453t-454 187l0 120z m0-238q218 0 371-153t153-369l-118 0q0 166-119 285t-287 119l0 118z m114-296q46 0 80-33t34-81q0-46-34-79t-80-33-80 33-34 79q0 48 34 81t80 33z" horiz-adv-x="760" />
-
-<glyph glyph-name="phone" unicode="&#xe854;" d="M461 290q162 162 118 206l-8 8q-30 30-41 48t-4 54 49 88q20 24 37 39t35 16 30 1 29-13 24-18 26-25 21-22q48-48-6-194t-204-294q-150-150-295-205t-193-7q-2 2-23 22t-25 25-18 24-13 31 2 30 15 35 38 37q42 34 70 47t54 2 35-18 39-37q44-44 208 120z" horiz-adv-x="800" />
-
-<glyph glyph-name="cog" unicode="&#xe855;" d="M760 350q0-72 80-122-12-40-34-82-70 18-136-44-54-58-34-136-40-20-84-36-46 82-132 82t-132-82q-44 16-84 36 20 80-34 136-54 54-136 34-14 26-34 82 82 52 82 132 0 72-82 124 20 56 34 82 74-18 136 44 54 56 34 136 42 22 84 34 46-80 132-80t132 80q42-12 84-34-20-78 34-136 66-62 136-44 22-42 34-82-80-50-80-124z m-340-182q76 0 129 53t53 129-53 130-129 54-129-54-53-130 53-129 129-53z" horiz-adv-x="840" />
-
-<glyph glyph-name="tools" unicode="&#xe856;" d="M155 506q-8-8-11-22t-3-25-2-11q-2-2-17-15t-19-17q-16-14-28 4l-70 76q-11 12 2 24 2 2 18 14t20 16q6 6 27 6t37 14q14 14 18 38t10 30q2 0 9 7t26 22 41 31q134 90 186 96 122 0 148-2 12 0-8-8-120-52-152-76-80-56-36-114 34-46 38-48 8-8-2-14-2-2-38-35t-38-35q-14-8-18-4-42 48-71 60t-67-12z m286-26l410-476q18-22-2-38l-48-42q-22-14-38 4l-414 472q-8 8 0 20l72 62q12 8 20-2z m554 202q16-104-16-166-50-88-154-62-56 12-100-32l-82-78-68 78 68 70q24 24 31 53t6 65 5 58q12 56 140 112 12 6 18-3t2-15q-12-12-46-80-14-10-12-35t40-53q58-40 96 22 6 12 26 41t22 33q4 10 13 9t11-17z m-858-684l254 248 76-86-246-242q-20-20-38-4l-46 46q-22 18 0 38z" horiz-adv-x="1000" />
-
-<glyph glyph-name="share" unicode="&#xe857;" d="M650 200q62 0 106-43t44-107q0-62-44-106t-106-44-106 44-44 106q0 6 1 14t1 12l-260 156q-42-32-92-32-62 0-106 44t-44 106 44 106 106 44q54 0 92-30l260 156q0 4-1 12t-1 12q0 62 44 106t106 44 106-43 44-107q0-62-44-106t-106-44q-52 0-90 32l-262-156q2-8 2-26 0-16-2-24l262-156q36 30 90 30z" horiz-adv-x="800" />
-
-<glyph glyph-name="shareable" unicode="&#xe858;" d="M340 350q0 68 47 114t113 46 113-46 47-114q0-66-47-113t-113-47-113 47-47 113z m-114 60q-14-60-66-60l-160 0 0 120 118 0q40 124 145 202t237 78q164 0 284-116 16-18 16-43t-16-43q-18-16-43-16t-43 16q-78 82-198 82-100 0-176-62t-98-158z m614-60l160 0 0-120-118 0q-40-124-144-202t-238-78q-164 0-282 118-18 18-18 43t18 41q16 18 41 18t43-18q82-82 198-82 100 0 176 63t98 157q12 60 66 60z" horiz-adv-x="1000" />
-
-<glyph glyph-name="basket" unicode="&#xe859;" d="M150 0q0 40 30 70t70 30q42 0 71-30t29-70q0-42-29-71t-71-29q-40 0-70 29t-30 71z m500 0q0 40 30 70t70 30q42 0 71-30t29-70q0-42-29-71t-71-29q-40 0-70 29t-30 71z m-322 236q-36-10-34-23t44-13l562 0 0-76q0-20-20-20l-654 0q-20 0-20 20l0 76-10 46-98 454-98 0 0 80q0 20 20 20l156 0q20 0 20-20l0-86 704 0 0-274q0-22-18-26z" horiz-adv-x="900" />
-
-<glyph glyph-name="bag" unicode="&#xe85a;" d="M835 668q28-26 24-60l-98-648q-8-30-38-30l-586 0q-28 0-40 30-94 620-96 648-5 34 22 60 6 6 54 43t56 43q18 16 56 16l480 0q38 0 56-16 78-58 110-86z m-406-436q56 0 98 34t63 89 30 89 13 66l-92 0q-38-188-112-188t-112 188l-92 0q46-278 204-278z m-352 368l704 0-110 116-484 0z" horiz-adv-x="859" />
-
-<glyph glyph-name="calendar" unicode="&#xe85b;" d="M800 700q42 0 71-29t29-71l0-600q0-40-29-70t-71-30l-700 0q-40 0-70 30t-30 70l0 600q0 42 30 71t70 29l46 0 0-100 160 0 0 100 290 0 0-100 160 0 0 100 44 0z m0-700l0 400-700 0 0-400 700 0z m-540 800l0-170-70 0 0 170 70 0z m450 0l0-170-70 0 0 170 70 0z" horiz-adv-x="900" />
-
-<glyph glyph-name="login" unicode="&#xe85c;" d="M800 800q42 0 71-29t29-71l0-700q0-40-29-70t-71-30l-450 0q-40 0-69 30t-29 70l0 100 98 0 0-100 450 0 0 700-450 0 0-150-98 0 0 150q0 42 29 71t69 29l450 0z m-350-670l0 120-450 0 0 150 450 0 0 120 200-194z" horiz-adv-x="900" />
-
-<glyph glyph-name="logout" unicode="&#xe85d;" d="M502 0l0 100 98 0 0-100q0-40-29-70t-71-30l-400 0q-40 0-70 30t-30 70l0 700q0 42 30 71t70 29l400 0q42 0 71-29t29-71l0-150-98 0 0 150-402 0 0-700 402 0z m398 326l-198-196 0 120-450 0 0 150 450 0 0 120z" horiz-adv-x="900" />
-
-<glyph glyph-name="mic" unicode="&#xe85e;" d="M620 488q20 0 20-20l0-138q0-92-69-164t-201-84l0-132 130 0q20 0 20-20l0-60q0-20-20-20l-360 0q-20 0-20 20l0 60q0 20 20 20l130 0 0 132q-132 12-201 84t-69 164l0 138q0 20 20 20l30 0q20 0 20-20l0-138q0-66 59-123t191-57 191 57 59 123l0 138q0 20 20 20l30 0z m-300-238q-80 0-115 25t-35 55l0 158 300 0 0-158q0-30-35-55t-115-25z m150 520l0-212-300 0 0 212q0 30 35 55t115 25 115-25 35-55z" horiz-adv-x="640" />
-
-<glyph glyph-name="mute" unicode="&#xe85f;" d="M868 778q16-16 16-36t-16-36l-782-782q-18-14-34-14-18 0-36 14-16 14-16 36t16 36l782 782q34 32 70 0z m-216-386l50 50q74-92 101-172t-7-116q-24-24-75-57t-131-71-161-45-165 23l278 276q44-32 88-54t67-25 33 1q6 10 2 34t-26 68-54 88z m-276 62l-270-270q-40 132 28 283t132 215q34 32 105 11t159-85l-52-50q-58 38-105 53t-57 5q-4-8-2-28t19-58 43-76z" horiz-adv-x="884" />
-
-<glyph glyph-name="sound" unicode="&#xe860;" d="M176 588q42 42 149-5t217-157 157-217 5-149q-28-28-92-67t-156-78-194-29-176 84-84 176 29 194 78 156 67 92z m464-480q8 10-3 49t-49 101-96 118q-56 58-118 96t-101 49-49 3q-8-10 3-49t49-101 94-120q58-56 120-94t101-49 49-3z m6 394q-18 0-34 16-16 14-16 35t16 35l94 96q36 32 72 0 32-36 0-72l-96-94q-16-16-36-16z m-180 124q-18 10-23 30t5 38l54 96q26 44 68 20 18-10 23-30t-5-38l-54-96q-14-26-42-26-14 0-26 6z m438-150q10-18 4-38t-24-30l-96-54q-16-8-24-8-28 0-44 26-10 18-4 38t24 30l96 54q18 10 38 5t30-23z" horiz-adv-x="910" />
-
-<glyph glyph-name="volume" unicode="&#xe861;" d="M896 180q0-34-24-57t-56-23l-780 0q-22 0-31 5t-3 15 24 20l802 452q28 18 48 7t20-45l0-374z" horiz-adv-x="896" />
-
-<glyph glyph-name="clock" unicode="&#xe862;" d="M460 810q190 0 325-135t135-325-135-325-325-135-325 135-135 325 135 325 325 135z m0-820q150 0 255 106t105 254q0 150-105 255t-255 105q-148 0-254-105t-106-255q0-148 106-254t254-106z m36 620l0-244 150-150-50-50-170 170 0 274 70 0z" horiz-adv-x="920" />
-
-<glyph glyph-name="hourglass" unicode="&#xe863;" d="M560 622q0-44-48-96t-97-99-49-77 49-76 97-97 48-97l0-118q0-34-86-73t-194-39-194 39-86 73l0 118q0 46 48 97t97 97 49 76-49 77-97 99-48 96l0 118q0 32 87 71t193 39 193-39 87-71l0-118z m-482 112l-18-14q-4-8 4-14 92-52 216-52 132 0 220 50 14 10-16 30-96 54-202 54-120 0-204-54z m228-384q0 18 4 33t18 33 20 25 31 31 29 28q92 92 92 122l2 50q-100-54-222-54t-222 54l4-50q0-32 90-122 6-6 22-21t23-22l19-19t17-21 11-20 9-23 3-24q0-10-1-19t-6-18-8-16-11-17l-12-15t-15-16-16-15-18-16-17-16q-90-90-90-122l0-66q8 4 66 23t92 43 34 58q0 30 26 30t26-30q0-34 33-58t94-43 67-23l0 66q0 30-92 122-4 4-21 20t-22 21-18 19-18 22-12 20-9 23-2 23z" horiz-adv-x="560" />
-
-<glyph glyph-name="lamp" unicode="&#xe864;" d="M209-110l0 104 282 0 0-104q-70-42-142-40-70-2-140 40z m276 164l-270 0q0 72-36 140t-78 113-74 112-26 139q8 120 94 206t254 86q170 0 255-86t95-206q4-60-16-113t-52-96-65-85-57-96-24-114z m-378 496q-4-4 0-20t2-20 5-19 6-18 8-18 11-19 13-19 14-19 15-21 16-23q88-122 112-212l82 0q24 94 112 212 4 6 25 35t25 36 17 29 16 33 6 28 1 35q-16 196-244 196-226 0-242-196z" horiz-adv-x="700" />
-
-<glyph glyph-name="light-down" unicode="&#xe865;" d="M350 510q68 0 114-47t46-113q0-68-46-114t-114-46q-66 0-113 46t-47 114q0 66 47 113t113 47z m0-264q44 0 73 30t29 74q0 42-29 72t-73 30q-42 0-72-30t-30-72q0-44 30-74t72-30z m-300 144q20 0 35-12t15-28q0-40-50-40t-50 40q0 16 15 28t35 12z m546 204q28-28-8-64-14-14-33-16t-29 10q-12 12-10 31t16 33q36 34 64 6z m54-204q20 0 35-12t15-28q0-40-50-40-48 0-48 40 0 16 14 28t34 12z m-300-290q16 0 28-15t12-35-12-35-28-15-28 15-12 35 12 35 28 15z m-238 62q36 36 64 8t-8-64q-14-14-33-16t-29 8q-30 28 6 64z m-10 430q28 28 64-8 14-14 16-33t-8-29q-30-28-64 6-36 36-8 64z m432-484q-34 36-6 64t64-8q14-14 16-33t-10-29q-30-28-64 6z m-184 492q-16 0-28 15t-12 35 12 35 28 15 28-15 12-35-12-35-28-15z" horiz-adv-x="700" />
-
-<glyph glyph-name="light-up" unicode="&#xe866;" d="M950 390q20 0 35-12t15-28q0-40-50-40l-48 0q-50 0-50 40 0 16 15 28t35 12l48 0z m-450 234q114 0 195-80t81-194q0-116-81-196t-195-80-194 80-80 196q0 114 80 194t194 80z m0-474q82 0 141 58t59 142q0 82-59 141t-141 59-141-59-59-141q0-84 59-142t141-58z m-350 200q0-40-50-40l-50 0q-50 0-50 40 0 16 15 28t35 12l50 0q20 0 35-12t15-28z m350 350q-16 0-28 15t-12 35l0 50q0 20 12 35t28 15 28-15 12-35l0-50q0-20-12-35t-28-15z m0-700q16 0 28-15t12-35l0-50q0-20-12-35t-28-15-28 15-12 35l0 50q0 20 12 35t28 15z m368 660l-34-34q-34-34-64-8-28 28 8 64 4 6 34 36 36 34 64 6t-8-64z m-700-588q14 16 33 18t29-10q12-12 10-31t-16-33l-36-36q-14-14-33-16t-29 10q-30 28 6 64 6 4 36 34z m20 646l36-36q36-36 6-64-10-10-29-8t-33 16q-30 30-36 34-14 14-16 33t10 31q10 12 29 10t33-16z m590-702q-36 36-8 64t64-8l34-34q36-36 8-64t-64 6q-30 30-34 36z" horiz-adv-x="1000" />
-
-<glyph glyph-name="adjust" unicode="&#xe867;" d="M950 390q20 0 35-12t15-28q0-40-50-40l-48 0q-50 0-50 40 0 16 15 28t35 12l48 0z m-450 234q114 0 195-80t81-194q0-116-81-196t-195-80-194 80-80 196q0 114 80 194t194 80z m6-474l0 400q-86 0-146-59t-60-141q0-84 60-142t146-58z m-356 200q0-40-50-40l-50 0q-50 0-50 40 0 16 15 28t35 12l50 0q20 0 35-12t15-28z m350 350q-16 0-28 15t-12 35l0 50q0 20 12 35t28 15 28-15 12-35l0-50q0-20-12-35t-28-15z m0-700q16 0 28-15t12-35l0-50q0-20-12-35t-28-15-28 15-12 35l0 50q0 20 12 35t28 15z m368 660l-34-34q-34-34-64-8-28 28 8 64 4 6 34 36 36 34 64 6t-8-64z m-700-588q14 16 33 18t29-10q12-12 10-31t-16-33l-36-36q-14-14-33-16t-29 10q-30 28 6 64 6 4 36 34z m20 646l36-36q36-36 6-64-10-10-29-8t-33 16q-30 30-36 34-14 14-16 33t10 31q10 12 29 10t33-16z m590-702q-36 36-8 64t64-8l34-34q36-36 8-64t-64 6q-30 30-34 36z" horiz-adv-x="1000" />
-
-<glyph glyph-name="block" unicode="&#xe868;" d="M480 830q200 0 340-140t140-340q0-198-140-339t-340-141q-198 0-339 141t-141 339q0 200 141 340t339 140z m258-220z m-622-260q0-132 82-230l514 514q-100 82-232 82-152 0-258-107t-106-259z m106-258z m258-106q152 0 259 107t107 257q0 130-82 232l-514-514q98-82 230-82z" horiz-adv-x="960" />
-
-<glyph glyph-name="resize-full" unicode="&#xe869;" d="M476 746l316 0 0-316-100 124-146-152-100 100 152 146z m-230-444l100-100-152-146 122-100-316 0 0 316 100-122z" horiz-adv-x="792" />
-
-<glyph glyph-name="resize-small" unicode="&#xe86a;" d="M156 146l-106 100 296 0 0-296-100 106-146-156-100 100z m744 554l-154-144 104-100-294 0 0 294 100-104 144 154z" horiz-adv-x="900" />
-
-<glyph glyph-name="popup" unicode="&#xe86b;" d="M700 750q42 0 71-29t29-71l0-400q0-40-29-70t-71-30l-400 0q-40 0-70 30t-30 70l0 402q0 40 29 69t71 29l400 0z m0-500l0 400-400 0 0-400 400 0z m-600 100l0-300 300 0 0-100-300 0q-40 0-70 30t-30 70l0 300 100 0z" horiz-adv-x="800" />
-
-<glyph glyph-name="publish" unicode="&#xe86c;" d="M900 800q42 0 71-30t29-70l0-600q0-42-29-71t-71-29l-198 0 0 98 200 0 0 462-802 0 0-462 200 0 0-98-200 0q-40 0-70 29t-30 71l0 600q0 40 30 70t70 30l800 0z m-770-168q38 0 38 38 0 16-11 26t-27 10-27-11-11-25q0-16 11-27t27-11z m100 0q38 0 38 38 0 16-11 26t-27 10-27-11-11-25q0-16 11-27t27-11z m672 6l0 62-602 0 0-62 602 0z m-404-198l242-240-150 0 0-300-184 0 0 300-150 0z" horiz-adv-x="1000" />
-
-<glyph glyph-name="window" unicode="&#xe86d;" d="M900 750q42 0 71-30t29-70l0-600q0-42-29-71t-71-29l-800 0q-40 0-70 29t-30 71l0 600q0 40 30 70t70 30l800 0z m-670-94q-16 0-27-11t-11-25q0-16 11-27t27-11q38 0 38 38 0 16-11 26t-27 10z m-138-36q0-16 11-27t27-11q38 0 38 38 0 16-11 26t-27 10-27-11-11-25z m810-570l0 460-802 0 0-460 802 0z m0 540l0 60-602 0 0-60 602 0z" horiz-adv-x="1000" />
-
-<glyph glyph-name="arrow-combo" unicode="&#xe86e;" d="M230 850l230-364-460 0z m0-1000l-230 366 460 0z" horiz-adv-x="460" />
-
-<glyph glyph-name="down-circled" unicode="&#xe86f;" d="M460 810q190 0 325-135t135-325-135-325-325-135-325 135-135 325 135 325 325 135z m0-820q148 0 254 106t106 254q0 150-106 255t-254 105-254-105-106-255q0-148 106-254t254-106z m90 554l0-206 112 0-202-190-202 190 112 0 0 206 180 0z" horiz-adv-x="920" />
-
-<glyph glyph-name="left-circled" unicode="&#xe870;" d="M920 350q0-190-135-325t-325-135-325 135-135 325q0 192 135 326t325 134 325-134 135-326z m-820 0q0-148 106-254t254-106 254 106 106 254q0 150-106 255t-254 105-254-105-106-255z m552-90l-204 0 0-112-190 202 190 204 0-114 204 0 0-180z" horiz-adv-x="920" />
-
-<glyph glyph-name="right-circled" unicode="&#xe871;" d="M0 350q0 190 135 325t325 135 325-135 135-325-135-325-325-135-325 135-135 325z m820 0q0 150-105 255t-255 105q-148 0-254-105t-106-255q0-148 106-254t254-106q150 0 255 106t105 254z m-552 90l204 0 0 114 190-204-190-202 0 112-204 0 0 180z" horiz-adv-x="920" />
-
-<glyph glyph-name="up-circled" unicode="&#xe872;" d="M460-110q-190 0-325 135t-135 325q0 192 135 326t325 134 325-134 135-326q0-190-135-325t-325-135z m0 820q-148 0-254-105t-106-255q0-148 106-254t254-106q150 0 255 106t105 254q0 150-105 255t-255 105z m-90-552l0 204-112 0 202 192 202-192-112 0 0-204-180 0z" horiz-adv-x="920" />
-
-<glyph glyph-name="down-open" unicode="&#xe873;" d="M564 422l-234-224q-18-18-40-18t-40 18l-234 224q-16 16-16 41t16 41q38 38 78 0l196-188 196 188q40 38 78 0 16-16 16-41t-16-41z" horiz-adv-x="580" />
-
-<glyph glyph-name="left-open" unicode="&#xe874;" d="M242 626q14 16 39 16t41-16q38-36 0-80l-186-196 186-194q38-44 0-80-16-16-40-16t-40 16l-226 236q-16 16-16 38 0 24 16 40 206 214 226 236z" horiz-adv-x="341" />
-
-<glyph glyph-name="right-open" unicode="&#xe875;" d="M98 626l226-236q16-16 16-40 0-22-16-38l-226-236q-16-16-40-16t-40 16q-36 36 0 80l186 194-186 196q-36 44 0 80 16 16 41 16t39-16z" horiz-adv-x="340" />
-
-<glyph glyph-name="up-open" unicode="&#xe876;" d="M564 280q16-16 16-41t-16-41q-38-38-78 0l-196 188-196-188q-40-38-78 0-16 16-16 41t16 41l234 224q16 16 40 16t40-16z" horiz-adv-x="580" />
-
-<glyph glyph-name="down-open-mini" unicode="&#xe877;" d="M405 470q22 26 48 0 26-22 0-48l-196-192q-22-22-48 0l-196 192q-26 26 0 48 24 24 50 0l170-156z" horiz-adv-x="466" />
-
-<glyph glyph-name="left-open-mini" unicode="&#xe878;" d="M252 180q26-26 0-48-26-26-48 0l-192 194q-24 24 0 50l192 194q22 26 48 0 26-22 0-48l-156-172z" horiz-adv-x="265" />
-
-<glyph glyph-name="right-open-mini" unicode="&#xe879;" d="M13 180l158 170-158 172q-26 26 0 48 26 26 48 0l192-194q24-26 0-50l-192-194q-22-26-48 0-26 22 0 48z" horiz-adv-x="265" />
-
-<glyph glyph-name="up-open-mini" unicode="&#xe87a;" d="M62 230q-26-22-50 0-24 24 0 50l196 190q26 26 48 0l196-190q24-26 0-50-24-22-50 0l-170 158z" horiz-adv-x="464" />
-
-<glyph glyph-name="down-open-big" unicode="&#xe87b;" d="M63 570l370-356 372 356q22 26 48 0 26-22 0-48l-396-392q-22-22-48 0l-396 392q-26 26 0 48 24 24 50 0z" horiz-adv-x="866" />
-
-<glyph glyph-name="left-open-big" unicode="&#xe87c;" d="M452-20q26-26 0-48-26-26-48 0l-392 394q-24 24 0 50l392 394q22 26 48 0 26-22 0-48l-358-372z" horiz-adv-x="465" />
-
-<glyph glyph-name="right-open-big" unicode="&#xe87d;" d="M13-20l358 370-358 372q-26 26 0 48 26 26 48 0l392-394q24-26 0-50l-392-394q-22-26-48 0-26 22 0 48z" horiz-adv-x="465" />
-
-<glyph glyph-name="up-open-big" unicode="&#xe87e;" d="M804 130l-372 358-370-358q-26-22-50 0-24 24 0 50l396 390q26 26 48 0l396-390q24-26 0-50-26-22-48 0z" horiz-adv-x="864" />
-
-<glyph glyph-name="down" unicode="&#xe87f;" d="M660 366l-330-380-330 380 192 0 0 350 276 0 0-350 192 0z" horiz-adv-x="660" />
-
-<glyph glyph-name="left" unicode="&#xe880;" d="M378 20l-378 330 378 330 0-190 352 0 0-278-352 0 0-192z" horiz-adv-x="730" />
-
-<glyph glyph-name="right" unicode="&#xe881;" d="M350 680l380-330-380-330 0 192-350 0 0 278 350 0 0 190z" horiz-adv-x="730" />
-
-<glyph glyph-name="up" unicode="&#xe882;" d="M660 336l-192 0 0-350-276 0 0 350-192 0 330 380z" horiz-adv-x="660" />
-
-<glyph glyph-name="down-dir" unicode="&#xe883;" d="M460 550l-230-400-230 400 460 0z" horiz-adv-x="460" />
-
-<glyph glyph-name="left-dir" unicode="&#xe884;" d="M400 580l0-460-400 230z" horiz-adv-x="400" />
-
-<glyph glyph-name="right-dir" unicode="&#xe885;" d="M0 580l400-230-400-230 0 460z" horiz-adv-x="400" />
-
-<glyph glyph-name="up-dir" unicode="&#xe886;" d="M0 150l230 400 230-400-460 0z" horiz-adv-x="460" />
-
-<glyph glyph-name="down-bold" unicode="&#xe887;" d="M760 366l-380-380-380 380 192 0 0 350 376 0 0-350 192 0z" horiz-adv-x="760" />
-
-<glyph glyph-name="left-bold" unicode="&#xe888;" d="M378 730l0-190 352 0 0-378-352 0 0-192-378 380z" horiz-adv-x="730" />
-
-<glyph glyph-name="right-bold" unicode="&#xe889;" d="M350 730l380-380-380-380 0 192-350 0 0 378 350 0 0 190z" horiz-adv-x="730" />
-
-<glyph glyph-name="up-bold" unicode="&#xe88a;" d="M760 336l-192 0 0-350-376 0 0 350-192 0 380 380z" horiz-adv-x="760" />
-
-<glyph glyph-name="down-thin" unicode="&#xe88b;" d="M500 100l-250-240-250 240 162 0 0 740 176 0 0-740 162 0z" horiz-adv-x="500" />
-
-<glyph glyph-name="left-thin" unicode="&#xe88c;" d="M240 100l-240 250 240 250 0-160 740 0 0-178-740 0 0-162z" horiz-adv-x="980" />
-
-<glyph glyph-name="right-thin" unicode="&#xe88d;" d="M742 100l0 162-742 0 0 178 742 0 0 160 238-250z" horiz-adv-x="980" />
-
-<glyph glyph-name="up-thin" unicode="&#xe88e;" d="M500 602l-162 0 0-742-176 0 0 742-162 0 250 238z" horiz-adv-x="500" />
-
-<glyph glyph-name="ccw" unicode="&#xe88f;" d="M532 736q170 0 289-120t119-290-119-290-289-120q-142 0-252 88l70 74q84-60 182-60 126 0 216 90t90 218-90 218-216 90q-124 0-214-87t-92-211l142 0-184-204-184 204 124 0q2 166 122 283t286 117z" horiz-adv-x="940" />
-
-<glyph glyph-name="cw" unicode="&#xe890;" d="M408 760q168 0 287-116t123-282l122 0-184-206-184 206 144 0q-4 124-94 210t-214 86q-126 0-216-90t-90-218q0-126 90-216t216-90q104 0 182 60l70-76q-110-88-252-88-168 0-288 120t-120 290 120 290 288 120z" horiz-adv-x="940" />
-
-<glyph glyph-name="arrows-ccw" unicode="&#xe891;" d="M186 140l116 116 0-292-276 16 88 86q-116 122-114 290t120 288q100 100 240 116l4-102q-100-16-172-88-88-88-90-213t84-217z m332 598l276-16-88-86q116-122 114-290t-120-288q-96-98-240-118l-2 104q98 16 170 88 88 88 90 213t-84 217l-114-116z" horiz-adv-x="820" />
-
-<glyph glyph-name="level-down" unicode="&#xe892;" d="M100 200q-42 0-71 30t-29 70l0 350 140 0 0-310 364 0 0 150 240-220-240-220 0 150-404 0z" horiz-adv-x="744" />
-
-<glyph glyph-name="level-up" unicode="&#xe893;" d="M200 350l0-90-200 160 200 170 0-100 550 0q40 0 70-29t30-71l0-280-140 0 0 240-510 0z" horiz-adv-x="850" />
-
-<glyph glyph-name="shuffle" unicode="&#xe894;" d="M754 516q-54 0-105-32t-80-66-83-104q-48-62-75-94t-78-77-107-66-122-21l-104 0 0 140 104 0q54 0 106 32t81 66 83 104q62 82 101 126t116 88 163 44l36 0 0 120 210-180-210-180 0 100-36 0z m-484-88q-74 78-166 78l-104 0 0 140 104 0q140 0 254-108-14-16-37-45t-27-33q-8-12-24-32z m520-242l0 100 210-180-210-180 0 120-36 0q-140 0-260 116 46 58 72 92 0 2 6 9t8 11q84-88 174-88l36 0z" horiz-adv-x="1000" />
-
-<glyph glyph-name="loop" unicode="&#xe895;" d="M800 540q42 0 71-29t29-71l0-290q0-40-29-70t-71-30l-700 0q-40 0-70 30t-30 70l0 290q0 42 30 71t70 29l250 0 0 110 200-180-200-180 0 110-210 0 0-210 620 0 0 210-150 0 0 140 190 0z" horiz-adv-x="900" />
-
-<glyph glyph-name="switch" unicode="&#xe896;" d="M700 592l0-140-500 0 0-90-200 160 200 170 0-100 500 0z m300-420l-200-160 0 90-500 0 0 140 500 0 0 100z" horiz-adv-x="1000" />
-
-<glyph glyph-name="play" unicode="&#xe897;" d="M486 376q14-10 14-26 0-14-14-24l-428-266q-24-16-41-6t-17 40l0 514q0 30 17 40t41-6z" horiz-adv-x="500" />
-
-<glyph glyph-name="stop" unicode="&#xe898;" d="M526 650q74 0 74-64l0-470q0-66-74-66l-450 0q-76 0-76 66l0 470q0 36 18 50t58 14l450 0z" horiz-adv-x="600" />
-
-<glyph glyph-name="pause" unicode="&#xe899;" d="M440 700q90 0 90-64l0-570q0-66-90-66t-90 66l0 570q0 64 90 64z m-350 0q90 0 90-64l0-570q0-66-90-66t-90 66l0 570q0 64 90 64z" horiz-adv-x="530" />
-
-<glyph glyph-name="record" unicode="&#xe89a;" d="M350 700q146 0 248-102t102-248q0-144-102-247t-248-103-248 103-102 247q0 146 102 248t248 102z" horiz-adv-x="700" />
-
-<glyph glyph-name="to-end" unicode="&#xe89b;" d="M412 374q14-10 14-24 0-12-14-22l-362-228q-22-14-36-5t-14 35l0 442q0 26 14 35t36-5z m114 268q74 0 74-58l0-466q0-58-74-58-76 0-76 58l0 466q0 58 76 58z" horiz-adv-x="600" />
-
-<glyph glyph-name="to-start" unicode="&#xe89c;" d="M174 350q0 14 14 24l364 228q20 14 34 5t14-35l0-442q0-26-14-35t-34 5l-364 228q-14 10-14 22z m-174 234q0 58 76 58 74 0 74-58l0-466q0-58-74-58-76 0-76 58l0 466z" horiz-adv-x="600" />
-
-<glyph glyph-name="fast-forward" unicode="&#xe89d;" d="M866 374q14-10 14-24t-14-22l-372-248q-22-14-37-6t-15 36l0 482q0 28 15 36t37-6z m-454 0q14-10 14-24t-14-22l-360-248q-20-14-36-6t-16 36l0 482q0 28 16 36t36-6z" horiz-adv-x="880" />
-
-<glyph glyph-name="fast-backward" unicode="&#xe89e;" d="M0 350q0 14 14 24l374 248q20 14 36 6t16-36l0-482q0-28-16-36t-36 6l-374 248q-14 8-14 22z m454 0q0 14 14 24l360 248q20 14 36 6t16-36l0-482q0-28-16-36t-36 6l-360 248q-14 8-14 22z" horiz-adv-x="880" />
-
-<glyph glyph-name="progress-0" unicode="&#xe89f;" d="M1000 450l0-250q0-42-29-71t-71-29l-800 0q-40 0-70 29t-30 71l0 300q0 40 30 70t70 30l800 0q42 0 71-30t29-70l0-50z m-100-250l0 300-800 0 0-300 800 0z" horiz-adv-x="1000" />
-
-<glyph glyph-name="progress-1" unicode="&#xe8a0;" d="M1000 450l0-250q0-42-29-71t-71-29l-800 0q-40 0-70 29t-30 71l0 300q0 40 30 70t70 30l800 0q42 0 71-30t29-70l0-50z m-100-250l0 300-800 0 0-300 800 0z m-750 50l0 198 200 0 0-198-200 0z" horiz-adv-x="1000" />
-
-<glyph glyph-name="progress-2" unicode="&#xe8a1;" d="M1000 450l0-250q0-42-29-71t-71-29l-800 0q-40 0-70 29t-30 71l0 300q0 40 30 70t70 30l800 0q42 0 71-30t29-70l0-50z m-100-250l0 300-800 0 0-300 800 0z m-750 50l0 198 200 0 0-198-200 0z m250 0l0 198 200 0 0-198-200 0z" horiz-adv-x="1000" />
-
-<glyph glyph-name="progress-3" unicode="&#xe8a2;" d="M1000 450l0-250q0-42-29-71t-71-29l-800 0q-40 0-70 29t-30 71l0 300q0 40 30 70t70 30l800 0q42 0 71-30t29-70l0-50z m-100-250l0 300-800 0 0-300 800 0z m-750 50l0 198 200 0 0-198-200 0z m250 0l0 198 200 0 0-198-200 0z m250 198l200 0 0-198-200 0 0 198z" horiz-adv-x="1000" />
-
-<glyph glyph-name="target" unicode="&#xe8a3;" d="M430 780q178 0 304-126t126-304-126-304-304-126-304 126-126 304 126 304 304 126z m36-778q124 14 212 102t100 212l-192 0 0 70 192 0q-12 124-100 212t-212 102l0-194-70 0 0 194q-124-14-213-102t-101-212l194 0 0-70-194 0q12-124 101-212t213-102l0 194 70 0 0-194z" horiz-adv-x="860" />
-
-<glyph glyph-name="list" unicode="&#xe8a5;" d="M100 200q20 0 35-15t15-35-15-35-35-15l-50 0q-20 0-35 15t-15 35 14 35 36 15l50 0z m0 200q20 0 35-15t15-35-15-35-35-15l-50 0q-20 0-35 15t-15 35 14 35 36 15l50 0z m0 200q20 0 35-15t15-35-15-35-35-15l-50 0q-20 0-35 15t-15 35 14 35 36 15l50 0z m200-100q-20 0-35 15t-15 35 15 35 35 15l350 0q22 0 36-15t14-35-15-35-35-15l-350 0z m350-100q22 0 36-15t14-35-15-35-35-15l-350 0q-20 0-35 15t-15 35 15 35 35 15l350 0z m0-200q22 0 36-15t14-35-15-35-35-15l-350 0q-20 0-35 15t-15 35 15 35 35 15l350 0z" horiz-adv-x="700" />
-
-<glyph glyph-name="list-add" unicode="&#xe8a6;" d="M350 400q22 0 36-15t14-35-15-35-35-15l-300 0q-20 0-35 15t-15 35 14 35 36 15l300 0z m0-200q22 0 36-15t14-35-15-35-35-15l-300 0q-20 0-35 15t-15 35 14 35 36 15l300 0z m620 200q30 0 30-50t-30-50l-170 0 0-170q0-30-50-30t-50 30l0 170-164 0q-30 0-30 50t30 50l164 0 0 170q0 30 50 30t50-30l0-170 170 0z m-620 200q22 0 36-15t14-35-15-35-35-15l-300 0q-20 0-35 15t-15 35 14 35 36 15l300 0z" horiz-adv-x="1000" />
-
-<glyph glyph-name="battery" unicode="&#xe8a9;" d="M770 350q0-98 36-157t78-59l66 0q-30-46-64-65t-118-19l-500 0q-130 0-199 94t-69 206q0 110 69 205t199 95l500 0q84 0 118-19t64-65l-66 0q-42 0-78-60t-36-156z m-136-90q10 12-8 26-136 134-178 164-16 10-26 13t-18-5-10-12-8-18l-22-56-148 66q-26 12-34 0-8-14 8-28 136-132 180-162 34-16 42-11t18 31l24 58 146-68q26-12 34 2z m310 192q22 0 39-27t17-71-17-72-39-28l-38 0q-22 0-38 28t-16 72 16 71 38 27l38 0z" horiz-adv-x="1000" />
-
-<glyph glyph-name="back-in-time" unicode="&#xe8aa;" d="M532 760q170 0 289-120t119-290-119-290-289-120q-138 0-252 88l70 76q82-60 182-60 126 0 216 90t90 216q0 128-90 218t-216 90q-124 0-213-86t-93-210l142 0-184-206-184 206 124 0q4 166 123 282t285 116z m-36-190l70 0 0-204 130-130-50-50-150 150 0 234z" horiz-adv-x="940" />
-
-<glyph glyph-name="monitor" unicode="&#xe8ab;" d="M900 790q42 0 71-30t29-70l0-550q0-42-29-77t-69-43l-218-44 86-38q50-28-20-28l-500 0q-98 0 32 52l36 14-220 44q-40 8-69 43t-29 77l0 550q0 40 30 70t70 30l800 0z m0-646l0 556-800 0 0-556 800 0z" horiz-adv-x="1000" />
-
-<glyph glyph-name="mobile" unicode="&#xe8ac;" d="M480 840q42 0 71-29t29-71l0-780q0-40-29-70t-71-30l-380 0q-40 0-70 30t-30 70l0 780q0 42 30 71t70 29l380 0z m-190-940q30 0 50 15t20 35q0 22-20 36t-50 14q-28 0-49-15t-21-35 21-35 49-15z m210 150l0 660-420 0 0-660 420 0z" horiz-adv-x="580" />
-
-<glyph glyph-name="cd" unicode="&#xe8ae;" d="M460 810q190 0 325-135t135-325-135-325-325-135-325 135-135 325 135 325 325 135z m0-610q62 0 106 44t44 106q0 64-43 107t-107 43q-62 0-106-44t-44-106 44-106 106-44z" horiz-adv-x="920" />
-
-<glyph glyph-name="inbox" unicode="&#xe8af;" d="M967 398q40-42 30-72l-28-154q-4-20-22-33t-40-13l-816 0q-22 0-40 13t-22 33l-28 154q-8 32 32 72 8 10 36 38t68 67 52 51q22 22 52 22l516 0q30 0 52-22 16-16 53-52t67-65 38-39z m-266-32l178 0-102 114-556 0-102-114 178 0q8 0 12-8l40-100 300 0 40 100q4 8 12 8z" horiz-adv-x="999" />
-
-<glyph glyph-name="install" unicode="&#xe8b0;" d="M884 306q24-52 14-96l-34-184q-2-20-19-35t-39-15l-712 0q-22 0-39 15t-19 35l-34 184q-8 50 14 96l158 374q22 46 72 46l104 0-20-204-134 0 254-210 256 210-136 0-18 204 102 0q50 0 74-46z m-68-132q2 22-10 38t-34 16l-644 0q-22 0-34-16t-10-38l14-74q2-22 19-37t37-15l592 0q22 0 39 15t19 37z" horiz-adv-x="901" />
-
-<glyph glyph-name="globe" unicode="&#xe8b1;" d="M480 830q200 0 340-141t140-339q0-200-140-340t-340-140q-198 0-339 140t-141 340q0 198 141 339t339 141z m410-480q0 132-78 239t-202 149q-18-24-16-32 4-38 18-51t30-7l32 12t20 2q22-24 0-47t-45-56-1-77q34-64 96-64 28-2 43-36t17-66q10-80-14-140-22-44 14-76 86 112 86 250z m-466 404q-112-14-199-84t-127-174q6 0 22-2t28-3 26-4 24-8 12-13q4-12-14-45t-18-61q0-30 38-56t38-46q0-28 8-68t8-44q0-12 36-54t52-42q10 0 11 22t-2 54-3 40q0 32 14 74 12 42 59 70t55 46q16 34 9 61t-17 43-34 28-41 17-37 9-22 4q-16 6-42 7t-36-3-27 11-17 29q0 10 15 27t35 37 28 30q8 14 17 21t22 16 27 21q4 4 25 17t27 23z m-72-794q66-20 128-20 128 0 226 68-26 44-118 34-24-2-65-17t-47-17q-74-16-76-16-12-2-26-14t-22-18z" horiz-adv-x="960" />
-
-<glyph glyph-name="cloud" unicode="&#xe8b2;" d="M760 494q100 0 170-68t70-166-70-166-170-68l-578 0q-74 0-128 52t-54 124q0 74 53 126t129 52q2 0 10-1t10-1q-2 12-2 38 0 108 78 184t188 76q90 0 160-52t94-134q28 4 40 4z" horiz-adv-x="1000" />
-
-<glyph glyph-name="cloud-thunder" unicode="&#xe8b3;" d="M760 494q100 0 170-68t70-166-70-166-170-68l-578 0q-74 0-128 52t-54 124q0 74 53 126t129 52q2 0 10-1t10-1q-2 12-2 38 0 108 78 184t188 76q90 0 160-52t94-134q28 4 40 4z m-192-216q14 16 14 30 0 20-30 32l-4 0q-26 14-38 16l50 116q6 0 6 20 0 14-8 18-16 10-34-8-2-2-30-32t-61-66-45-52q-12-18-12-30 0-22 30-30l4-2q8-4 38-16l-52-114-2-8q-2-8-2-14 0-10 8-18 18-10 34 10 100 100 134 148z" horiz-adv-x="1000" />
-
-<glyph glyph-name="flash" unicode="&#xe8b4;" d="M40-100q-4 4 35 94t79 182 38 98-94 45-98 55q-4 12 84 120t180 209 96 97q6-4-74-186t-78-186 95-43 97-57q4-20-174-227t-186-201z" horiz-adv-x="400" />
-
-<glyph glyph-name="moon" unicode="&#xe8b5;" d="M524 238q106 106 125 252t-53 270q52-26 96-72 128-128 128-309t-128-309-310-128-310 128q-40 40-72 94 124-70 271-51t253 125z" horiz-adv-x="820" />
-
-<glyph glyph-name="flight" unicode="&#xe8b6;" d="M268-120l124 400-180 0-112-100-100 0 80 170-80 170 100 0 112-100 180 0-124 400 100 0 224-400 274 0t36-4 46-11 36-21 16-34q0-32-38-49t-74-19l-38-2-258 0-224-400-100 0z" horiz-adv-x="1000" />
-
-<glyph glyph-name="paper-plane" unicode="&#xe8b7;" d="M894 720q14 4 22-3t4-19q-2-6-72-310t-74-316q-2-14-14-19t-24 1l-248 134-30 16 22 26q388 420 394 426 4 4-1 9t-9 1l-550-402-112 44-190 76q-12 4-12 12t12 12q8 4 441 157t441 155z m-582-728l0 204 160-82q-130-116-142-128-18-14-18 6z" horiz-adv-x="921" />
-
-<glyph glyph-name="leaf" unicode="&#xe8b8;" d="M236 646q182 106 506 66 168-22 196-50 4-6-2-10-76-40-130-109t-78-132-65-132-93-105q-138-96-382-4-66-76-114-176-12-24-47-7t-25 39q44 100 129 193t176 153 176 106 141 68l54 20q-14 0-41-1t-104-14-148-38-162-84-161-141q-22 242 174 358z" horiz-adv-x="940" />
-
-<glyph glyph-name="lifebuoy" unicode="&#xe8b9;" d="M454 810q190 2 326-130t140-322q2-190-131-327t-323-141q-190-2-327 131t-139 323q-4 190 130 327t324 139z m0-60q-94 0-178-44l62-104q56 28 122 28t122-28l62 104q-88 46-190 44z m-246-522q-28 60-28 122 0 64 28 124l-102 62q-46-88-46-190 2-96 46-180z m258-278q98 4 178 46l-62 104q-60-30-122-30t-122 30l-62-104q86-46 190-46z m-6 180q92 0 156 65t64 155q0 92-64 156t-156 64-156-64-64-156q0-90 64-155t156-65z m252 98l104-62q46 96 44 190 0 96-44 180l-104-62q28-60 28-124 0-62-28-122z" horiz-adv-x="920" />
-
-<glyph glyph-name="mouse" unicode="&#xe8ba;" d="M551 130q28-80-17-157t-139-111q-94-28-175 9t-103 117l-106 384q-20 68 6 134t84 106l-96 186q-14 34 14 48 30 18 48-14l98-192q80 22 154-16t102-116z m-324 274q28 10 40 36t4 54q-10 28-35 41t-53 5q-28-10-40-36t-4-54q10-28 35-41t53-5z" horiz-adv-x="561" />
-
-<glyph glyph-name="briefcase" unicode="&#xe8bb;" d="M456 326l0-100-456 0q8 226 10 292 4 108 100 108l160 0q16 26 37 67t23 45q14 26 23 32t37 6l222 0q26 0 36-7t22-31q18-32 60-112l160 0q96 0 100-108l10-292-454 0 0 100-90 0z m-74 354l-28-54 292 0-28 54q-14 26-42 26l-152 0q-28 0-42-26z m164-604l0 100 430 0q-6-88-10-166-6-84-90-84l-750 0q-90 0-90 84l-10 166 430 0 0-100 90 0z" horiz-adv-x="1000" />
-
-<glyph glyph-name="suitcase" unicode="&#xe8bc;" d="M900 650q42 0 71-30t29-70l0-550q0-42-29-71t-71-29l-50 0 0 750 50 0z m-900-100q0 40 30 70t70 30l50 0 0-750-50 0q-40 0-70 29t-30 71l0 550z m670 204l0-104 110 0 0-750-560 0 0 750 110 0 0 104q98 46 170 46t170-46z m-60-104l0 66q-52 24-110 24-54 0-110-24l0-66 220 0z" horiz-adv-x="1000" />
-
-<glyph glyph-name="dot" unicode="&#xe8bd;" d="M110 460q46 0 78-32t32-78q0-44-32-77t-78-33-78 33-32 77q0 46 32 78t78 32z" horiz-adv-x="220" />
-
-<glyph glyph-name="dot-2" unicode="&#xe8be;" d="M110 460q46 0 78-32t32-78q0-44-32-77t-78-33-78 32-32 78 32 78 78 32z m350 0q46 0 78-32t32-78q0-44-33-77t-77-33q-46 0-78 32t-32 78 32 78 78 32z" horiz-adv-x="570" />
-
-<glyph glyph-name="dot-3" unicode="&#xe8bf;" d="M110 460q46 0 78-32t32-78q0-44-32-77t-78-33-78 33-32 77q0 46 32 78t78 32z m350 0q46 0 78-32t32-78q0-44-33-77t-77-33-77 33-33 77q0 46 32 78t78 32z m350 0q46 0 78-32t32-78q0-44-32-77t-78-33-78 33-32 77q0 46 32 78t78 32z" horiz-adv-x="920" />
-
-<glyph glyph-name="brush" unicode="&#xe8c0;" d="M118 170q38 34 85 29t87-45q42-40 48-87t-30-83q-86-84-228-102-84-12-80 14 0 4 6 10 52 60 64 145t48 119z m840 646q26-26-148-248t-292-338q-38-38-124-104-8-6-16 8-18 34-48 64-32 32-66 48-16 6-8 16 64 84 104 122 118 116 344 287t254 145z" horiz-adv-x="962" />
-
-<glyph glyph-name="infinity" unicode="&#xe8c2;" d="M796 570q84 0 144-53t60-167q0-112-60-166t-144-54q-78 0-157 40t-139 106q-58-66-137-106t-157-40q-86 0-146 54t-60 166q0 114 60 167t146 53q78 0 157-39t137-105q58 66 138 105t158 39z m-590-352q60 0 127 37t113 95q-46 58-112 95t-128 37q-114 0-114-132t114-132z m590 0q114 0 114 132t-114 132q-62 0-129-37t-111-95q44-58 111-95t129-37z" horiz-adv-x="1000" />
-
-<glyph glyph-name="erase" unicode="&#xe8c3;" d="M902 700q42 0 71-29t29-71l0-500q0-40-29-70t-71-30l-478 0q-38 0-70 28l-340 296q-28 26 0 54l340 296q30 26 70 26l478 0z m-140-550l72 74-128 126 128 128-72 72-128-126-128 126-72-72 128-128-128-126 72-74 128 128z" horiz-adv-x="1002" />
-
-<glyph glyph-name="chart-pie" unicode="&#xe8c4;" d="M368 770l0-368-368 0q18 146 121 249t247 119z m106 0q156-20 261-139t105-279q0-174-123-298t-299-124q-160 0-278 105t-140 263l424 0q20 0 35 14t15 36l0 422z" horiz-adv-x="840" />
-
-<glyph glyph-name="chart-line" unicode="&#xe8c5;" d="M34 284q-42 10-32 56 10 42 54 32l98-24-52-80z m890-12q14 12 33 11t31-15q32-32-2-64l-252-226q-12-12-30-12-14 0-28 10l-286 220-54 14 50 80 36-8q12-4 16-8l264-204z m-490 220l-350-550q-12-22-38-22-12 0-24 8-16 10-20 29t6 33l374 588q8 16 28 20 18 6 36-6l246-156 226 326q10 16 28 19t34-9q38-24 12-62l-252-362q-24-36-62-12z" horiz-adv-x="1003" />
-
-<glyph glyph-name="chart-bar" unicode="&#xe8c6;" d="M750 800q22 0 36-15t14-35l0-850-200 0 0 850q0 50 40 50l110 0z m-300-300q22 0 36-15t14-35l0-550-200 0 0 550q0 50 40 50l110 0z m-300-300q22 0 36-15t14-35l0-250-200 0 0 250q0 50 40 50l110 0z" horiz-adv-x="800" />
-
-<glyph glyph-name="chart-area" unicode="&#xe8c7;" d="M964 732q16 22 16-4l0-768-964 0q-12 0-15 7t5 17l230 288q20 22 40 2l74-66q10-8 21-7t17 11l158 238q16 26 38 4l112-104q20-20 38 4z" horiz-adv-x="980" />
-
-<glyph glyph-name="tape" unicode="&#xe8c8;" d="M770 580q96 0 163-67t67-163q0-94-67-162t-163-68l-540 0q-94 0-162 68t-68 162q0 96 68 163t162 67q96 0 163-67t67-163q0-72-40-130l160 0q-40 64-40 130 0 96 68 163t162 67z m-670-230q0-52 38-91t92-39 92 39 38 91q0 54-38 92t-92 38-92-38-38-92z m670-130q54 0 92 39t38 91q0 54-38 92t-92 38-92-38-38-92q0-52 38-91t92-39z" horiz-adv-x="1000" />
-
-<glyph glyph-name="graduation-cap" unicode="&#xe8c9;" d="M166 238l334-168 276 136q-4-22-8-47t-6-35-11-23-24-23-45-22q-40-18-80-41t-63-34-39-11-40 13-64 37-80 40q-72 32-103 69t-47 109z m810 246q24-14 24-33t-24-33l-78-44-308 102q-22 36-90 36-40 0-67-16t-27-40 27-40 67-16q26 0 36 4l292-68-268-152q-60-32-120 0l-416 234q-24 14-24 33t24 33l416 234q60 32 120 0z m-128-442q18 116 13 182t-19 90l-14 22 70 38q6-8 12-28t17-101-7-197q-4-26-22-30t-35 5-15 19z" horiz-adv-x="1000" />
-
-<glyph glyph-name="language" unicode="&#xe8ca;" d="M988 306q30-82-10-176t-134-160q-10 0-12 2t-16 19-16 19q-2 6 2 10 86 60 117 152t-11 148q-16-38-39-76t-59-80-86-65-106-15q-52 6-84 41t-32 93q0 84 60 148 50 50 114 66l-2 100q-140-24-146-24-6-2-10 4 0 2-5 29t-5 31q-2 2 1 4t7 2l156 28q0 110-2 114 0 8 8 8 46 0 52 2 10 0 10-8l0-104q158 22 164 22 8 4 10-6 0-2 4-23t4-25q4-10-4-12l-176-30 0-102 12 0q86 0 148-36t86-100z m-370-160q28-6 62 6l-4 214q-34-12-60-40-44-44-44-108 0-66 46-72z m122 28q28 24 58 68t45 79 7 41q-36 18-96 18-2 0-6-1t-6-1z m-448 382q10-28 53-165t83-261 40-126q0-4-4-4l-86 0q-6 0-6 4l-50 166-176 0q-48-164-50-166 0-4-6-4l-86 0q-4 0-4 4 10 18 176 552 2 8 10 8l96 0q10 0 10-8z m-130-316l144 0-72 264z" horiz-adv-x="1001" />
-
-<glyph glyph-name="ticket" unicode="&#xe8cb;" d="M216 272l326 326 178-178-326-326z m710 244q14-14 14-36t-14-36l-550-550q-16-16-36-16t-36 16l-76 76q12 20 12 48 0 42-29 72t-71 30q-22 0-50-14l-74 76q-16 16-16 36t16 36l550 550q14 14 36 14t36-14l74-76q-12-22-12-48 0-42 30-71t72-29q26 0 48 12z m-532-502l406 406-258 258-408-406z" horiz-adv-x="940" />
-
-<glyph glyph-name="water" unicode="&#xe8cc;" d="M168 844q10-86 50-155t73-123 33-112q0-66-48-113t-114-47-114 47-48 113q0 58 33 112t73 123 50 155q2 4 7 4t5-4z m616 0q10-86 50-155t73-123 33-112q0-66-48-113t-114-47-114 47-48 113q0 48 21 93t48 78 53 92 34 127q2 4 7 4t5-4z m-320-444q2 4 7 4t5-4q10-86 50-155t73-123 33-112q0-66-48-113t-114-47-114 47-48 113q0 58 33 112t73 123 50 155z" horiz-adv-x="940" />
-
-<glyph glyph-name="droplet" unicode="&#xe8cd;" d="M290 822q14-118 60-219t92-159 82-136 36-160q0-114-83-196t-197-82-197 82-83 196q0 82 36 160t82 136 92 159 60 219q2 8 11 8t9-8z m-42-392q2 4-2 14-6 6-14 6t-12-6l-40-58q-32-46-48-70t-34-75-18-101q0-24 17-41t41-17q58 0 58 68 0 94 42 246 2 6 5 17t5 17z" horiz-adv-x="560" />
-
-<glyph glyph-name="air" unicode="&#xe8ce;" d="M85 534q-16-14-36-12t-34 18q-14 14-12 36t18 36q48 40 79 60t89 40 129 4 159-66 155-53 100 16 89 67q38 30 70-6 32-40-6-72-122-110-234-110-100 0-222 70-68 38-119 52t-93 0-65-29-67-51z m736-110q38 32 70-6 32-40-6-72-40-34-65-53t-72-38-97-19q-96 0-222 70-68 38-119 52t-93 0-65-29-67-51q-14-14-35-12t-35 18q-32 40 6 72 38 34 60 50t69 38 88 23 105-15 134-56q68-38 119-52t93 0 65 29 67 51z m0-256q38 32 70-6 14-14 12-36t-18-36q-40-34-65-53t-72-38-97-19q-96 0-222 70-68 38-119 52t-93 1-66-29-66-52q-14-14-35-12t-35 18q-32 40 6 72 38 34 60 50t69 38 88 23 105-15 134-56q68-38 119-52t93 0 65 29 67 51z" horiz-adv-x="905" />
-
-<glyph glyph-name="credit-card" unicode="&#xe8cf;" d="M900 700q42 0 71-30t29-70l0-500q0-42-29-71t-71-29l-800 0q-40 0-70 29t-30 71l0 500q0 40 30 70t70 30l800 0z m0-600l0 300-800 0 0-300 800 0z m0 450l0 50-800 0 0-50 800 0z m-700-256l30 0 0-30-30 0 0 30z m180-60l30 0 0 30 30 0 0 30 60 0 0-30-30 0 0-30-30 0 0-30-60 0 0 30z m120-30l-30 0 0 30 30 0 0-30z m-150 0l-60 0 0 30 60 0 0-30z m30 60l0-30-30 0 0 60 60 0 0-30-30 0z m-120-30l0-30-60 0 0 30 30 0 0 30 30 0 0 30 60 0 0-30-30 0 0-30-30 0z" horiz-adv-x="1000" />
-
-<glyph glyph-name="floppy" unicode="&#xe8d0;" d="M658 750l142-156 0-544q0-40-29-70t-71-30l-600 0q-40 0-70 30t-30 70l0 600q0 42 30 71t70 29l558 0z m-58-300l0 250-400 0 0-250q0-20 15-35t35-15l300 0q20 0 35 15t15 35z m-50 200l0-200-100 0 0 200 100 0z" horiz-adv-x="800" />
-
-<glyph glyph-name="clipboard" unicode="&#xe8d1;" d="M630 750q28 0 49-21t21-49l0-760q0-30-21-50t-49-20l-560 0q-28 0-49 20t-21 50l0 760q0 28 21 49t49 21l60-150 440 0z m-100-100l-360 0-44 100 108 0 36 100 160 0 36-100 110 0z" horiz-adv-x="700" />
-
-<glyph glyph-name="megaphone" unicode="&#xe8d2;" d="M792 500q58-138 67-258t-39-140q-28-12-61 3t-65 40-99 41-149 8q-28-4-42-19t-6-37q22-56 46-108 4-10 24-22t24-20q14-34-22-46-50-22-102-40-30-10-54 42-32 76-58 132-6 12-34 17t-46 31q-30-10-38-14-34-12-74 12t-54 60q-17 32-5 79t43 61q126 52 213 108t124 103 59 92 25 78 15 59 36 36q48 20 130-70t142-228z m-28-300q8 4 10 38t-11 98-41 128q-28 66-67 123t-67 84-36 23-10-42 10-105 40-133 68-119 68-76 36-19z" horiz-adv-x="860" />
-
-<glyph glyph-name="database" unicode="&#xe8d3;" d="M686 208q14 20 14-2l0-100q0-74-104-135t-246-61q-140 0-245 61t-105 135l0 100q0 8 4 10t10-8q32-52 125-86t211-34 211 34 125 86z m2 254q8 16 12 0l0-116q0-68-102-114t-248-46q-144 0-247 46t-103 114l0 116q0 20 14 0 30-46 124-75t212-29 212 29 126 75z m-338 328q144 0 247-39t103-93l0-64q0-58-103-99t-247-41-247 41-103 99l0 64q0 54 103 93t247 39z" horiz-adv-x="700" />
-
-<glyph glyph-name="drive" unicode="&#xe8d4;" d="M884 304q26-44 14-96l-34-184q-2-20-19-35t-39-15l-712 0q-20 0-38 15t-20 35l-34 184q-8 52 14 96l158 374q22 46 72 46l408 0q50 0 74-46z m-68-132q2 22-10 38t-34 16l-644 0q-22 0-34-16t-10-38l14-74q2-22 19-37t39-15l590 0q22 0 39 15t19 37z" horiz-adv-x="902" />
-
-<glyph glyph-name="bucket" unicode="&#xe8d5;" d="M522 780q174 0 286-49t104-105q-6-38-48-307t-44-281q-2-18-37-44t-107-50-154-24-153 24-106 50-37 44q0 2-4 30 82-6 163 35t139 117q28 0 48 20t20 50q0 28-20 49t-50 21q-28 0-49-21t-21-49q0-20 10-36-48-58-115-89t-131-27q-102 10-157 57t-59 109q-8 122 156 184-18 94-22 138-8 56 104 105t284 49z m-452-470q4-32 37-59t91-39l-32 204q-100-44-96-106z m452 212q82 0 157 18t113 39 38 35-38 35-112 39-158 18q-82 0-156-18t-112-39-38-35 38-35 112-39 156-18z" horiz-adv-x="913" />
-
-<glyph glyph-name="thermometer" unicode="&#xe8d6;" d="M400 356q64-36 102-98t38-138q0-112-79-191t-191-79-191 79-79 191q0 76 38 138t102 98l0 444q0 50 40 50l170 0q20 0 35-15t15-35l0-444z m-130-406q70 0 120 50t50 120q0 56-32 100t-84 60l0 370-100 0 0-368q-54-16-89-61t-35-101q0-70 50-120t120-50z" horiz-adv-x="540" />
-
-<glyph glyph-name="key" unicode="&#xe8d7;" d="M774 612q20-116-28-215t-150-117q-66-12-130-2l-118-194-70-12-104-166q-14-28-46-32l-76-14q-12-4-22 4t-12 22l-16 98q-8 30 12 56l258 386q-24 50-38 120-18 106 53 187t185 101q106 20 195-45t107-177z m-126-76q30 44 21 97t-51 83q-42 32-92 22t-80-54q-8-12-12-23t-1-20 5-16 13-17 18-15 22-16 23-17q6-4 22-16t23-16 19-12 19-8 17 1 18 8 16 19z" horiz-adv-x="780" />
-
-<glyph glyph-name="flow-cascade" unicode="&#xe8d8;" d="M520 120q50 0 85-35t35-85-35-85-85-35q-80 0-110 74l-164 0q-88 0-131 54t-43 118l0 464q-72 34-72 110 0 50 35 85t85 35 85-35 35-85q0-76-72-110l0-114q0-78 78-78l164 0q30 72 110 72 50 0 85-35t35-85-35-85-85-35q-80 0-110 74l-164 0q-42 0-78 16l0-194q0-78 78-78l164 0q30 72 110 72z m0 300q-28 0-49-20t-21-50q0-28 21-48t49-20 49 20 21 48q0 30-21 50t-49 20z m-470 280q0-28 21-48t49-20 49 20 21 48q0 30-21 50t-49 20-49-20-21-50z m470-768q28 0 49 20t21 48q0 30-21 50t-49 20-49-20-21-50q0-28 21-48t49-20z" horiz-adv-x="640" />
-
-<glyph glyph-name="flow-branch" unicode="&#xe8d9;" d="M640 650q0-80-74-110-6-58-28-101t-61-69-68-38-75-26q-42-14-63-22t-47-24-38-40-16-60q70-30 70-110 0-50-35-85t-85-35-85 35-35 85q0 78 72 112l0 378q-72 34-72 110 0 50 35 85t85 35 85-35 35-85q0-76-72-110l0-204q40 30 138 60 58 18 84 29t51 41 29 76q-70 32-70 108 0 50 35 85t85 35 85-35 35-85z m-588 0q0-28 20-48t48-20 49 20 21 48q0 30-21 50t-49 20-48-20-20-50z m68-668q28 0 49 20t21 48q0 30-21 50t-49 20-48-20-20-50q0-28 20-48t48-20z m400 600q28 0 49 20t21 48q0 30-21 50t-49 20-48-20-20-50q0-28 20-48t48-20z" horiz-adv-x="640" />
-
-<glyph glyph-name="flow-tree" unicode="&#xe8da;" d="M868 112q72-34 72-112 0-50-35-85t-85-35-85 35-35 85q0 78 72 112l0 114q0 78-76 78l-100 0q-44 0-78 12l0-204q72-34 72-112 0-50-35-85t-85-35-85 35-35 85q0 78 72 112l0 204q-30-12-76-12l-100 0q-34 0-53-19t-22-33-3-26l0-114q72-34 72-112 0-50-35-85t-85-35-85 35-35 85q0 78 72 112l0 114q0 64 43 118t131 54l100 0q76 0 76 52l0 140q-72 34-72 110 0 50 35 85t85 35 85-35 35-85q0-76-72-110l0-140q0-52 78-52l100 0q86 0 129-54t43-118l0-114z m-678-112q0 30-21 50t-49 20-48-20-20-50q0-28 20-48t48-20 49 20 21 48z m212 700q0-28 20-48t48-20 49 20 21 48q0 30-21 50t-49 20-48-20-20-50z m138-700q0 30-21 50t-49 20-48-20-20-50q0-28 20-48t48-20 49 20 21 48z m280-68q28 0 49 20t21 48q0 30-21 50t-49 20-48-20-20-50q0-28 20-48t48-20z" horiz-adv-x="940" />
-
-<glyph glyph-name="flow-line" unicode="&#xe8db;" d="M168 162q72-34 72-112 0-50-35-85t-85-35-85 35-35 85q0 78 72 112l0 378q-72 34-72 110 0 50 35 85t85 35 85-35 35-85q0-76-72-110l0-378z m-116 488q0-28 20-48t48-20 49 20 21 48q0 30-21 50t-49 20-48-20-20-50z m68-668q28 0 49 20t21 48q0 30-21 50t-49 20-48-20-20-50q0-28 20-48t48-20z" horiz-adv-x="240" />
-
-<glyph glyph-name="flow-parallel" unicode="&#xe8dc;" d="M240 650q0-76-72-110l0-378q72-34 72-112 0-50-35-85t-85-35-85 35-35 85q0 78 72 112l0 378q-72 34-72 110 0 50 35 85t85 35 85-35 35-85z m-50-600q0 30-21 50t-49 20-48-20-20-50q0-28 20-48t48-20 49 20 21 48z m-70 532q28 0 49 20t21 48q0 30-21 50t-49 20-48-20-20-50q0-28 20-48t48-20z m448-420q72-34 72-112 0-50-35-85t-85-35-85 35-35 85q0 78 72 112l0 378q-72 34-72 110 0 50 35 85t85 35 85-35 35-85q0-76-72-110l0-378z m-116 488q0-28 20-48t48-20 49 20 21 48q0 30-21 50t-49 20-48-20-20-50z m68-668q28 0 49 20t21 48q0 30-21 50t-49 20-48-20-20-50q0-28 20-48t48-20z" horiz-adv-x="640" />
-
-<glyph glyph-name="rocket" unicode="&#xe8dd;" d="M543 236q6-50 8-81t-8-59-13-40-35-32-45-26-70-31-85-37q-32-12-45 4t-3 44l40 110-130 132-106-40q-28-12-43 2t-3 46q12 30 31 79t27 65 22 45 25 36 29 20 41 13l52 0t71-6q10 14 29 39t77 85 118 104 145 75 165 19q8 0 14-6 4-4 6-14 10-82-18-168t-76-151-98-118-86-81z m50 296q22-22 54-22t54 22q22 24 22 56t-22 56q-22 22-54 22t-54-22q-22-24-22-56t22-56z" horiz-adv-x="860" />
-
-<glyph glyph-name="gauge" unicode="&#xe8de;" d="M406 178q34 56 214 284t194 220q12-6-96-278t-138-326q-50-86-136-36t-38 136z m94 380q-168 0-284-127t-116-311q0-30 2-46 2-22-12-37t-34-17-36 12-18 34q0 8-1 26t-1 28q0 226 145 382t355 156q72 0 134-18l-70-86q-40 4-64 4z m362-62q138-154 138-376 0-38-2-56-2-20-16-33t-34-13l-4 0q-22 4-35 20t-11 36q2 14 2 46 0 150-80 268 6 14 20 51t22 57z" horiz-adv-x="1000" />
-</font>
-</defs>
-</svg>

BIN
src/mol-app/skin/fonts/fontello.ttf


BIN
src/mol-app/skin/fonts/fontello.woff


BIN
src/mol-app/skin/fonts/fontello.woff2


+ 0 - 135
src/mol-app/skin/icons.scss

@@ -1,135 +0,0 @@
-
-[class^="molstar-icon-"]:before, [class*=" molstar-icon-"]:before {
-    font-family: "fontello";
-    font-style: normal;
-    font-weight: normal;
-    speak: none;
-
-    display: inline-block;
-    text-decoration: inherit;
-    width: 1em;
-    margin-right: .2em;
-    text-align: center;
-    /* opacity: .8; */
-
-    /* For safety - reset parent styles, that can break glyph codes*/
-    font-variant: normal;
-    text-transform: none;
-
-    /* fix buttons height, for twitter bootstrap */
-    line-height: 1em;
-
-    /* Animation center compensation - margins should be symmetric */
-    /* remove if not needed */
-    margin-left: .2em;
-
-    /* you can be more comfortable with increased icons size */
-    /* font-size: 120%; */
-
-    /* Font smoothing. That was taken from TWBS */
-    -webkit-font-smoothing: antialiased;
-    -moz-osx-font-smoothing: grayscale;
-
-    /* Uncomment for 3D effect */
-    /* text-shadow: 1px 1px 1px rgba(127, 127, 127, 0.3); */
-  }
-
-  .molstar-icon-expand-layout:before {
-      content: "\e84a";
-  }
-
-  .molstar-icon-plus:before {
-      content: "\e816";
-  }
-
-  .molstar-icon-minus:before {
-      content: "\e819";
-  }
-
-  .molstar-icon-reset-scene:before {
-      content: "\e891";
-  }
-
-  .molstar-icon-ok:before {
-      content: "\e812";
-  }
-
-  .molstar-icon-cross:before {
-      content: "\e868";
-  }
-
-  .molstar-icon-off:before {
-      content: "\e813";
-  }
-
-  .molstar-icon-expand:before {
-      content: "\e885";
-  }
-
-  .molstar-icon-collapse:before {
-      content: "\e883";
-  }
-
-  .molstar-icon-visual-visibility:before {
-      content: "\e826";
-  }
-
-  .molstar-icon-abort:before {
-      content: "\e814";
-  }
-
-  .molstar-icon-focus-on-visual:before {
-      content: "\e8a3";
-  }
-
-  .molstar-icon-settings:before  {
-      content: "\e855";
-  }
-
-  .molstar-icon-tools:before {
-      content: "\e856";
-  }
-
-  .molstar-icon-log:before {
-      content: "\e8a5";
-  }
-
-  .molstar-icon-remove:before {
-      content: "\e847";
-  }
-
-  .molstar-icon-help:before {
-      content: '\e81c'
-  }
-
-  .molstar-icon-info:before {
-      content: '\e81e'
-  }
-
-  .molstar-icon-left-open-big:before {
-      content: '\e87c'
-  }
-
-  .molstar-icon-right-open-big:before {
-      content: '\e87d'
-  }
-
-  .molstar-icon-left-open:before {
-      content: '\e874'
-  }
-
-  .molstar-icon-right-open:before {
-      content: '\e875'
-  }
-
-  .molstar-icon-screenshot:before {
-      content: "\e80f";
-  }
-
-  .molstar-icon-help:before {
-      content: "\e81c";
-  }
-
-  .molstar-icon-help-circle:before {
-      content: "\e81d";
-  }

+ 0 - 29
src/mol-app/skin/layout.scss

@@ -1,29 +0,0 @@
-
-@import 'layout/common';
-
-.molstar-layout-standard-outside {
-    position: absolute;
-    @import 'layout/outside';
-}
-
-.molstar-layout-standard-landscape {
-    position: absolute;
-    @import 'layout/landscape';
-}
-
-.molstar-layout-standard-portrait {
-    position: absolute;
-    @import 'layout/portrait';
-}
-
-.molstar-layout-expanded {
-    position: fixed;
-
-    @media (orientation:landscape) {
-        @import 'layout/landscape';
-    };
-
-    @media (orientation:portrait) {
-        @import 'layout/portrait';
-    };
-}

+ 0 - 60
src/mol-app/skin/layout/common.scss

@@ -1,60 +0,0 @@
-
-.molstar-layout-expanded, .molstar-layout-standard {
-    left: 0;
-    right: 0;
-    top: 0;
-    bottom: 0;
-}
-
-.molstar-layout-region {
-    overflow: hidden;
-    background: $default-background;
-}
-
-.molstar-layout-static, .molstar-layout-scrollable {
-    position: absolute;
-}
-
-.molstar-layout-scrollable {
-    overflow-y: auto;
-}
-
-.molstar-layout-static {
-    overflow: hidden;
-}
-
-.molstar-layout-main, .molstar-layout-bottom, .molstar-layout-top {
-    .molstar-layout-static {
-        left: 0;
-        right: 0;
-        top: 0;
-        bottom: 0;
-    }
-}
-
-.molstar-layout-right {
-
-    .molstar-layout-static {
-        left: 0;
-        right: 0;
-        top: 0;
-        height: $row-height + $control-spacing;
-    }
-
-    .molstar-layout-scrollable {
-        left: 0;
-        right: 0;
-        top: $row-height + $control-spacing + 1;
-        bottom: 0;
-     }
-
-}
-
-.molstar-layout-left {
-    .molstar-layout-static {
-        left: 0;
-        right: 0;
-        bottom: 0;
-        top: 0;
-    }
-}

+ 0 - 81
src/mol-app/skin/layout/landscape.scss

@@ -1,81 +0,0 @@
-
-.molstar-layout-main {
-    position: absolute;
-    left: $expanded-left-width;
-    right: $expanded-right-width;
-    bottom: $expanded-bottom-height;
-    top: $expanded-top-height;
-}
-
-.molstar-layout-top {
-    position: absolute;
-    left: $expanded-left-width;
-    right: $expanded-right-width;
-    height: $expanded-top-height;
-    top: 0;
-    border-bottom: 1px solid $border-color;
-}
-
-.molstar-layout-bottom {
-    position: absolute;
-    left: $expanded-left-width;
-    right: $expanded-right-width;
-    height: $expanded-bottom-height;
-    bottom: 0;
-    border-top: 1px solid $border-color;
-}
-
-.molstar-layout-right {
-    position: absolute;
-    width: $expanded-right-width;
-    right: 0;
-    bottom: 0;
-    top: 0;
-    border-left: 1px solid $border-color;
-}
-
-.molstar-layout-left {
-    position: absolute;
-    width: $expanded-left-width;
-    left: 0;
-    bottom: 0;
-    top: 0;
-    border-right: 1px solid $border-color;
-}
-
-.molstar-layout-hide-right {
-    .molstar-layout-right {
-        display: none;
-    }
-    .molstar-layout-main, .molstar-layout-top, .molstar-layout-bottom {
-        right: 0;
-    }
-}
-
-
-.molstar-layout-hide-left {
-    .molstar-layout-left {
-        display: none;
-    }
-    .molstar-layout-main, .molstar-layout-top, .molstar-layout-bottom {
-        left: 0;
-    }
-}
-
-.molstar-layout-hide-bottom {
-    .molstar-layout-bottom {
-        display: none;
-    }
-    .molstar-layout-main {
-        bottom: 0;
-    }
-}
-
-.molstar-layout-hide-top {
-    .molstar-layout-top {
-        display: none;
-    }
-    .molstar-layout-main {
-        top: 0;
-    }
-}

+ 0 - 89
src/mol-app/skin/layout/outside.scss

@@ -1,89 +0,0 @@
-
-.molstar-layout-main {
-    position: absolute;
-    left: 0;
-    right: 0;
-    bottom: 0;
-    top: 0;
-}
-
-.molstar-layout-top {
-    position: absolute;
-    right: 0;
-    height: $standard-top-height;
-    top: -$standard-top-height;
-    width: 50%;
-    border-left: 1px solid $border-color;
-    border-bottom: 1px solid $border-color;
-}
-
-.molstar-layout-bottom {
-    position: absolute;
-    left: 0;
-    right: 0;
-    height: $standard-top-height;
-    top: -$standard-top-height;
-    width: 50%;
-    border-bottom: 1px solid $border-color;
-}
-
-.molstar-layout-right {
-    position: absolute;
-    width: 50%;
-    right: 0;
-    bottom: -$standard-bottom-height;
-    height: $standard-bottom-height;
-    border-left: 1px solid $border-color;
-    border-top: 1px solid $border-color;
-}
-
-.molstar-layout-left {
-    position: absolute;
-    width: 50%;
-    left: 0;
-    bottom: 0;
-    bottom: -$standard-bottom-height;
-    height: $standard-bottom-height;
-    border-top: 1px solid $border-color;
-}
-
-/////////////////////////////////////////
-.molstar-layout-hide-right {
-    .molstar-layout-right {
-        display: none;
-    }
-    .molstar-layout-left {
-        width: 100%;
-    }
-}
-
-.molstar-layout-hide-left {
-    .molstar-layout-left {
-        display: none;
-    }
-    .molstar-layout-right {
-        width: 100%;
-        border-left: none;
-    }
-}
-
-///////////////////////////////////
-.molstar-layout-hide-top {
-    .molstar-layout-top {
-        display: none;
-    }
-    .molstar-layout-bottom {
-        width: 100%;
-        border-left: none;
-    }
-}
-
-.molstar-layout-hide-bottom {
-    .molstar-layout-bottom {
-        display: none;
-    }
-    .molstar-layout-top {
-        width: 100%;
-        border-left: none;
-    }
-}

+ 0 - 99
src/mol-app/skin/layout/portrait.scss

@@ -1,99 +0,0 @@
-
-.molstar-layout-main {
-    position: absolute;
-    left: 0;
-    right: 0;
-    bottom: $expanded-portrait-bottom-height;
-    top: $expanded-portrait-top-height;
-}
-
-.molstar-layout-top {
-    position: absolute;
-    right: 0;
-    height: $expanded-portrait-top-height;
-    top: 0;
-    width: 50%;
-    border-left: 1px solid $border-color;
-    border-bottom: 1px solid $border-color;
-}
-
-.molstar-layout-bottom {
-    position: absolute;
-    left: 0;
-    right: 0;
-    height: $expanded-portrait-top-height;
-    width: 50%;
-    border-bottom: 1px solid $border-color;
-}
-
-.molstar-layout-right {
-    position: absolute;
-    width: 50%;
-    right: 0;
-    bottom: 0;
-    height: $expanded-portrait-bottom-height;
-    border-left: 1px solid $border-color;
-    border-top: 1px solid $border-color;
-}
-
-.molstar-layout-left {
-    position: absolute;
-    width: 50%;
-    left: 0;
-    bottom: 0;
-    height: $expanded-portrait-bottom-height;
-    border-top: 1px solid $border-color;
-}
-
-/////////////////////////////////////////
-.molstar-layout-hide-right {
-    .molstar-layout-right {
-        display: none;
-    }
-    .molstar-layout-left {
-        width: 100%;
-    }
-}
-
-.molstar-layout-hide-left {
-    .molstar-layout-left {
-        display: none;
-    }
-    .molstar-layout-right {
-        width: 100%;
-        border-left: none;
-    }
-}
-
-.molstar-layout-hide-right.molstar-layout-hide-left {
-    .molstar-layout-main {
-        bottom: 0;
-    }
-}
-
-///////////////////////////////////
-.molstar-layout-hide-top {
-    .molstar-layout-top {
-        display: none;
-    }
-    .molstar-layout-bottom {
-        width: 100%;
-        border-left: none;
-    }
-}
-
-.molstar-layout-hide-bottom {
-    .molstar-layout-bottom {
-        display: none;
-    }
-    .molstar-layout-top {
-        width: 100%;
-        border-left: none;
-    }
-}
-
-.molstar-layout-hide-top.molstar-layout-hide-bottom {
-    .molstar-layout-main {
-        top: 0;
-    }
-}

File diff suppressed because it is too large
+ 0 - 45
src/mol-app/skin/logo.scss


+ 0 - 2
src/mol-app/skin/molstar-blue.scss

@@ -1,2 +0,0 @@
-@import 'colors/blue';
-@import 'base';

+ 0 - 2
src/mol-app/skin/molstar-dark.scss

@@ -1,2 +0,0 @@
-@import 'colors/dark';
-@import 'base';

+ 0 - 2
src/mol-app/skin/molstar-light.scss

@@ -1,2 +0,0 @@
-@import 'colors/light';
-@import 'base';

+ 0 - 39
src/mol-app/skin/ui.scss

@@ -1,39 +0,0 @@
-@mixin non-selectable {
-    -webkit-user-select: none; /* Chrome/Safari */
-    -moz-user-select: none; /* Firefox */
-    -ms-user-select: none; /* IE10+ */
-    /* Rules below not implemented in browsers yet */
-    -o-user-select: none;
-    user-select: none;
-
-    cursor: default;
-}
-
-::-webkit-scrollbar {
-    width: 10px;
-    height:10px;
-}
-
-::-webkit-scrollbar-track {
-    //-webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.8);
-    border-radius: 0;
-    background-color: color-lower-contrast($control-background, 4%);
-}
-
-::-webkit-scrollbar-thumb {
-    border-radius: 0;
-    //-webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.9);
-    background-color: color-lower-contrast($control-background, 8%);
-}
-
-@import 'components/controls-base';
-@import 'components/controls';
-@import 'components/entity';
-@import 'components/help';
-@import 'components/jobs';
-@import 'components/log';
-@import 'components/misc';
-@import 'components/panel';
-@import 'components/slider';
-@import 'components/viewport';
-@import 'components/sequence-view';

+ 0 - 78
src/mol-app/skin/variables.scss

@@ -1,78 +0,0 @@
-
-// measures
-
-$control-label-width:   110px;
-$row-height:            32px;
-$control-spacing:       10px;
-$entity-subtree-offset: 8px;
-$info-vertical-padding: 6px;
-$slider-border-radius-base: 6px;
-
-// layout
-$expanded-top-height:    100px;
-$expanded-bottom-height: 3 * $row-height + 2;
-$expanded-right-width:   290px;
-$expanded-left-width:    290px;
-
-$expanded-portrait-bottom-height: 10 * ($row-height + 1) + 3 * $control-spacing + 1;
-$expanded-portrait-top-height:    2 * $row-height + 1;
-
-$standard-bottom-height: 8 * ($row-height + 1) + 3 * $control-spacing + 1;
-$standard-top-height:    2 * $row-height + 1;
-
-//////////////////////////////////////////////////
-// ENTITY COLORS
-
-
-// entity colors are "somewhat orthogonal" on the RGB cube
-// TypeClass = 'Root' | 'Group' | 'Data' | 'Object' | 'Visual' | 'Selection' | 'Action' | 'Behaviour'
-
-// DO NOT CHANGE THESE!!
-$entity-color-Root:      $default-background;
-$entity-color-Data:      color-lower-contrast(#95a5a6, 15%);
-$entity-color-Selection: color-lower-contrast(#e74c3c, 15%);
-$entity-color-Action:    color-lower-contrast(#34495e, 10%);
-$entity-color-Object:    color-lower-contrast(#2ecc71, 10%);
-$entity-color-Behaviour: color-lower-contrast(#9b59b6, 10%);
-$entity-color-Visual:    color-lower-contrast(#3498db, 5%);
-$entity-color-Group:     color-lower-contrast(#e67e22, 5%);
-
-//////////////////////////////////////////////////
-// COLORS and COMPUTED COLORS
-
-$slider-disabledColor: #ccc;
-
-$control-background: color-increase-contrast($default-background, 6.5%);
-$border-color: color-increase-contrast($default-background, 15%);
-$molstar-form-control-background: color-lower-contrast($default-background, 2.5%);
-
-// buttons
-$molstar-btn-link-font-color: $font-color;
-$molstar-btn-link-toggle-on-font-color: $font-color;
-$molstar-btn-link-toggle-off-font-color: color-lower-contrast($font-color, 33%);
-
-// used for "actions" -- i.e. + in selection
-$molstar-btn-remove-font-color: $font-color;
-
-$molstar-btn-action-background: $molstar-form-control-background;
-
-// update selection etc
-//!! $molstar-btn-commit-on-font-color: $entity-current-font-color;
-$molstar-btn-commit-on-hover-font-color: color-lower-contrast($molstar-btn-commit-on-font-color, 20%); //!!Change
-$molstar-btn-commit-on-background: color-lower-contrast($default-background, 2%);
-$molstar-btn-commit-off-background:  color-lower-contrast($default-background, 4%); //$control-background;
-$molstar-btn-commit-off-font-color: $font-color;
-
-// log
-$log-font-color: color-lower-contrast($font-color, 5%);
-$log-timestamp-font-color: color-lower-contrast($font-color, 20%);
-
-// highlight
-$highlight-info-font-color: $hover-font-color;
-$highlight-info-additional-font-color: color-lower-contrast($hover-font-color, 20%);
-
-// entity state
-$entity-color-fully-visible: $font-color;
-$entity-color-not-visible: color-lower-contrast($font-color, 66%);
-$entity-color-partialy-visible: color-lower-contrast($font-color, 33%);
-$entity-tag-color: color-lower-contrast($font-color, 20%);

+ 0 - 167
src/mol-app/ui/controls/common.tsx

@@ -1,167 +0,0 @@
-/*
- * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
- *
- * Adapted from LiteMol
- * Copyright (c) 2016 - now David Sehnal, licensed under Apache 2.0, See LICENSE file for more info.
- */
-
-import * as React from 'react'
-import { shallowEqual } from 'mol-util'
-
-export type ButtonSize = 'xs' | 'sm' | 'normal' | 'lg'
-
-export type ButtonStyle = 'link' | 'remove' | 'default'
-
-export abstract class Pure<Props> extends React.Component<Props, {}> {
-    shouldComponentUpdate(nextProps: any, nextState: any) {
-        return !shallowEqual(this.props, nextProps) || !shallowEqual(this.state, nextState);
-    }
-}
-
-export class Button extends Pure<{
-    onClick: (e: React.MouseEvent<HTMLButtonElement> | React.TouchEvent<HTMLButtonElement>) => void,
-    size?: ButtonSize,
-    style?: ButtonStyle,
-    active?: boolean,
-    activeStyle?: ButtonStyle,
-    icon?: string,
-    activeIcon?: string,
-    disabled?: boolean,
-    disabledStyle?: ButtonStyle,
-    asBlock?: boolean,
-    title?: string,
-    customClass?: string,
-    customStyle?: any
-}> {
-    render() {
-
-        let props = this.props;
-
-        let className = 'molstar-btn';
-        if (props.size && props.size !== 'normal') className += ' molstar-btn-' + props.size;
-        if (props.asBlock) className += ' molstar-btn-block';
-
-        if (props.disabled) className += ' molstar-btn-' + (props.disabledStyle || props.style || 'default');
-        else if (props.active) className += ' molstar-btn-' + (props.activeStyle || props.style || 'default');
-        else className += ' molstar-btn-' + (props.style || 'default');
-
-        if (props.customClass) className += ' ' + props.customClass;
-
-        let icon: any = void 0;
-
-        if (props.icon) {
-            if (props.active && props.activeIcon) icon = <span className={ `molstar-icon molstar-icon-${props.activeIcon}` }></span>
-            else icon = <span className={ `molstar-icon molstar-icon-${props.icon}` }></span>
-        }
-        //onTouchEnd={(e) => { (e.target as HTMLElement).blur() } }
-
-        return <button
-            title={props.title}
-            className={className}
-            style={props.customStyle}
-            disabled={props.disabled}
-            onClick={(e) => { props.onClick.call(null, e); (e.target as HTMLElement).blur() } }
-                >
-            {icon}{props.children}
-        </button>
-    }
-}
-
-export const TextBox = (props: {
-    onChange: (v: string) => void,
-    value?: string,
-    defaultValue?: string,
-    onKeyPress?: (e: React.KeyboardEvent<HTMLInputElement>) => void,
-    onBlur?: (e: React.FormEvent<HTMLInputElement>) => void,
-    placeholder?: string
-}) => <input type='text' className='molstar-form-control' placeholder={props.placeholder} value={props.value} defaultValue={props.defaultValue}
-        onBlur={e => { if (props.onBlur) props.onBlur.call(null, e) } }
-        onChange={e => props.onChange.call(null, (e.target as HTMLInputElement).value)} onKeyPress={props.onKeyPress} />;
-
-export function isEnter(e: React.KeyboardEvent<HTMLInputElement>) {
-    if ((e.keyCode === 13 || e.charCode === 13)) {
-        return true;
-    }
-    return false;
-}
-
-export function TextBoxGroup(props: {
-    value: string,
-    onChange: (v: string) => void,
-    placeholder?: string,
-    label: string,
-    onEnter?: (e: React.KeyboardEvent<HTMLInputElement>) => void
-    title?: string
-}) {
-    return <div className='molstar-control-row molstar-options-group' title={props.title}>
-        <span>{props.label}</span>
-        <div>
-            <TextBox placeholder={props.placeholder} onChange={props.onChange} value={props.value} onKeyPress={(e) => {
-                if (isEnter(e) && props.onEnter) props.onEnter.call(null, e)
-            } }  />
-        </div>
-    </div>;
-}
-
-export const CommitButton = (props: {
-    action: () => void,
-    isOn: boolean,
-    on: string,
-    off?: string,
-    title?: string
-}) => <div style={{ marginTop: '1px' }}><button onClick={e => { props.action(); (e.target as HTMLElement).blur(); }}
-        className={'molstar-btn molstar-btn-block molstar-btn-commit molstar-btn-commit-' + (props.isOn ? 'on' : 'off')}
-        disabled={!props.isOn} title={props.title}>
-        <span className={ `molstar-icon molstar-icon-${props.isOn ? 'ok' : 'cross'}` }></span>
-        {props.isOn ? <b>{props.on}</b> : (props.off ? props.off : props.on) }
-    </button></div> ;
-
-export const Toggle = (props: {
-    onChange: (v: boolean) => void,
-    value: boolean,
-    label: string,
-    title?: string
-}) => <div className='molstar-control-row molstar-toggle-button' title={props.title}>
-        <span>{props.label}</span>
-        <div>
-            <button onClick={e => { props.onChange.call(null, !props.value); (e.target as HTMLElement).blur(); }}>
-                    <span className={ `molstar-icon molstar-icon-${props.value ? 'ok' : 'off'}` }></span> {props.value ? 'On' : 'Off'}
-            </button>
-        </div>
-    </div>
-
-export const ControlGroupExpander = (props: { onChange: (e: boolean) => void, isExpanded: boolean }) =>
-        <Button style='link' title={`${props.isExpanded ? 'Less' : 'More'} options`} onClick={() => props.onChange.call(null, !props.isExpanded) }
-                            icon={props.isExpanded ? 'minus' : 'plus'} customClass='molstar-conrol-group-expander' />
-
-
-export const RowText = (props: {
-    value: any,
-    label: string,
-    title?: string
-}) => <div className='molstar-control-row molstar-row-text' title={props.title}>
-        <span>{props.label}</span>
-        <div>
-            {props.value}
-        </div>
-    </div>
-
-export const HelpBox = (props: {
-    title: string,
-    content: JSX.Element | string
-}) => <div className='molstar-help-row'>
-        <span>{props.title}</span>
-        <div>{props.content}</div>
-    </div>
-
-export function FileInput (props: {
-    accept: string
-    onChange: (v: FileList | null) => void,
-}) {
-    return <input
-        accept={props.accept || '*.*'}
-        type='file'
-        className='molstar-form-control'
-        onChange={e => props.onChange.call(null, e.target.files)}
-    />
-}

+ 0 - 824
src/mol-app/ui/controls/slider.tsx

@@ -1,824 +0,0 @@
-/*
- * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
- *
- * Adapted from LiteMol
- * Copyright (c) 2016 - now David Sehnal, licensed under Apache 2.0, See LICENSE file for more info.
- */
-
-import * as React from 'react'
-import { TextBox, isEnter } from './common'
-
-export class Slider extends React.Component<{
-    label: any,
-    min: number,
-    max: number,
-    value: number,
-    step?: number,
-    title?: string,
-    callOnChangeWhileSliding?: boolean,
-    onChange: (v: number) => void
-}, { value: string }> {
-
-    state = { value: '0' }
-
-    private firedValue = NaN;
-
-    componentWillMount() {
-        this.setState({ value: '' + this.props.value });
-    }
-
-    componentWillReceiveProps(nextProps: any) {
-        this.setState({ value: '' + nextProps.value });
-    }
-
-    private updateValue(s: string) {
-        let v = +s;
-        if (v < this.props.min) { v = this.props.min; s = '' + v; }
-        else if (v > this.props.max) { v = this.props.max; s = '' + v; }
-        this.setState({ value: s })
-    }
-
-    private fire() {
-        let v = +this.state.value;
-        if (isNaN(v)) { v = this.props.value; }
-        if (v !== this.props.value) {
-            if (this.firedValue !== v) {
-                this.firedValue = v;
-                this.props.onChange.call(null, v);
-            }
-        }
-    }
-
-    render() {
-        let step = this.props.step;
-        if (step === void 0) step = 1;
-        return <div className='molstar-control-row molstar-slider' title={this.props.title}>
-            <span>{this.props.label}</span>
-            <div>
-                <div>
-                    <div>
-                        <SliderBase min={this.props.min} max={this.props.max} step={step} value={+this.state.value}
-                            onChange={v => {
-                                this.setState({ value: '' + v });
-                                if (this.props.callOnChangeWhileSliding) this.fire();
-                            }}
-                            onAfterChange={v => this.fire()} />
-                    </div>
-                </div>
-                <div>
-                    <TextBox value={this.state.value}  onChange={v => this.updateValue(v)} onBlur={() => this.fire()} onKeyPress={e => {
-                        if (isEnter(e)) this.fire();
-                    } } />
-                </div>
-            </div>
-        </div>;
-    }
-}
-
-/**
- * The following code was adapted from react-components/slider library.
- *
- * The MIT License (MIT)
- * Copyright (c) 2015-present Alipay.com, https://www.alipay.com/
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
-
-    * The above copyright notice and this permission notice shall be included in
-    * all copies or substantial portions of the Software.
-
-    * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-    * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-    * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-    * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-    * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-    * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-    * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-    */
-
-function classNames(_classes: { [name: string]: boolean | number }) {
-    let classes = [];
-    let hasOwn = {}.hasOwnProperty;
-
-    for (let i = 0; i < arguments.length; i++) {
-        let arg = arguments[i];
-        if (!arg) continue;
-
-        let argType = typeof arg;
-
-        if (argType === 'string' || argType === 'number') {
-            classes.push(arg);
-        } else if (Array.isArray(arg)) {
-            classes.push(classNames.apply(null, arg));
-        } else if (argType === 'object') {
-            for (let key in arg) {
-                if (hasOwn.call(arg, key) && arg[key]) {
-                    classes.push(key);
-                }
-            }
-        }
-    }
-
-    return classes.join(' ');
-}
-
-function noop() {
-}
-
-function isNotTouchEvent(e: TouchEvent) {
-    return e.touches.length > 1 || (e.type.toLowerCase() === 'touchend' && e.touches.length > 0);
-}
-
-function getTouchPosition(vertical: boolean, e: TouchEvent) {
-    return vertical ? e.touches[0].clientY : e.touches[0].pageX;
-}
-
-function getMousePosition(vertical: boolean, e: MouseEvent) {
-    return vertical ? e.clientY : e.pageX;
-}
-
-function getHandleCenterPosition(vertical: boolean, handle: HTMLElement) {
-    const coords = handle.getBoundingClientRect();
-    return vertical ?
-        coords.top + (coords.height * 0.5) :
-        coords.left + (coords.width * 0.5);
-}
-
-function pauseEvent(e: Event) {
-    e.stopPropagation();
-    e.preventDefault();
-}
-
-export class Handle extends React.Component<Partial<HandleProps>, {}> {
-    render() {
-        const {
-            className,
-            tipFormatter,
-            vertical,
-            offset,
-            value,
-            index,
-        } = this.props as HandleProps;
-
-        const style = vertical ? { bottom: `${offset}%` } : { left: `${offset}%` };
-        return (
-            <div className={className} style={style} title={tipFormatter(value, index)}
-                />
-        );
-    }
-}
-
-export interface SliderBaseProps {
-    min: number,
-    max: number,
-    step?: number,
-    defaultValue?: number | number[],
-    value?: number | number[],
-    marks?: any,
-    included?: boolean,
-    className?: string,
-    prefixCls?: string,
-    disabled?: boolean,
-    children?: any,
-    onBeforeChange?: (value: number | number[]) => void,
-    onChange?: (value: number | number[]) => void,
-    onAfterChange?: (value: number | number[]) => void,
-    handle?: JSX.Element,
-    tipFormatter?: (value: number, index: number) => any,
-    dots?: boolean,
-    range?: boolean | number,
-    vertical?: boolean,
-    allowCross?: boolean,
-    pushable?: boolean | number,
-}
-
-export interface SliderBaseState {
-    handle: number | null,
-    recent: number,
-    bounds: number[]
-}
-
-export class SliderBase extends React.Component<SliderBaseProps, SliderBaseState> {
-    private sliderElement: HTMLElement | undefined = void 0;
-    private handleElements: (HTMLElement | undefined)[] = [];
-
-    state: SliderBaseState = {
-        handle: null,
-        recent: 0,
-        bounds: [0, 0],
-    };
-
-    constructor(props: SliderBaseProps) {
-        super(props);
-
-        const { range, min, max } = props;
-        const initialValue = range ? Array.apply(null, Array(+range + 1)).map(() => min) : min;
-        const defaultValue = ('defaultValue' in props ? props.defaultValue : initialValue);
-        const value = (props.value !== undefined ? props.value : defaultValue);
-
-        const bounds = (range ? value : [min, value]).map((v: number) => this.trimAlignValue(v));
-
-        let recent;
-        if (range && bounds[0] === bounds[bounds.length - 1] && bounds[0] === max) {
-            recent = 0;
-        } else {
-            recent = bounds.length - 1;
-        }
-
-        this.state = {
-            handle: null,
-            recent,
-            bounds,
-        };
-    }
-
-    public static defaultProps: SliderBaseProps = {
-        prefixCls: 'molstar-slider-base',
-        className: '',
-        min: 0,
-        max: 100,
-        step: 1,
-        marks: {},
-        handle: <Handle className='' vertical={false} offset={0} tipFormatter={v => v} value={0} index={0} />,
-        onBeforeChange: noop,
-        onChange: noop,
-        onAfterChange: noop,
-        tipFormatter: (value, index) => value,
-        included: true,
-        disabled: false,
-        dots: false,
-        range: false,
-        vertical: false,
-        allowCross: true,
-        pushable: false,
-    };
-
-    private dragOffset = 0;
-    private startPosition = 0;
-    private startValue = 0;
-    private _getPointsCache: any = void 0;
-
-    componentWillReceiveProps(nextProps: SliderBaseProps) {
-        if (!('value' in nextProps || 'min' in nextProps || 'max' in nextProps)) return;
-
-        const { bounds } = this.state;
-        if (nextProps.range) {
-            const value = nextProps.value || bounds;
-            const nextBounds = (value as number[]).map((v: number) => this.trimAlignValue(v, nextProps));
-            if (nextBounds.every((v: number, i: number) => v === bounds[i])) return;
-
-            this.setState({ bounds: nextBounds } as SliderBaseState);
-            if (bounds.some(v => this.isValueOutOfBounds(v, nextProps))) {
-                this.props.onChange!(nextBounds);
-            }
-        } else {
-            const value = nextProps.value !== undefined ? nextProps.value : bounds[1];
-            const nextValue = this.trimAlignValue(value as number, nextProps);
-            if (nextValue === bounds[1] && bounds[0] === nextProps.min) return;
-
-            this.setState({ bounds: [nextProps.min, nextValue] } as SliderBaseState);
-            if (this.isValueOutOfBounds(bounds[1], nextProps)) {
-                this.props.onChange!(nextValue);
-            }
-        }
-    }
-
-    onChange(state: this['state']) {
-        const props = this.props;
-        const isNotControlled = !('value' in props);
-        if (isNotControlled) {
-            this.setState(state);
-        } else if (state.handle !== undefined) {
-            this.setState({ handle: state.handle } as SliderBaseState);
-        }
-
-        const data = { ...this.state, ...(state as any) };
-        const changedValue = props.range ? data.bounds : data.bounds[1];
-        props.onChange!(changedValue);
-    }
-
-    onMouseDown(e: MouseEvent) {
-        if (e.button !== 0) { return; }
-
-        let position = getMousePosition(this.props.vertical!, e);
-        if (!this.isEventFromHandle(e)) {
-            this.dragOffset = 0;
-        } else {
-            const handlePosition = getHandleCenterPosition(this.props.vertical!, e.target as HTMLElement);
-            this.dragOffset = position - handlePosition;
-            position = handlePosition;
-        }
-        this.onStart(position);
-        this.addDocumentEvents('mouse');
-        pauseEvent(e);
-    }
-
-    onMouseMove(e: MouseEvent) {
-        const position = getMousePosition(this.props.vertical!, e);
-        this.onMove(e, position - this.dragOffset);
-    }
-
-    onMove(e: MouseEvent | TouchEvent, position: number) {
-        pauseEvent(e);
-        const props = this.props;
-        const state = this.state;
-
-        let diffPosition = position - this.startPosition;
-        diffPosition = this.props.vertical ? -diffPosition : diffPosition;
-        const diffValue = diffPosition / this.getSliderLength() * (props.max - props.min);
-
-        const value = this.trimAlignValue(this.startValue + diffValue);
-        const oldValue = state.bounds[state.handle!];
-        if (value === oldValue) return;
-
-        const nextBounds = [...state.bounds];
-        nextBounds[state.handle!] = value;
-        let nextHandle = state.handle!;
-        if (props.pushable !== false) {
-            const originalValue = state.bounds[nextHandle];
-            this.pushSurroundingHandles(nextBounds, nextHandle, originalValue);
-        } else if (props.allowCross) {
-            nextBounds.sort((a, b) => a - b);
-            nextHandle = nextBounds.indexOf(value);
-        }
-        this.onChange({
-            handle: nextHandle,
-            bounds: nextBounds,
-        } as SliderBaseState);
-    }
-
-    onStart(position: number) {
-        const props = this.props;
-        props.onBeforeChange!(this.getValue());
-
-        const value = this.calcValueByPos(position);
-        this.startValue = value;
-        this.startPosition = position;
-
-        const state = this.state;
-        const { bounds } = state;
-
-        let valueNeedChanging = 1;
-        if (this.props.range) {
-            let closestBound = 0;
-            for (let i = 1; i < bounds.length - 1; ++i) {
-                if (value > bounds[i]) { closestBound = i; }
-            }
-            if (Math.abs(bounds[closestBound + 1] - value) < Math.abs(bounds[closestBound] - value)) {
-                closestBound = closestBound + 1;
-            }
-            valueNeedChanging = closestBound;
-
-            const isAtTheSamePoint = (bounds[closestBound + 1] === bounds[closestBound]);
-            if (isAtTheSamePoint) {
-                valueNeedChanging = state.recent;
-            }
-
-            if (isAtTheSamePoint && (value !== bounds[closestBound + 1])) {
-                valueNeedChanging = value < bounds[closestBound + 1] ? closestBound : closestBound + 1;
-            }
-        }
-
-        this.setState({
-            handle: valueNeedChanging,
-            recent: valueNeedChanging,
-        } as SliderBaseState);
-
-        const oldValue = state.bounds[valueNeedChanging];
-        if (value === oldValue) return;
-
-        const nextBounds = [...state.bounds];
-        nextBounds[valueNeedChanging] = value;
-        this.onChange({ bounds: nextBounds } as SliderBaseState);
-    }
-
-    onTouchMove(e: TouchEvent) {
-        if (isNotTouchEvent(e)) {
-            this.end('touch');
-            return;
-        }
-
-        const position = getTouchPosition(this.props.vertical!, e);
-        this.onMove(e, position - this.dragOffset);
-    }
-
-    onTouchStart(e: TouchEvent) {
-        if (isNotTouchEvent(e)) return;
-
-        let position = getTouchPosition(this.props.vertical!, e);
-        if (!this.isEventFromHandle(e)) {
-            this.dragOffset = 0;
-        } else {
-            const handlePosition = getHandleCenterPosition(this.props.vertical!, e.target as HTMLElement);
-            this.dragOffset = position - handlePosition;
-            position = handlePosition;
-        }
-        this.onStart(position);
-        this.addDocumentEvents('touch');
-        pauseEvent(e);
-    }
-
-    /**
-     * Returns an array of possible slider points, taking into account both
-     * `marks` and `step`. The result is cached.
-     */
-    getPoints() {
-        const { marks, step, min, max } = this.props;
-        const cache = this._getPointsCache;
-        if (!cache || cache.marks !== marks || cache.step !== step) {
-            const pointsObject = { ...marks };
-            if (step !== null) {
-                for (let point = min; point <= max; point += step!) {
-                    pointsObject[point] = point;
-                }
-            }
-            const points = Object.keys(pointsObject).map(parseFloat);
-            points.sort((a, b) => a - b);
-            this._getPointsCache = { marks, step, points };
-        }
-        return this._getPointsCache.points;
-    }
-
-    getPrecision(step: number) {
-        const stepString = step.toString();
-        let precision = 0;
-        if (stepString.indexOf('.') >= 0) {
-            precision = stepString.length - stepString.indexOf('.') - 1;
-        }
-        return precision;
-    }
-
-    getSliderLength() {
-        const slider = this.sliderElement;
-        if (!slider) {
-            return 0;
-        }
-
-        return this.props.vertical ? slider.clientHeight : slider.clientWidth;
-    }
-
-    getSliderStart() {
-        const slider = this.sliderElement as HTMLElement;
-        const rect = slider.getBoundingClientRect();
-
-        return this.props.vertical ? rect.top : rect.left;
-    }
-
-    getValue(): number {
-        const { bounds } = this.state;
-        return (this.props.range ? bounds : bounds[1]) as number;
-    }
-
-    private eventHandlers = {
-        'touchmove': (e: TouchEvent) => this.onTouchMove(e),
-        'touchend': (e: TouchEvent) => this.end('touch'),
-        'mousemove': (e: MouseEvent) => this.onMouseMove(e),
-        'mouseup': (e: MouseEvent) => this.end('mouse'),
-    }
-
-    addDocumentEvents(type: 'touch' | 'mouse') {
-        if (type === 'touch') {
-            document.addEventListener('touchmove', this.eventHandlers.touchmove);
-            document.addEventListener('touchend', this.eventHandlers.touchend);
-        } else if (type === 'mouse') {
-            document.addEventListener('mousemove', this.eventHandlers.mousemove);
-            document.addEventListener('mouseup', this.eventHandlers.mouseup);
-        }
-    }
-
-    calcOffset(value: number) {
-        const { min, max } = this.props;
-        const ratio = (value - min) / (max - min);
-        return ratio * 100;
-    }
-
-    calcValue(offset: number) {
-        const { vertical, min, max } = this.props;
-        const ratio = Math.abs(offset / this.getSliderLength());
-        const value = vertical ? (1 - ratio) * (max - min) + min : ratio * (max - min) + min;
-        return value;
-    }
-
-    calcValueByPos(position: number) {
-        const pixelOffset = position - this.getSliderStart();
-        const nextValue = this.trimAlignValue(this.calcValue(pixelOffset));
-        return nextValue;
-    }
-
-    end(type: 'mouse' | 'touch') {
-        this.removeEvents(type);
-        this.props.onAfterChange!(this.getValue());
-        this.setState({ handle: null } as SliderBaseState);
-    }
-
-    isEventFromHandle(e: Event) {
-        for (const h of this.handleElements) {
-            if (h === e.target) return true;
-        }
-        return false;
-
-        // return this.state.bounds.some((x, i) => e.target
-
-        // (
-        //     //this.handleElements[i] && e.target === ReactDOM.findDOMNode(this.handleElements[i])
-        // ));
-    }
-
-    isValueOutOfBounds(value: number, props: SliderBaseProps) {
-        return value < props.min || value > props.max;
-    }
-
-    pushHandle(bounds: number[], handle: number, direction: number, amount: number) {
-        const originalValue = bounds[handle];
-        let currentValue = bounds[handle];
-        while (direction * (currentValue - originalValue) < amount) {
-            if (!this.pushHandleOnePoint(bounds, handle, direction)) {
-                // can't push handle enough to create the needed `amount` gap, so we
-                // revert its position to the original value
-                bounds[handle] = originalValue;
-                return false;
-            }
-            currentValue = bounds[handle];
-        }
-        // the handle was pushed enough to create the needed `amount` gap
-        return true;
-    }
-
-    pushHandleOnePoint(bounds: number[], handle: number, direction: number) {
-        const points = this.getPoints();
-        const pointIndex = points.indexOf(bounds[handle]);
-        const nextPointIndex = pointIndex + direction;
-        if (nextPointIndex >= points.length || nextPointIndex < 0) {
-            // reached the minimum or maximum available point, can't push anymore
-            return false;
-        }
-        const nextHandle = handle + direction;
-        const nextValue = points[nextPointIndex];
-        const { pushable: threshold } = this.props;
-        const diffToNext = direction * (bounds[nextHandle] - nextValue);
-        if (!this.pushHandle(bounds, nextHandle, direction, +threshold! - diffToNext)) {
-            // couldn't push next handle, so we won't push this one either
-            return false;
-        }
-        // push the handle
-        bounds[handle] = nextValue;
-        return true;
-    }
-
-    pushSurroundingHandles(bounds: number[], handle: number, originalValue: number) {
-        const { pushable: threshold } = this.props;
-        const value = bounds[handle];
-
-        let direction = 0;
-        if (bounds[handle + 1] - value < threshold!) {
-            direction = +1;
-        } else if (value - bounds[handle - 1] < threshold!) {
-            direction = -1;
-        }
-
-        if (direction === 0) { return; }
-
-        const nextHandle = handle + direction;
-        const diffToNext = direction * (bounds[nextHandle] - value);
-        if (!this.pushHandle(bounds, nextHandle, direction, +threshold! - diffToNext)) {
-            // revert to original value if pushing is impossible
-            bounds[handle] = originalValue;
-        }
-    }
-
-    removeEvents(type: 'touch' | 'mouse') {
-        if (type === 'touch') {
-            document.removeEventListener('touchmove', this.eventHandlers.touchmove);
-            document.removeEventListener('touchend', this.eventHandlers.touchend);
-        } else if (type === 'mouse') {
-            document.removeEventListener('mousemove', this.eventHandlers.mousemove);
-            document.removeEventListener('mouseup', this.eventHandlers.mouseup);
-        }
-    }
-
-    trimAlignValue(v: number, nextProps?: SliderBaseProps) {
-        const { handle, bounds } = (this.state || {}) as this['state'];
-        const { marks, step, min, max, allowCross } = { ...this.props, ...(nextProps || {}) } as SliderBaseProps;
-
-        let val = v;
-        if (val <= min) {
-            val = min;
-        }
-        if (val >= max) {
-            val = max;
-        }
-        /* eslint-disable eqeqeq */
-        if (!allowCross && handle != null && handle > 0 && val <= bounds[handle - 1]) {
-            val = bounds[handle - 1];
-        }
-        if (!allowCross && handle != null && handle < bounds.length - 1 && val >= bounds[handle + 1]) {
-            val = bounds[handle + 1];
-        }
-        /* eslint-enable eqeqeq */
-
-        const points = Object.keys(marks).map(parseFloat);
-        if (step !== null) {
-            const closestStep = (Math.round((val - min) / step!) * step!) + min;
-            points.push(closestStep);
-        }
-
-        const diffs = points.map((point) => Math.abs(val - point));
-        const closestPoint = points[diffs.indexOf(Math.min.apply(Math, diffs))];
-
-        return step !== null ? parseFloat(closestPoint.toFixed(this.getPrecision(step!))) : closestPoint;
-    }
-
-    render() {
-        const {
-            handle,
-            bounds,
-        } = this.state;
-        const {
-            className,
-            prefixCls,
-            disabled,
-            vertical,
-            dots,
-            included,
-            range,
-            step,
-            marks,
-            max, min,
-            tipFormatter,
-            children,
-        } = this.props;
-
-        const customHandle = this.props.handle;
-
-        const offsets = bounds.map(v => this.calcOffset(v));
-
-        const handleClassName = `${prefixCls}-handle`;
-
-        const handlesClassNames = bounds.map((v, i) => classNames({
-            [handleClassName]: true,
-            [`${handleClassName}-${i + 1}`]: true,
-            [`${handleClassName}-lower`]: i === 0,
-            [`${handleClassName}-upper`]: i === bounds.length - 1,
-        }));
-
-        const isNoTip = (step === null) || (tipFormatter === null);
-
-        const commonHandleProps = {
-            prefixCls,
-            noTip: isNoTip,
-            tipFormatter,
-            vertical,
-        };
-
-        this.handleElements = [];
-        const handles = bounds.map((v, i) => React.cloneElement(customHandle!, {
-            ...commonHandleProps,
-            className: handlesClassNames[i],
-            value: v,
-            offset: offsets[i],
-            dragging: handle === i,
-            index: i,
-            key: i,
-            ref: (h: any) => this.handleElements.push(h)  //`handle-${i}`,
-        }));
-        if (!range) { handles.shift(); }
-
-        const isIncluded = included || range;
-
-        const tracks: JSX.Element[] = [];
-        // for (let i = 1; i < bounds.length; ++i) {
-        //     const trackClassName = classNames({
-        //         [`${prefixCls}-track`]: true,
-        //         [`${prefixCls}-track-${i}`]: true,
-        //     });
-        //     tracks.push(
-        //         <Track className={trackClassName} vertical={vertical} included={isIncluded}
-        //             offset={offsets[i - 1]} length={offsets[i] - offsets[i - 1]} key={i}
-        //             />
-        //     );
-        // }
-
-        const sliderClassName = classNames({
-            [prefixCls!]: true,
-            [`${prefixCls}-with-marks`]: Object.keys(marks).length,
-            [`${prefixCls}-disabled`]: disabled!,
-            [`${prefixCls}-vertical`]: this.props.vertical!,
-            [className!]: !!className,
-        });
-
-        return (
-            <div ref={e => this.sliderElement = e!} className={sliderClassName}
-                onTouchStart={disabled ? noop : this.onTouchStart.bind(this)}
-                onMouseDown={disabled ? noop : this.onMouseDown.bind(this)}
-                >
-                <div className={`${prefixCls}-rail`} />
-                {tracks}
-                <Steps prefixCls={prefixCls} vertical={vertical} marks={marks} dots={dots} step={step}
-                    included={isIncluded} lowerBound={bounds[0]}
-                    upperBound={bounds[bounds.length - 1]} max={max} min={min}
-                    />
-                {handles}
-                <Marks className={`${prefixCls}-mark`} vertical={vertical!} marks={marks}
-                    included={isIncluded!} lowerBound={bounds[0]}
-                    upperBound={bounds[bounds.length - 1]} max={max} min={min}
-                    />
-                {children}
-            </div>
-        );
-    }
-}
-
-export interface HandleProps {
-    className: string,
-    vertical: boolean,
-    offset: number,
-    tipFormatter: (v: number, index: number) => any,
-    value: number,
-    index: number,
-}
-
-interface MarksProps {
-    className: string,
-    vertical: boolean,
-    marks: any,
-    included: boolean | number,
-    upperBound: number,
-    lowerBound: number,
-    max: number,
-    min: number
-}
-const Marks = ({ className, vertical, marks, included, upperBound, lowerBound, max, min }: MarksProps) => {
-    const marksKeys = Object.keys(marks);
-    const marksCount = marksKeys.length;
-    const unit = 100 / (marksCount - 1);
-    const markWidth = unit * 0.9;
-
-    const range = max - min;
-    const elements = marksKeys.map(parseFloat).sort((a, b) => a - b).map((point) => {
-        const isActived = (!included && point === upperBound) ||
-            (included && point <= upperBound && point >= lowerBound);
-        const markClassName = classNames({
-            [`${className}-text`]: true,
-            [`${className}-text-active`]: isActived,
-        });
-
-        const bottomStyle = {
-            // height: markWidth + '%',
-            marginBottom: '-50%',
-            bottom: `${(point - min) / range * 100}%`,
-        };
-
-        const leftStyle = {
-            width: `${markWidth}%`,
-            marginLeft: `${-markWidth / 2}%`,
-            left: `${(point - min) / range * 100}%`,
-        };
-
-        const style = vertical ? bottomStyle : leftStyle;
-
-        const markPoint = marks[point];
-        const markPointIsObject = typeof markPoint === 'object' && !React.isValidElement(markPoint);
-        const markLabel = markPointIsObject ? markPoint.label : markPoint;
-        const markStyle = markPointIsObject ? { ...style, ...markPoint.style } : style;
-        return (<span className={markClassName} style={markStyle} key={point}>
-            {markLabel}
-        </span>);
-    });
-
-    return <div className={className}>{elements}</div>;
-};
-
-function calcPoints(vertical: boolean, marks: any, dots: boolean, step: number, min: number, max: number) {
-    const points = Object.keys(marks).map(parseFloat);
-    if (dots) {
-        for (let i = min; i <= max; i = i + step) {
-            if (points.indexOf(i) >= 0) continue;
-            points.push(i);
-        }
-    }
-    return points;
-}
-
-const Steps = ({ prefixCls, vertical, marks, dots, step, included,
-    lowerBound, upperBound, max, min }: any) => {
-    const range = max - min;
-    const elements = calcPoints(vertical, marks, dots, step, min, max).map((point) => {
-        const offset = `${Math.abs(point - min) / range * 100}%`;
-        const style = vertical ? { bottom: offset } : { left: offset };
-
-        const isActived = (!included && point === upperBound) ||
-            (included && point <= upperBound && point >= lowerBound);
-        const pointClassName = classNames({
-            [`${prefixCls}-dot`]: true,
-            [`${prefixCls}-dot-active`]: isActived,
-        });
-
-        return <span className={pointClassName} style={style} key={point} />;
-    });
-
-    return <div className={`${prefixCls}-step`}>{elements}</div>;
-};

+ 0 - 113
src/mol-app/ui/entity/tree.tsx

@@ -1,113 +0,0 @@
-/**
- * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
- *
- * Adapted from LiteMol
- * Copyright (c) 2016 - now David Sehnal, licensed under Apache 2.0, See LICENSE file for more info.
- *
- * @author Alexander Rose <alexander.rose@weirdbyte.de>
- */
-
-import * as React from 'react'
-
-import { View } from '../view';
-import { EntityTreeController } from '../../controller/entity/tree';
-import { Controller } from '../../controller/controller';
-import { AnyEntity, RootEntity } from 'mol-view/state/entity';
-import { AnyTransform, SpacefillUpdate, UrlToData, DataToCif, FileToData, CifToMmcif, MmcifToModel, ModelToStructure, StructureToSpacefill, MmcifFileToSpacefill, StructureCenter, StructureToBallAndStick, DistanceRestraintUpdate, CartoonUpdate, BallAndStickUpdate, BackboneUpdate, MmcifUrlToSpacefill, CarbohydrateUpdate } from 'mol-view/state/transform';
-
-function getTransforms(entity: AnyEntity): AnyTransform[] {
-    const transforms: AnyTransform[] = []
-    switch (entity.kind) {
-        case 'root':
-            transforms.push(MmcifFileToSpacefill, MmcifUrlToSpacefill)
-            break;
-        case 'url':
-            transforms.push(UrlToData)
-            break;
-        case 'file':
-            transforms.push(FileToData)
-            break;
-        case 'data':
-            transforms.push(DataToCif)
-            break;
-        case 'cif':
-            transforms.push(CifToMmcif)
-            break;
-        case 'mmcif':
-            transforms.push(MmcifToModel)
-            break;
-        case 'model':
-            transforms.push(ModelToStructure)
-            break;
-        case 'structure':
-            transforms.push(StructureToSpacefill, StructureToBallAndStick, StructureCenter)
-            break;
-        case 'spacefill':
-            transforms.push(SpacefillUpdate)
-            break;
-        case 'ballandstick':
-            transforms.push(BallAndStickUpdate)
-            break;
-        case 'distancerestraint':
-            transforms.push(DistanceRestraintUpdate)
-            break;
-        case 'backbone':
-            transforms.push(BackboneUpdate)
-            break;
-        case 'cartoon':
-            transforms.push(CartoonUpdate)
-            break;
-        case 'carbohydrate':
-            transforms.push(CarbohydrateUpdate)
-            break;
-    }
-    return transforms
-}
-
-export class Entity extends View<Controller<any>, {}, { entity: AnyEntity}> {
-    render() {
-        const entity = this.props.entity
-
-        return <div className='molstar-entity-tree-entry'>
-            <div className='molstar-entity-tree-entry-body'>
-                <div className='molstar-entity-tree-entry-label-wrap'>
-                    <button
-                        className='molstar-entity-tree-entry-label'
-                        onClick={() => {
-                            console.log(entity)
-                            this.controller.context.currentEntity.next(entity)
-                            this.controller.context.currentTransforms.next(getTransforms(entity))
-                        }}
-                    >
-                        <span>{entity.id} - {entity.kind}</span>
-                    </button>
-                </div>
-            </div>
-        </div>;
-    }
-}
-
-export class EntityTree extends View<EntityTreeController, {}, {}> {
-    render() {
-        const entities: JSX.Element[] = []
-        const state = this.controller.state.getValue()
-        if (state) {
-            state.entities.forEach(e => {
-                entities.push(
-                    <div key={e.id}>
-                        <Entity controller={this.controller} entity={e}></Entity>
-                    </div>
-                )
-            })
-        }
-
-        return <div className='molstar-entity-tree'>
-            <div className='molstar-entity-tree-root'>
-                <Entity controller={this.controller} entity={RootEntity}></Entity>
-            </div>
-            <div className='molstar-entity-tree-children'>
-                <div>{entities}</div>
-            </div>
-        </div>;
-    }
-}

+ 0 - 89
src/mol-app/ui/layout.tsx

@@ -1,89 +0,0 @@
-/**
- * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
- *
- * Adapted from LiteMol
- * Copyright (c) 2016 - now David Sehnal, licensed under Apache 2.0, See LICENSE file for more info.
- */
-
-import * as React from 'react'
-import { LayoutController, LayoutTarget, LayoutRegion, CollapsedControlsLayout } from '../controller/layout';
-import { View } from './view';
-
-export class Layout extends View<LayoutController, { }, { }> {
-
-    private renderTarget(target: LayoutTarget) {
-        const statics: any[] = [];
-        const scrollable: any[] = [];
-
-        for (let c of target.components) {
-            if (c.isStatic) statics.push(<c.view key={c.key} controller={c.controller} />);
-            else scrollable.push(<c.view key={c.key} controller={c.controller} />);
-        }
-
-        return <div key={target.cssClass} className={'molstar-layout-region molstar-layout-' + target.cssClass}>
-            { statics.length ? <div className='molstar-layout-static'>{statics}</div> : void 0 }
-            { scrollable.length ? <div className='molstar-layout-scrollable'>{scrollable}</div> : void 0 }
-        </div>;
-    }
-
-    private updateTarget(name: string, regionType: LayoutRegion, layout: { regions: any[], layoutClass: string }) {
-        const state = this.controller.latestState;
-        const regionStates = state.regionStates;
-        const region = this.controller.targets[regionType];
-        let show: boolean;
-
-        if (state.hideControls) {
-            show = regionStates !== void 0 && regionStates[regionType] === 'Sticky' && region.components.length > 0;
-        } else if (regionStates && regionStates[regionType] === 'Hidden') {
-            show = false;
-        } else {
-            show = region.components.length > 0;
-        }
-
-        if (show) {
-            layout.regions.push(this.renderTarget(region));
-        } else {
-            layout.layoutClass += ' molstar-layout-hide-' + name;
-        }
-    }
-
-    render() {
-        let layoutClass = '';
-
-        const state = this.controller.latestState;
-        let layoutType: string;
-
-        if (state.isExpanded) {
-            layoutType = 'molstar-layout-expanded';
-        } else {
-            layoutType = 'molstar-layout-standard ';
-            switch (state.collapsedControlsLayout) {
-                case CollapsedControlsLayout.Outside: layoutType += 'molstar-layout-standard-outside'; break;
-                case CollapsedControlsLayout.Landscape: layoutType += 'molstar-layout-standard-landscape'; break;
-                case CollapsedControlsLayout.Portrait: layoutType += 'molstar-layout-standard-portrait'; break;
-                default: layoutType += 'molstar-layout-standard-outside'; break;
-            }
-        }
-
-        const targets = this.controller.targets;
-        const regions = [this.renderTarget(targets[LayoutRegion.Main])];
-
-        const layout = { regions, layoutClass };
-        this.updateTarget('top', LayoutRegion.Top, layout);
-        this.updateTarget('right', LayoutRegion.Right, layout);
-        this.updateTarget('bottom', LayoutRegion.Bottom, layout);
-        this.updateTarget('left', LayoutRegion.Left, layout);
-        layoutClass = layout.layoutClass;
-
-        let root = targets[LayoutRegion.Root].components.map(c => <c.view key={c.key} controller={c.controller} />);
-
-        return <div className='molstar-plugin'>
-            <div className={'molstar-plugin-content ' + layoutType}>
-                <div className={layoutClass}>
-                    {regions}
-                    {root}
-                </div>
-            </div>
-        </div>;
-    }
-}

+ 0 - 64
src/mol-app/ui/misc/jobs.tsx

@@ -1,64 +0,0 @@
-/**
- * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
- *
- * Adapted from LiteMol
- * Copyright (c) 2016 - now David Sehnal, licensed under Apache 2.0, See LICENSE file for more info.
- */
-
-import * as React from 'react'
-import { JobInfo, JobsController } from '../../controller/misc/jobs';
-import { Button } from '../controls/common';
-import { View } from '../view';
-
-class JobState extends React.Component<{ info: JobInfo, isSmall?: boolean }, {}> {
-    render() {
-        const info = this.props.info;
-        return <div className='molstar-task-state'>
-            <div>
-                { info.abort ? <Button onClick={() => info.abort!.call(null) } style='remove'
-                    icon='abort' title='Abort' customClass='molstar-btn-icon'
-                /> : void 0 }
-                <div>
-                    {info.name}: {info.message}
-                </div>
-            </div>
-        </div>;
-    }
-}
-
-export class Overlay extends View<JobsController, {}, {}> {
-    render() {
-        const state = this.controller.latestState;
-
-        if (!Object.keys(state.jobs).length) return <div className='molstar-empty-control' />
-
-        const jobs: any[] = [];
-        Object.keys(state.jobs).forEach(k => jobs.push(<JobState key={k} info={state.jobs[parseInt(k)]} />));
-
-        return <div className='molstar-overlay'>
-            <div className='molstar-overlay-background' />
-            <div className='molstar-overlay-content-wrap'>
-                <div className='molstar-overlay-content'>
-                    <div>
-                        {jobs}
-                    </div>
-                </div>
-            </div>
-        </div>;
-    }
-}
-
-export class BackgroundJobs extends View<JobsController, {}, {}> {
-    render() {
-        const state = this.controller.latestState;
-
-        if (!Object.keys(state.jobs).length) return <div className='molstar-empty-control' />
-
-        const jobs: any[] = [];
-        Object.keys(state.jobs).forEach(k => jobs.push(<JobState key={k} info={state.jobs[parseInt(k)]} isSmall={true} />));
-
-        return <div className='molstar-background-jobs'>
-            {jobs}
-        </div>;
-    }
-}

+ 0 - 69
src/mol-app/ui/misc/log.tsx

@@ -1,69 +0,0 @@
-/*
- * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
- *
- * Adapted from LiteMol
- * Copyright (c) 2016 - now David Sehnal, licensed under Apache 2.0, See LICENSE file for more info.
- */
-
-import * as React from 'react'
-import { View } from '../view';
-import { LogController } from '../../controller/misc/log';
-import { CommonEvents } from '../../event/basic';
-import { formatTime } from 'mol-util';
-import { Logger } from '../../service/logger';
-
-export class Log extends View<LogController, {}, {}> {
-
-    private wrapper: HTMLDivElement | undefined = void 0;
-
-    componentWillMount() {
-        super.componentWillMount();
-        this.subscribe(CommonEvents.LayoutChanged.getStream(this.controller.context), () => this.scrollToBottom());
-    }
-
-    componentDidUpdate() {
-        this.scrollToBottom();
-    }
-
-    private scrollToBottom() {
-        const log = this.wrapper;
-        if (log) log.scrollTop = log.scrollHeight - log.clientHeight - 1;
-    }
-
-    render() {
-        const entries = this.controller.latestState.entries;
-
-        return <div className='molstar-log-wrap'>
-            <div className='molstar-log' ref={log => this.wrapper = log!}>
-                <ul className='molstar-list-unstyled'>
-                    {entries.map((entry, i, arr) => {
-
-                        let label: JSX.Element;
-                        let e = entry!;
-                        switch (e.type) {
-                            case Logger.EntryType.Error:
-                                label = <span className='label label-danger'>Error</span>;
-                                break;
-                            case Logger.EntryType.Warning:
-                                label = <span className='label label-warning'>Warning</span>;
-                                break;
-                            case Logger.EntryType.Info:
-                                label = <span className='label label-info'>Info</span>;
-                                break;
-                            default:
-                                label = <span></span>
-                        }
-
-                        let t = formatTime(e.timestamp);
-                        return <li key={i}>
-                            <div className={'molstar-log-entry-badge molstar-log-entry-' + Logger.EntryType[e.type].toLowerCase()} />
-                            {label}
-                            <div className='molstar-log-timestamp'>{t}</div>
-                            <div className='molstar-log-entry'>{e.message}</div>
-                        </li>;
-                    }) }
-                </ul>
-            </div>
-        </div>;
-    }
-}

+ 0 - 244
src/mol-app/ui/transform/backbone.tsx

@@ -1,244 +0,0 @@
-/**
- * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
- *
- * Adapted from LiteMol
- * Copyright (c) 2016 - now David Sehnal, licensed under Apache 2.0, See LICENSE file for more info.
- *
- * @author Alexander Rose <alexander.rose@weirdbyte.de>
- */
-
-import * as React from 'react'
-
-import { View } from '../view';
-import { Controller } from '../../controller/controller';
-import { Toggle } from '../controls/common';
-import { BackboneEntity } from 'mol-view/state/entity';
-import { BackboneUpdate } from 'mol-view/state/transform'
-import { StateContext } from 'mol-view/state/context';
-import { ColorThemeProps, ColorThemeNames, ColorThemeName } from 'mol-view/theme/color';
-import { SizeThemeProps } from 'mol-view/theme/size';
-import { Color, ColorNames } from 'mol-util/color';
-import { Slider } from '../controls/slider';
-import { Unit } from 'mol-model/structure';
-import { VisualQuality } from 'mol-geo/geometry/geometry';
-
-interface BackboneState {
-    doubleSided: boolean
-    flipSided: boolean
-    flatShaded: boolean
-    detail: number
-    colorTheme: ColorThemeProps
-    colorValue: Color
-    sizeTheme: SizeThemeProps
-    visible: boolean
-    alpha: number
-    depthMask: boolean
-    useFog: boolean
-    quality: VisualQuality
-    unitKinds: Unit.Kind[]
-    radialSegments: number
-}
-
-export class Backbone extends View<Controller<any>, BackboneState, { transform: BackboneUpdate, entity: BackboneEntity, ctx: StateContext }> {
-    state = {
-        doubleSided: true,
-        flipSided: false,
-        flatShaded: false,
-        detail: 2,
-        colorTheme: { name: 'element-symbol' } as ColorThemeProps,
-        colorValue: Color(0x000000),
-        sizeTheme: { name: 'uniform', factor: 1 } as SizeThemeProps,
-        visible: true,
-        alpha: 1,
-        depthMask: true,
-        useFog: true,
-        quality: 'auto' as VisualQuality,
-        unitKinds: [] as Unit.Kind[],
-        radialSegments: 16
-    }
-
-    componentWillMount() {
-        this.setState({ ...this.state, ...this.props.entity.value.props })
-    }
-
-    update(state?: Partial<BackboneState>) {
-        const { transform, entity, ctx } = this.props
-        const newState = { ...this.state, ...state }
-        this.setState(newState)
-        transform.apply(ctx, entity, newState)
-    }
-
-    render() {
-        const { transform } = this.props
-
-        const qualityOptions = ['auto', 'custom', 'highest', 'high', 'medium', 'low', 'lowest'].map((name, idx) => {
-            return <option key={name} value={name}>{name}</option>
-        })
-
-        const sphereDetailOptions = [0, 1, 2, 3].map((value, idx) => {
-            return <option key={value} value={value}>{value.toString()}</option>
-        })
-
-        const colorThemeOptions = ColorThemeNames.map((name, idx) => {
-            return <option key={name} value={name}>{name}</option>
-        })
-
-        const colorValueOptions = Object.keys(ColorNames).map((name, idx) => {
-            return <option key={name} value={(ColorNames as any)[name]}>{name}</option>
-        })
-
-        return <div className='molstar-transformer-wrapper'>
-            <div className='molstar-panel molstar-control molstar-transformer molstar-panel-expanded'>
-                <div className='molstar-panel-header'>
-                    <button
-                        className='molstar-btn molstar-btn-link molstar-panel-expander'
-                        onClick={() => this.update()}
-                    >
-                        <span>[{transform.kind}] {transform.inputKind} -> {transform.outputKind}</span>
-                    </button>
-                </div>
-                <div className='molstar-panel-body'>
-                    <div>
-                    <div className='molstar-control-row molstar-options-group'>
-                        <span>Quality</span>
-                            <div>
-                                <select
-                                    className='molstar-form-control'
-                                    value={this.state.quality}
-                                    onChange={(e) => this.update({ quality: e.target.value as VisualQuality })}
-                                >
-                                    {qualityOptions}
-                                </select>
-                            </div>
-                        </div>
-                        <div className='molstar-control-row molstar-options-group'>
-                            <span>Sphere detail</span>
-                            <div>
-                                <select
-                                    className='molstar-form-control'
-                                    value={this.state.detail}
-                                    onChange={(e) => this.update({ detail: parseInt(e.target.value) })}
-                                >
-                                    {sphereDetailOptions}
-                                </select>
-                            </div>
-                        </div>
-                        <div className='molstar-control-row molstar-options-group'>
-                            <span>Color theme</span>
-                            <div>
-                                <select
-                                    className='molstar-form-control'
-                                    value={this.state.colorTheme.name}
-                                    onChange={(e) => {
-                                        this.update({
-                                            colorTheme: {
-                                                name: e.target.value as ColorThemeName,
-                                                value: this.state.colorValue
-                                            }
-                                        })
-                                    }}
-                                >
-                                    {colorThemeOptions}
-                                </select>
-                            </div>
-                        </div>
-                        <div className='molstar-control-row molstar-options-group'>
-                            <span>Color value</span>
-                            <div>
-                                <select
-                                    className='molstar-form-control'
-                                    value={this.state.colorValue}
-                                    onChange={(e) => {
-                                        const colorValue = Color(parseInt(e.target.value))
-                                        this.update({
-                                            colorTheme: {
-                                                name: 'uniform',
-                                                value: colorValue
-                                            },
-                                            colorValue
-                                        })
-                                    }}
-                                >
-                                    {colorValueOptions}
-                                </select>
-                            </div>
-                        </div>
-                        <div className='molstar-control-row molstar-options-group'>
-                            <div>
-                                <Toggle
-                                    value={this.state.visible}
-                                    label='Visibility'
-                                    onChange={value => this.update({ visible: value })}
-                                />
-                            </div>
-                        </div>
-                        <div className='molstar-control-row molstar-options-group'>
-                            <div>
-                                <Toggle
-                                    value={this.state.depthMask}
-                                    label='Depth write'
-                                    onChange={value => this.update({ depthMask: value })}
-                                />
-                            </div>
-                        </div>
-                        <div className='molstar-control-row molstar-options-group'>
-                            <div>
-                                <Toggle
-                                    value={this.state.doubleSided}
-                                    label='Double sided'
-                                    onChange={value => this.update({ doubleSided: value })}
-                                />
-                            </div>
-                        </div>
-                        <div className='molstar-control-row molstar-options-group'>
-                            <div>
-                                <Toggle
-                                    value={this.state.flipSided}
-                                    label='Flip sided'
-                                    onChange={value => this.update({ flipSided: value })}
-                                />
-                            </div>
-                        </div>
-                        <div className='molstar-control-row molstar-options-group'>
-                            <div>
-                                <Toggle
-                                    value={this.state.flatShaded}
-                                    label='Flat shaded'
-                                    onChange={value => this.update({ flatShaded: value })}
-                                />
-                            </div>
-                        </div>
-                        <div className='molstar-control-row molstar-options-group'>
-                            <div>
-                                <Slider
-                                    value={this.state.alpha}
-                                    label='Opacity'
-                                    min={0}
-                                    max={1}
-                                    step={0.01}
-                                    callOnChangeWhileSliding={true}
-                                    onChange={value => this.update({ alpha: value })}
-                                />
-                            </div>
-                        </div>
-                        <div className='molstar-control-row molstar-options-group'>
-                            <div>
-                                <Slider
-                                    value={this.state.sizeTheme.factor || 1}
-                                    label='Size factor'
-                                    min={0.1}
-                                    max={3}
-                                    step={0.01}
-                                    callOnChangeWhileSliding={true}
-                                    onChange={value => this.update({
-                                        sizeTheme: { ...this.state.sizeTheme, factor: value }
-                                    })}
-                                />
-                            </div>
-                        </div>
-                    </div>
-                </div>
-            </div>
-        </div>;
-    }
-}

+ 0 - 234
src/mol-app/ui/transform/ball-and-stick.tsx

@@ -1,234 +0,0 @@
-/**
- * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
- *
- * Adapted from LiteMol
- * Copyright (c) 2016 - now David Sehnal, licensed under Apache 2.0, See LICENSE file for more info.
- *
- * @author Alexander Rose <alexander.rose@weirdbyte.de>
- */
-
-import * as React from 'react'
-
-import { View } from '../view';
-import { Controller } from '../../controller/controller';
-import { Toggle } from '../controls/common';
-import { DistanceRestraintEntity } from 'mol-view/state/entity';
-import { DistanceRestraintUpdate } from 'mol-view/state/transform'
-import { StateContext } from 'mol-view/state/context';
-import { ColorThemeProps, ColorThemeNames, ColorThemeName } from 'mol-view/theme/color';
-import { SizeThemeProps } from 'mol-view/theme/size';
-import { Color, ColorNames } from 'mol-util/color';
-import { Slider } from '../controls/slider';
-import { Unit } from 'mol-model/structure';
-import { VisualQuality } from 'mol-geo/geometry/geometry';
-
-interface BallAndStickState {
-    doubleSided: boolean
-    flipSided: boolean
-    flatShaded: boolean
-    colorTheme: ColorThemeProps
-    colorValue: Color
-    sizeTheme: SizeThemeProps
-    visible: boolean
-    alpha: number
-    depthMask: boolean
-    useFog: boolean
-    quality: VisualQuality
-    linkScale: number
-    linkSpacing: number
-    linkRadius: number
-    radialSegments: number
-    detail: number
-    unitKinds: Unit.Kind[]
-}
-
-export class BallAndStick extends View<Controller<any>, BallAndStickState, { transform: DistanceRestraintUpdate, entity: DistanceRestraintEntity, ctx: StateContext }> {
-    state = {
-        doubleSided: true,
-        flipSided: false,
-        flatShaded: false,
-        colorTheme: { name: 'element-symbol' } as ColorThemeProps,
-        colorValue: Color(0x000000),
-        sizeTheme: { name: 'uniform', value: 0.15 } as SizeThemeProps,
-        visible: true,
-        alpha: 1,
-        depthMask: true,
-        useFog: true,
-        quality: 'auto' as VisualQuality,
-        linkScale: 0.4,
-        linkSpacing: 1,
-        linkRadius: 0.25,
-        radialSegments: 16,
-        detail: 1,
-        unitKinds: [] as Unit.Kind[]
-    }
-
-    componentWillMount() {
-        this.setState({ ...this.state, ...this.props.entity.value.props })
-    }
-
-    update(state?: Partial<BallAndStickState>) {
-        const { transform, entity, ctx } = this.props
-        const newState = { ...this.state, ...state }
-        this.setState(newState)
-        transform.apply(ctx, entity, newState)
-    }
-
-    render() {
-        const { transform } = this.props
-
-        const qualityOptions = ['auto', 'custom', 'highest', 'high', 'medium', 'low', 'lowest'].map((name, idx) => {
-            return <option key={name} value={name}>{name}</option>
-        })
-
-        const colorThemeOptions = ColorThemeNames.map((name, idx) => {
-            return <option key={name} value={name}>{name}</option>
-        })
-
-        const colorValueOptions = Object.keys(ColorNames).map((name, idx) => {
-            return <option key={name} value={(ColorNames as any)[name]}>{name}</option>
-        })
-
-        return <div className='molstar-transformer-wrapper'>
-            <div className='molstar-panel molstar-control molstar-transformer molstar-panel-expanded'>
-                <div className='molstar-panel-header'>
-                    <button
-                        className='molstar-btn molstar-btn-link molstar-panel-expander'
-                        onClick={() => this.update()}
-                    >
-                        <span>[{transform.kind}] {transform.inputKind} -> {transform.outputKind}</span>
-                    </button>
-                </div>
-                <div className='molstar-panel-body'>
-                    <div>
-                        <div className='molstar-control-row molstar-options-group'>
-                            <span>Quality</span>
-                            <div>
-                                <select
-                                    className='molstar-form-control'
-                                    value={this.state.quality}
-                                    onChange={(e) => this.update({ quality: e.target.value as VisualQuality })}
-                                >
-                                    {qualityOptions}
-                                </select>
-                            </div>
-                        </div>
-                        <div className='molstar-control-row molstar-options-group'>
-                            <span>Color theme</span>
-                            <div>
-                                <select
-                                    className='molstar-form-control'
-                                    value={this.state.colorTheme.name}
-                                    onChange={(e) => {
-                                        this.update({
-                                            colorTheme: {
-                                                name: e.target.value as ColorThemeName,
-                                                value: this.state.colorValue
-                                            }
-                                        })
-                                    }}
-                                >
-                                    {colorThemeOptions}
-                                </select>
-                            </div>
-                        </div>
-                        <div className='molstar-control-row molstar-options-group'>
-                            <span>Color value</span>
-                            <div>
-                                <select
-                                    className='molstar-form-control'
-                                    value={this.state.colorValue}
-                                    onChange={(e) => {
-                                        const colorValue = Color(parseInt(e.target.value))
-                                        this.update({
-                                            colorTheme: {
-                                                name: 'uniform',
-                                                value: colorValue
-                                            },
-                                            colorValue
-                                        })
-                                    }}
-                                >
-                                    {colorValueOptions}
-                                </select>
-                            </div>
-                        </div>
-                        <div className='molstar-control-row molstar-options-group'>
-                            <div>
-                                <Toggle
-                                    value={this.state.visible}
-                                    label='Visibility'
-                                    onChange={value => this.update({ visible: value })}
-                                />
-                            </div>
-                        </div>
-                        <div className='molstar-control-row molstar-options-group'>
-                            <div>
-                                <Toggle
-                                    value={this.state.depthMask}
-                                    label='Depth write'
-                                    onChange={value => this.update({ depthMask: value })}
-                                />
-                            </div>
-                        </div>
-                        <div className='molstar-control-row molstar-options-group'>
-                            <div>
-                                <Toggle
-                                    value={this.state.doubleSided}
-                                    label='Double sided'
-                                    onChange={value => this.update({ doubleSided: value })}
-                                />
-                            </div>
-                        </div>
-                        <div className='molstar-control-row molstar-options-group'>
-                            <div>
-                                <Toggle
-                                    value={this.state.flipSided}
-                                    label='Flip sided'
-                                    onChange={value => this.update({ flipSided: value })}
-                                />
-                            </div>
-                        </div>
-                        <div className='molstar-control-row molstar-options-group'>
-                            <div>
-                                <Toggle
-                                    value={this.state.flatShaded}
-                                    label='Flat shaded'
-                                    onChange={value => this.update({ flatShaded: value })}
-                                />
-                            </div>
-                        </div>
-                        <div className='molstar-control-row molstar-options-group'>
-                            <div>
-                                <Slider
-                                    value={this.state.alpha}
-                                    label='Opacity'
-                                    min={0}
-                                    max={1}
-                                    step={0.01}
-                                    callOnChangeWhileSliding={true}
-                                    onChange={value => this.update({ alpha: value })}
-                                />
-                            </div>
-                        </div>
-                        <div className='molstar-control-row molstar-options-group'>
-                            <div>
-                                <Slider
-                                    value={this.state.sizeTheme.factor || 1}
-                                    label='Size factor'
-                                    min={0.1}
-                                    max={3}
-                                    step={0.01}
-                                    callOnChangeWhileSliding={true}
-                                    onChange={value => this.update({
-                                        sizeTheme: { ...this.state.sizeTheme, factor: value }
-                                    })}
-                                />
-                            </div>
-                        </div>
-                    </div>
-                </div>
-            </div>
-        </div>;
-    }
-}

+ 0 - 250
src/mol-app/ui/transform/carbohydrate.tsx

@@ -1,250 +0,0 @@
-/**
- * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
- *
- * Adapted from LiteMol
- * Copyright (c) 2016 - now David Sehnal, licensed under Apache 2.0, See LICENSE file for more info.
- *
- * @author Alexander Rose <alexander.rose@weirdbyte.de>
- */
-
-import * as React from 'react'
-
-import { View } from '../view';
-import { Controller } from '../../controller/controller';
-import { Toggle } from '../controls/common';
-import { CarbohydrateEntity } from 'mol-view/state/entity';
-import { CarbohydrateUpdate } from 'mol-view/state/transform'
-import { StateContext } from 'mol-view/state/context';
-import { ColorThemeProps, ColorThemeNames, ColorThemeName } from 'mol-view/theme/color';
-import { SizeThemeProps } from 'mol-view/theme/size';
-import { Color, ColorNames } from 'mol-util/color';
-import { Slider } from '../controls/slider';
-import { Unit } from 'mol-model/structure';
-import { VisualQuality } from 'mol-geo/geometry/geometry';
-
-interface CarbohydrateState {
-    doubleSided: boolean
-    flipSided: boolean
-    flatShaded: boolean
-    detail: number
-    colorTheme: ColorThemeProps
-    colorValue: Color
-    sizeTheme: SizeThemeProps
-    visible: boolean
-    alpha: number
-    depthMask: boolean
-    useFog: boolean
-    quality: VisualQuality
-    unitKinds: Unit.Kind[]
-    linkScale: number
-    linkSpacing: number
-    linkRadius: number
-    radialSegments: number
-}
-
-export class Carbohydrate extends View<Controller<any>, CarbohydrateState, { transform: CarbohydrateUpdate, entity: CarbohydrateEntity, ctx: StateContext }> {
-    state = {
-        doubleSided: true,
-        flipSided: false,
-        flatShaded: false,
-        detail: 2,
-        colorTheme: { name: 'element-symbol' } as ColorThemeProps,
-        colorValue: Color(0x000000),
-        sizeTheme: { name: 'uniform', factor: 1 } as SizeThemeProps,
-        visible: true,
-        alpha: 1,
-        depthMask: true,
-        useFog: true,
-        quality: 'auto' as VisualQuality,
-        unitKinds: [] as Unit.Kind[],
-        linkScale: 0.4,
-        linkSpacing: 1,
-        linkRadius: 0.25,
-        radialSegments: 16
-    }
-
-    componentWillMount() {
-        this.setState({ ...this.state, ...this.props.entity.value.props })
-    }
-
-    update(state?: Partial<CarbohydrateState>) {
-        const { transform, entity, ctx } = this.props
-        const newState = { ...this.state, ...state }
-        this.setState(newState)
-        transform.apply(ctx, entity, newState)
-    }
-
-    render() {
-        const { transform } = this.props
-
-        const qualityOptions = ['auto', 'custom', 'highest', 'high', 'medium', 'low', 'lowest'].map((name, idx) => {
-            return <option key={name} value={name}>{name}</option>
-        })
-
-        const sphereDetailOptions = [0, 1, 2, 3].map((value, idx) => {
-            return <option key={value} value={value}>{value.toString()}</option>
-        })
-
-        const colorThemeOptions = ColorThemeNames.map((name, idx) => {
-            return <option key={name} value={name}>{name}</option>
-        })
-
-        const colorValueOptions = Object.keys(ColorNames).map((name, idx) => {
-            return <option key={name} value={(ColorNames as any)[name]}>{name}</option>
-        })
-
-        return <div className='molstar-transformer-wrapper'>
-            <div className='molstar-panel molstar-control molstar-transformer molstar-panel-expanded'>
-                <div className='molstar-panel-header'>
-                    <button
-                        className='molstar-btn molstar-btn-link molstar-panel-expander'
-                        onClick={() => this.update()}
-                    >
-                        <span>[{transform.kind}] {transform.inputKind} -> {transform.outputKind}</span>
-                    </button>
-                </div>
-                <div className='molstar-panel-body'>
-                    <div>
-                    <div className='molstar-control-row molstar-options-group'>
-                        <span>Quality</span>
-                            <div>
-                                <select
-                                    className='molstar-form-control'
-                                    value={this.state.quality}
-                                    onChange={(e) => this.update({ quality: e.target.value as VisualQuality })}
-                                >
-                                    {qualityOptions}
-                                </select>
-                            </div>
-                        </div>
-                        <div className='molstar-control-row molstar-options-group'>
-                            <span>Sphere detail</span>
-                            <div>
-                                <select
-                                    className='molstar-form-control'
-                                    value={this.state.detail}
-                                    onChange={(e) => this.update({ detail: parseInt(e.target.value) })}
-                                >
-                                    {sphereDetailOptions}
-                                </select>
-                            </div>
-                        </div>
-                        <div className='molstar-control-row molstar-options-group'>
-                            <span>Color theme</span>
-                            <div>
-                                <select
-                                    className='molstar-form-control'
-                                    value={this.state.colorTheme.name}
-                                    onChange={(e) => {
-                                        this.update({
-                                            colorTheme: {
-                                                name: e.target.value as ColorThemeName,
-                                                value: this.state.colorValue
-                                            }
-                                        })
-                                    }}
-                                >
-                                    {colorThemeOptions}
-                                </select>
-                            </div>
-                        </div>
-                        <div className='molstar-control-row molstar-options-group'>
-                            <span>Color value</span>
-                            <div>
-                                <select
-                                    className='molstar-form-control'
-                                    value={this.state.colorValue}
-                                    onChange={(e) => {
-                                        const colorValue = Color(parseInt(e.target.value))
-                                        this.update({
-                                            colorTheme: {
-                                                name: 'uniform',
-                                                value: colorValue
-                                            },
-                                            colorValue
-                                        })
-                                    }}
-                                >
-                                    {colorValueOptions}
-                                </select>
-                            </div>
-                        </div>
-                        <div className='molstar-control-row molstar-options-group'>
-                            <div>
-                                <Toggle
-                                    value={this.state.visible}
-                                    label='Visibility'
-                                    onChange={value => this.update({ visible: value })}
-                                />
-                            </div>
-                        </div>
-                        <div className='molstar-control-row molstar-options-group'>
-                            <div>
-                                <Toggle
-                                    value={this.state.depthMask}
-                                    label='Depth write'
-                                    onChange={value => this.update({ depthMask: value })}
-                                />
-                            </div>
-                        </div>
-                        <div className='molstar-control-row molstar-options-group'>
-                            <div>
-                                <Toggle
-                                    value={this.state.doubleSided}
-                                    label='Double sided'
-                                    onChange={value => this.update({ doubleSided: value })}
-                                />
-                            </div>
-                        </div>
-                        <div className='molstar-control-row molstar-options-group'>
-                            <div>
-                                <Toggle
-                                    value={this.state.flipSided}
-                                    label='Flip sided'
-                                    onChange={value => this.update({ flipSided: value })}
-                                />
-                            </div>
-                        </div>
-                        <div className='molstar-control-row molstar-options-group'>
-                            <div>
-                                <Toggle
-                                    value={this.state.flatShaded}
-                                    label='Flat shaded'
-                                    onChange={value => this.update({ flatShaded: value })}
-                                />
-                            </div>
-                        </div>
-                        <div className='molstar-control-row molstar-options-group'>
-                            <div>
-                                <Slider
-                                    value={this.state.alpha}
-                                    label='Opacity'
-                                    min={0}
-                                    max={1}
-                                    step={0.01}
-                                    callOnChangeWhileSliding={true}
-                                    onChange={value => this.update({ alpha: value })}
-                                />
-                            </div>
-                        </div>
-                        <div className='molstar-control-row molstar-options-group'>
-                            <div>
-                                <Slider
-                                    value={this.state.sizeTheme.factor || 1}
-                                    label='Size factor'
-                                    min={0.1}
-                                    max={3}
-                                    step={0.01}
-                                    callOnChangeWhileSliding={true}
-                                    onChange={value => this.update({
-                                        sizeTheme: { ...this.state.sizeTheme, factor: value }
-                                    })}
-                                />
-                            </div>
-                        </div>
-                    </div>
-                </div>
-            </div>
-        </div>;
-    }
-}

+ 0 - 278
src/mol-app/ui/transform/cartoon.tsx

@@ -1,278 +0,0 @@
-/**
- * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
- *
- * Adapted from LiteMol
- * Copyright (c) 2016 - now David Sehnal, licensed under Apache 2.0, See LICENSE file for more info.
- *
- * @author Alexander Rose <alexander.rose@weirdbyte.de>
- */
-
-import * as React from 'react'
-
-import { View } from '../view';
-import { Controller } from '../../controller/controller';
-import { Toggle } from '../controls/common';
-import { CartoonEntity } from 'mol-view/state/entity';
-import { CartoonUpdate } from 'mol-view/state/transform'
-import { StateContext } from 'mol-view/state/context';
-import { ColorThemeProps, ColorThemeNames, ColorThemeName } from 'mol-view/theme/color';
-import { SizeThemeProps } from 'mol-view/theme/size';
-import { Color, ColorNames } from 'mol-util/color';
-import { Slider } from '../controls/slider';
-import { Unit } from 'mol-model/structure';
-import { VisualQuality } from 'mol-geo/geometry/geometry';
-
-interface CartoonState {
-    doubleSided: boolean
-    flipSided: boolean
-    flatShaded: boolean
-    detail: number
-    colorTheme: ColorThemeProps
-    colorValue: Color
-    sizeTheme: SizeThemeProps
-    visible: boolean
-    alpha: number
-    depthMask: boolean
-    useFog: boolean
-    quality: VisualQuality
-    unitKinds: Unit.Kind[]
-    linearSegments: number
-    radialSegments: number
-    aspectRatio: number
-    arrowFactor: number
-}
-
-export class Cartoon extends View<Controller<any>, CartoonState, { transform: CartoonUpdate, entity: CartoonEntity, ctx: StateContext }> {
-    state = {
-        doubleSided: true,
-        flipSided: false,
-        flatShaded: false,
-        detail: 2,
-        colorTheme: { name: 'element-symbol' } as ColorThemeProps,
-        colorValue: Color(0x000000),
-        sizeTheme: { name: 'uniform', value: 0.13, factor: 1 } as SizeThemeProps,
-        visible: true,
-        alpha: 1,
-        depthMask: true,
-        useFog: true,
-        quality: 'auto' as VisualQuality,
-        unitKinds: [] as Unit.Kind[],
-        linearSegments: 8,
-        radialSegments: 12,
-        aspectRatio: 8,
-        arrowFactor: 1.5
-    }
-
-    componentWillMount() {
-        this.setState({ ...this.state, ...this.props.entity.value.props })
-    }
-
-    update(state?: Partial<CartoonState>) {
-        const { transform, entity, ctx } = this.props
-        const newState = { ...this.state, ...state }
-        this.setState(newState)
-        transform.apply(ctx, entity, newState)
-    }
-
-    render() {
-        const { transform } = this.props
-
-        const qualityOptions = ['auto', 'custom', 'highest', 'high', 'medium', 'low', 'lowest'].map((name, idx) => {
-            return <option key={name} value={name}>{name}</option>
-        })
-
-        const sphereDetailOptions = [0, 1, 2, 3].map((value, idx) => {
-            return <option key={value} value={value}>{value.toString()}</option>
-        })
-
-        const colorThemeOptions = ColorThemeNames.map((name, idx) => {
-            return <option key={name} value={name}>{name}</option>
-        })
-
-        const colorValueOptions = Object.keys(ColorNames).map((name, idx) => {
-            return <option key={name} value={(ColorNames as any)[name]}>{name}</option>
-        })
-
-        return <div className='molstar-transformer-wrapper'>
-            <div className='molstar-panel molstar-control molstar-transformer molstar-panel-expanded'>
-                <div className='molstar-panel-header'>
-                    <button
-                        className='molstar-btn molstar-btn-link molstar-panel-expander'
-                        onClick={() => this.update()}
-                    >
-                        <span>[{transform.kind}] {transform.inputKind} -> {transform.outputKind}</span>
-                    </button>
-                </div>
-                <div className='molstar-panel-body'>
-                    <div>
-                    <div className='molstar-control-row molstar-options-group'>
-                        <span>Quality</span>
-                            <div>
-                                <select
-                                    className='molstar-form-control'
-                                    value={this.state.quality}
-                                    onChange={(e) => this.update({ quality: e.target.value as VisualQuality })}
-                                >
-                                    {qualityOptions}
-                                </select>
-                            </div>
-                        </div>
-                        <div className='molstar-control-row molstar-options-group'>
-                            <span>Sphere detail</span>
-                            <div>
-                                <select
-                                    className='molstar-form-control'
-                                    value={this.state.detail}
-                                    onChange={(e) => this.update({ detail: parseInt(e.target.value) })}
-                                >
-                                    {sphereDetailOptions}
-                                </select>
-                            </div>
-                        </div>
-                        <div className='molstar-control-row molstar-options-group'>
-                            <span>Color theme</span>
-                            <div>
-                                <select
-                                    className='molstar-form-control'
-                                    value={this.state.colorTheme.name}
-                                    onChange={(e) => {
-                                        this.update({
-                                            colorTheme: {
-                                                name: e.target.value as ColorThemeName,
-                                                value: this.state.colorValue
-                                            }
-                                        })
-                                    }}
-                                >
-                                    {colorThemeOptions}
-                                </select>
-                            </div>
-                        </div>
-                        <div className='molstar-control-row molstar-options-group'>
-                            <span>Color value</span>
-                            <div>
-                                <select
-                                    className='molstar-form-control'
-                                    value={this.state.colorValue}
-                                    onChange={(e) => {
-                                        const colorValue = Color(parseInt(e.target.value))
-                                        this.update({
-                                            colorTheme: {
-                                                name: 'uniform',
-                                                value: colorValue
-                                            },
-                                            colorValue
-                                        })
-                                    }}
-                                >
-                                    {colorValueOptions}
-                                </select>
-                            </div>
-                        </div>
-                        <div className='molstar-control-row molstar-options-group'>
-                            <div>
-                                <Toggle
-                                    value={this.state.visible}
-                                    label='Visibility'
-                                    onChange={value => this.update({ visible: value })}
-                                />
-                            </div>
-                        </div>
-                        <div className='molstar-control-row molstar-options-group'>
-                            <div>
-                                <Toggle
-                                    value={this.state.depthMask}
-                                    label='Depth write'
-                                    onChange={value => this.update({ depthMask: value })}
-                                />
-                            </div>
-                        </div>
-                        <div className='molstar-control-row molstar-options-group'>
-                            <div>
-                                <Toggle
-                                    value={this.state.doubleSided}
-                                    label='Double sided'
-                                    onChange={value => this.update({ doubleSided: value })}
-                                />
-                            </div>
-                        </div>
-                        <div className='molstar-control-row molstar-options-group'>
-                            <div>
-                                <Toggle
-                                    value={this.state.flipSided}
-                                    label='Flip sided'
-                                    onChange={value => this.update({ flipSided: value })}
-                                />
-                            </div>
-                        </div>
-                        <div className='molstar-control-row molstar-options-group'>
-                            <div>
-                                <Toggle
-                                    value={this.state.flatShaded}
-                                    label='Flat shaded'
-                                    onChange={value => this.update({ flatShaded: value })}
-                                />
-                            </div>
-                        </div>
-                        <div className='molstar-control-row molstar-options-group'>
-                            <div>
-                                <Slider
-                                    value={this.state.alpha}
-                                    label='Opacity'
-                                    min={0}
-                                    max={1}
-                                    step={0.01}
-                                    callOnChangeWhileSliding={true}
-                                    onChange={value => this.update({ alpha: value })}
-                                />
-                            </div>
-                        </div>
-                        <div className='molstar-control-row molstar-options-group'>
-                            <div>
-                                <Slider
-                                    value={this.state.aspectRatio || 1}
-                                    label='Aspect ratio'
-                                    min={0.1}
-                                    max={10}
-                                    step={0.1}
-                                    callOnChangeWhileSliding={true}
-                                    onChange={value => this.update({ aspectRatio: value })}
-                                />
-                            </div>
-                        </div>
-                        <div className='molstar-control-row molstar-options-group'>
-                            <div>
-                                <Slider
-                                    value={this.state.sizeTheme.value || 0.1}
-                                    label='Size value'
-                                    min={0.01}
-                                    max={0.3}
-                                    step={0.01}
-                                    callOnChangeWhileSliding={true}
-                                    onChange={value => this.update({
-                                        sizeTheme: { ...this.state.sizeTheme, value: value }
-                                    })}
-                                />
-                            </div>
-                        </div>
-                        <div className='molstar-control-row molstar-options-group'>
-                            <div>
-                                <Slider
-                                    value={this.state.sizeTheme.factor || 1}
-                                    label='Size factor'
-                                    min={0.1}
-                                    max={3}
-                                    step={0.01}
-                                    callOnChangeWhileSliding={true}
-                                    onChange={value => this.update({
-                                        sizeTheme: { ...this.state.sizeTheme, factor: value }
-                                    })}
-                                />
-                            </div>
-                        </div>
-                    </div>
-                </div>
-            </div>
-        </div>;
-    }
-}

+ 0 - 219
src/mol-app/ui/transform/distance-restraint.tsx

@@ -1,219 +0,0 @@
-/**
- * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
- *
- * Adapted from LiteMol
- * Copyright (c) 2016 - now David Sehnal, licensed under Apache 2.0, See LICENSE file for more info.
- *
- * @author Alexander Rose <alexander.rose@weirdbyte.de>
- */
-
-import * as React from 'react'
-
-import { View } from '../view';
-import { Controller } from '../../controller/controller';
-import { Toggle } from '../controls/common';
-import { DistanceRestraintEntity } from 'mol-view/state/entity';
-import { DistanceRestraintUpdate } from 'mol-view/state/transform'
-import { StateContext } from 'mol-view/state/context';
-import { ColorThemeProps, ColorThemeNames, ColorThemeName } from 'mol-view/theme/color';
-import { SizeThemeProps } from 'mol-view/theme/size';
-import { Color, ColorNames } from 'mol-util/color';
-import { Slider } from '../controls/slider';
-import { Unit } from 'mol-model/structure';
-import { VisualQuality } from 'mol-geo/geometry/geometry';
-
-interface DistanceRestraintState {
-    doubleSided: boolean
-    flipSided: boolean
-    flatShaded: boolean
-    colorTheme: ColorThemeProps
-    colorValue: Color
-    sizeTheme: SizeThemeProps
-    visible: boolean
-    alpha: number
-    depthMask: boolean
-    useFog: boolean
-    quality: VisualQuality
-    linkScale: number
-    linkSpacing: number
-    linkRadius: number
-    radialSegments: number
-    detail: number
-    unitKinds: Unit.Kind[]
-}
-
-export class DistanceRestraint extends View<Controller<any>, DistanceRestraintState, { transform: DistanceRestraintUpdate, entity: DistanceRestraintEntity, ctx: StateContext }> {
-    state = {
-        doubleSided: true,
-        flipSided: false,
-        flatShaded: false,
-        colorTheme: { name: 'element-symbol' } as ColorThemeProps,
-        colorValue: Color(0x000000),
-        sizeTheme: { name: 'uniform' } as SizeThemeProps,
-        visible: true,
-        alpha: 1,
-        depthMask: true,
-        useFog: true,
-        quality: 'auto' as VisualQuality,
-        linkScale: 0.4,
-        linkSpacing: 1,
-        linkRadius: 0.25,
-        radialSegments: 16,
-        detail: 1,
-        unitKinds: [] as Unit.Kind[]
-    }
-
-    componentWillMount() {
-        this.setState({ ...this.state, ...this.props.entity.value.props })
-    }
-
-    update(state?: Partial<DistanceRestraintState>) {
-        const { transform, entity, ctx } = this.props
-        const newState = { ...this.state, ...state }
-        this.setState(newState)
-        transform.apply(ctx, entity, newState)
-    }
-
-    render() {
-        const { transform } = this.props
-
-        const qualityOptions = ['auto', 'custom', 'highest', 'high', 'medium', 'low', 'lowest'].map((name, idx) => {
-            return <option key={name} value={name}>{name}</option>
-        })
-
-        const colorThemeOptions = ColorThemeNames.map((name, idx) => {
-            return <option key={name} value={name}>{name}</option>
-        })
-
-        const colorValueOptions = Object.keys(ColorNames).map((name, idx) => {
-            return <option key={name} value={(ColorNames as any)[name]}>{name}</option>
-        })
-
-        return <div className='molstar-transformer-wrapper'>
-            <div className='molstar-panel molstar-control molstar-transformer molstar-panel-expanded'>
-                <div className='molstar-panel-header'>
-                    <button
-                        className='molstar-btn molstar-btn-link molstar-panel-expander'
-                        onClick={() => this.update()}
-                    >
-                        <span>[{transform.kind}] {transform.inputKind} -> {transform.outputKind}</span>
-                    </button>
-                </div>
-                <div className='molstar-panel-body'>
-                    <div>
-                        <div className='molstar-control-row molstar-options-group'>
-                            <span>Quality</span>
-                            <div>
-                                <select
-                                    className='molstar-form-control'
-                                    value={this.state.quality}
-                                    onChange={(e) => this.update({ quality: e.target.value as VisualQuality })}
-                                >
-                                    {qualityOptions}
-                                </select>
-                            </div>
-                        </div>
-                        <div className='molstar-control-row molstar-options-group'>
-                            <span>Color theme</span>
-                            <div>
-                                <select
-                                    className='molstar-form-control'
-                                    value={this.state.colorTheme.name}
-                                    onChange={(e) => {
-                                        this.update({
-                                            colorTheme: {
-                                                name: e.target.value as ColorThemeName,
-                                                value: this.state.colorValue
-                                            }
-                                        })
-                                    }}
-                                >
-                                    {colorThemeOptions}
-                                </select>
-                            </div>
-                        </div>
-                        <div className='molstar-control-row molstar-options-group'>
-                            <span>Color value</span>
-                            <div>
-                                <select
-                                    className='molstar-form-control'
-                                    value={this.state.colorValue}
-                                    onChange={(e) => {
-                                        const colorValue = Color(parseInt(e.target.value))
-                                        this.update({
-                                            colorTheme: {
-                                                name: 'uniform',
-                                                value: colorValue
-                                            },
-                                            colorValue
-                                        })
-                                    }}
-                                >
-                                    {colorValueOptions}
-                                </select>
-                            </div>
-                        </div>
-                        <div className='molstar-control-row molstar-options-group'>
-                            <div>
-                                <Toggle
-                                    value={this.state.visible}
-                                    label='Visibility'
-                                    onChange={value => this.update({ visible: value })}
-                                />
-                            </div>
-                        </div>
-                        <div className='molstar-control-row molstar-options-group'>
-                            <div>
-                                <Toggle
-                                    value={this.state.depthMask}
-                                    label='Depth write'
-                                    onChange={value => this.update({ depthMask: value })}
-                                />
-                            </div>
-                        </div>
-                        <div className='molstar-control-row molstar-options-group'>
-                            <div>
-                                <Toggle
-                                    value={this.state.doubleSided}
-                                    label='Double sided'
-                                    onChange={value => this.update({ doubleSided: value })}
-                                />
-                            </div>
-                        </div>
-                        <div className='molstar-control-row molstar-options-group'>
-                            <div>
-                                <Toggle
-                                    value={this.state.flipSided}
-                                    label='Flip sided'
-                                    onChange={value => this.update({ flipSided: value })}
-                                />
-                            </div>
-                        </div>
-                        <div className='molstar-control-row molstar-options-group'>
-                            <div>
-                                <Toggle
-                                    value={this.state.flatShaded}
-                                    label='Flat shaded'
-                                    onChange={value => this.update({ flatShaded: value })}
-                                />
-                            </div>
-                        </div>
-                        <div className='molstar-control-row molstar-options-group'>
-                            <div>
-                                <Slider
-                                    value={this.state.alpha}
-                                    label='Opacity'
-                                    min={0}
-                                    max={1}
-                                    step={0.01}
-                                    callOnChangeWhileSliding={true}
-                                    onChange={value => this.update({ alpha: value })}
-                                />
-                            </div>
-                        </div>
-                    </div>
-                </div>
-            </div>
-        </div>;
-    }
-}

Some files were not shown because too many files changed in this diff