@ccp-nc/crystvis-js 0.4.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (100) hide show
  1. package/.eslintrc.json +16 -0
  2. package/.github/workflows/test-mocha.yml +30 -0
  3. package/.vscode/settings.json +4 -0
  4. package/LICENSE +21 -0
  5. package/README.html +1127 -0
  6. package/README.md +76 -0
  7. package/demo/demo.css +30 -0
  8. package/demo/index.html +76 -0
  9. package/demo/main.js +143 -0
  10. package/docs/.nojekyll +0 -0
  11. package/docs-tutorials/Events.md +57 -0
  12. package/docs-tutorials/Queries.md +50 -0
  13. package/fonts/Rubik/OFL.txt +93 -0
  14. package/fonts/Rubik/README.txt +77 -0
  15. package/fonts/Rubik/Rubik-Italic-VariableFont_wght.ttf +0 -0
  16. package/fonts/Rubik/Rubik-VariableFont_wght.ttf +0 -0
  17. package/fonts/Rubik/static/Rubik-Black.ttf +0 -0
  18. package/fonts/Rubik/static/Rubik-BlackItalic.ttf +0 -0
  19. package/fonts/Rubik/static/Rubik-Bold.ttf +0 -0
  20. package/fonts/Rubik/static/Rubik-BoldItalic.ttf +0 -0
  21. package/fonts/Rubik/static/Rubik-ExtraBold.ttf +0 -0
  22. package/fonts/Rubik/static/Rubik-ExtraBoldItalic.ttf +0 -0
  23. package/fonts/Rubik/static/Rubik-Italic.ttf +0 -0
  24. package/fonts/Rubik/static/Rubik-Light.ttf +0 -0
  25. package/fonts/Rubik/static/Rubik-LightItalic.ttf +0 -0
  26. package/fonts/Rubik/static/Rubik-Medium.ttf +0 -0
  27. package/fonts/Rubik/static/Rubik-MediumItalic.ttf +0 -0
  28. package/fonts/Rubik/static/Rubik-Regular.ttf +0 -0
  29. package/fonts/Rubik/static/Rubik-SemiBold.ttf +0 -0
  30. package/fonts/Rubik/static/Rubik-SemiBoldItalic.ttf +0 -0
  31. package/index.html +25 -0
  32. package/index.js +11 -0
  33. package/jsconf.json +14 -0
  34. package/lib/assets/fonts/Rubik-Medium.fnt +297 -0
  35. package/lib/assets/fonts/Rubik-Medium.png +0 -0
  36. package/lib/assets/fonts/bmpfonts.in.js +16 -0
  37. package/lib/assets/fonts/bmpfonts.js +9 -0
  38. package/lib/assets/fonts/font.js +82 -0
  39. package/lib/assets/fonts/index.js +14 -0
  40. package/lib/assets/fonts/threebmfont.js +28 -0
  41. package/lib/data.js +125 -0
  42. package/lib/formats/cell.js +114 -0
  43. package/lib/formats/cif.js +22 -0
  44. package/lib/formats/magres.js +337 -0
  45. package/lib/formats/xyz.js +124 -0
  46. package/lib/loader.js +87 -0
  47. package/lib/model.js +2076 -0
  48. package/lib/modelview.js +382 -0
  49. package/lib/nmrdata.js +2898 -0
  50. package/lib/orbit.js +1233 -0
  51. package/lib/primitives/atoms.js +261 -0
  52. package/lib/primitives/cell.js +160 -0
  53. package/lib/primitives/dither.js +156 -0
  54. package/lib/primitives/ellipsoid.js +183 -0
  55. package/lib/primitives/geometries.js +20 -0
  56. package/lib/primitives/index.js +48 -0
  57. package/lib/primitives/isosurface.js +171 -0
  58. package/lib/primitives/shapes.js +100 -0
  59. package/lib/primitives/sprites.js +172 -0
  60. package/lib/query.js +158 -0
  61. package/lib/render.js +440 -0
  62. package/lib/selbox.js +361 -0
  63. package/lib/shaders/aura.frag +26 -0
  64. package/lib/shaders/aura.vert +37 -0
  65. package/lib/shaders/dither.frag +42 -0
  66. package/lib/shaders/dither.vert +8 -0
  67. package/lib/shaders/index.in.js +17 -0
  68. package/lib/shaders/index.js +25 -0
  69. package/lib/shaders/msdf300.frag +25 -0
  70. package/lib/shaders/msdf300.vert +45 -0
  71. package/lib/tensor.js +227 -0
  72. package/lib/utils.js +168 -0
  73. package/lib/visualizer.js +480 -0
  74. package/package.json +106 -0
  75. package/scripts/build-bundle.js +17 -0
  76. package/scripts/build-fonts.js +43 -0
  77. package/scripts/build-resources.js +46 -0
  78. package/scripts/plugins-shim.js +10 -0
  79. package/test/chemdata.js +69 -0
  80. package/test/data/CHA.cif +74 -0
  81. package/test/data/H2O.xyz +8 -0
  82. package/test/data/H2_bound.xyz +4 -0
  83. package/test/data/ethanol.cell +25 -0
  84. package/test/data/ethanol.magres +238 -0
  85. package/test/data/example_single.cif +789 -0
  86. package/test/data/frac.cell +8 -0
  87. package/test/data/org.cif +427 -0
  88. package/test/data/pyridine.xyz +13 -0
  89. package/test/data/si8.xyz +10 -0
  90. package/test/loader.js +107 -0
  91. package/test/model.js +368 -0
  92. package/test/query.js +135 -0
  93. package/test/tensor.js +133 -0
  94. package/test/test-html/examples.js +1485 -0
  95. package/test/test-html/index.html +33 -0
  96. package/test/test-html/index.js +279 -0
  97. package/tools/compile_colors.py +120 -0
  98. package/tools/compile_periodic.py +96 -0
  99. package/tools/ptable.json +497 -0
  100. package/tools/test +5844 -0
package/README.md ADDED
@@ -0,0 +1,76 @@
1
+ # crystvis-js
2
+
3
+ A [Three.js](https://threejs.org/) based crystallographic visualisation tool. It reads multiple file formats and renders them with WebGL to a `canvas` element, allowing the user to interact with them. A few of the key functionality:
4
+
5
+ * visualize popular file formats as ball-and-stick structures, easily embedded within a webpage, with orbit mouse control for rotation and zooming;
6
+ * interactive visualisation responsive to user clicks via customizable callbacks;
7
+ * high definition text labels;
8
+ * advanced searching and selection functions to interact with specific subset of atoms (select by proximity, bonding, species and more);
9
+ * smart visualisation of molecular crystal: reconstruct full molecules across the periodic boundary;
10
+ * compute and display isosurfaces from volumetric data;
11
+ * visualize tensor data as ellipsoids centred on atoms.
12
+
13
+ ### Supported formats
14
+
15
+ The currently supported file formats are the following:
16
+
17
+ * **CIF**, using [crystcif-parse](https://github.com/stur86/crystcif-parse);
18
+ * **XYZ**, including Extended XYZ such as the one written by the [Atomic Simulation Environment](https://wiki.fysik.dtu.dk/ase/);
19
+ * **CELL**, input file supported by the DFT package [CASTEP](http://www.castep.org/);
20
+ * **Magres**, output file format for simulated NMR parameters used by CASTEP and Quantum Espresso and developed by the [CCP for NMR Crystallography](https://www.ccpnc.ac.uk/).
21
+
22
+ ### Getting started
23
+
24
+ In order to install `crystvis-js`, simply use the Node Package Manager:
25
+
26
+ ```bash
27
+ npm install crystvis-js --save
28
+ ```
29
+
30
+ You can then create a visualizer for your webpage by simply importing and instantiating it:
31
+
32
+ ```js
33
+ import CrystVis from 'crystvis-js';
34
+
35
+ const visualizer = CrystVis('#target-id', 800, 600)
36
+ ```
37
+
38
+ will create an 800x600 canvas with the visualizer inside the element specified by the given selector. To load a model, simply load the contents of your file as a text string and then pass them to the visualizer's `loadModels` method:
39
+
40
+ ```js
41
+ var loaded = visualizer.loadModels(contents);
42
+ console.log('Models loaded: ', loaded);
43
+ visualizer.displayModel(loaded[0])
44
+ ```
45
+
46
+ ### Preparing for development
47
+
48
+ If you want to develop for crystvis-js, you should follow these steps:
49
+
50
+ * fork the repository
51
+ * clone the forked repository locally to your system
52
+ * install all the required packages, *including the development dependencies*, with `npm install --production=false`
53
+
54
+ You're then ready to develop. In particular you can use:
55
+
56
+ * `npm test` to run with Mocha the suite of tests found in `./test`
57
+ * `npm start` to start a server that includes the in-browser tests from `./test/test-html` as well as the demo from `./demo`
58
+ * `npm run docs` to compile the documents
59
+ * `npm run deploy-docs` to compile the documents and then deploy them to the `gh-pages` branch of your repository
60
+
61
+ #### Fonts and shaders
62
+
63
+ Some additional steps are necessary when dealing with fonts and shaders. You generally shouldn't worry about these when working
64
+ with most of the code, but in some special cases it might be necessary to do this.
65
+
66
+ Fonts in crystvis-js need to be translated to a bitmap format to be usable. In other words, a regular font format (like a TTF file)
67
+ must be rendered into a bitmap texture and a table of coordinates designating each letter to then be used in graphical rendering. This operation
68
+ relies on the library `msdf-bmfont-xml` and is executed by running the command `npm run build-fonts`. The original fonts are found in
69
+ the `./fonts` folder, and they get rendered to `./lib/assets/fonts`. This command needs only to be rerun *if the TTF files change*.
70
+
71
+ Shaders are provided as `.frag` and `.vert` files. Both shaders and font textures need to baked directly into the JavaScript files in order to be
72
+ included in the final build. Since ESBuild (the package used to build crystvis-js) has a hard time dealing with them in the final pass, they get
73
+ pre-baked with an additional step that only needs to be repeated whenever either of them changes. This consists of taking "template" JS files (for
74
+ shaders it's `./lib/shaders/index.in.js`, for fonts `./lib/assets/fonts/bmpfonts.in.js`) and rebuilding them into final files with the
75
+ assets imported in data URL form. The script to do this is `npm run build-resources`. This command only needs to be rerun *if the fonts were rebuilt, if the shader
76
+ code was edited, or if any of the two template files was changed*.
package/demo/demo.css ADDED
@@ -0,0 +1,30 @@
1
+ #main-app {
2
+ position: relative;
3
+ background-color: #002030;
4
+ width: 40vw;
5
+ height: 60vh;
6
+
7
+ color: white;
8
+ font-size: 30pt;
9
+ font-weight: bold;
10
+ font-family: sans-serif;
11
+ text-align: center;
12
+ line-height: 30vh;
13
+ }
14
+
15
+ #main-app canvas {
16
+ position: absolute;
17
+ top: 0;
18
+ left: 0;
19
+ }
20
+
21
+ #colorgrid {
22
+ display: grid;
23
+ grid-template-rows: repeat(10, 1fr);
24
+ grid-template-columns: repeat(30, 1fr);
25
+
26
+ width: 300px;
27
+ height: 300px;
28
+
29
+ background-color: #000000;
30
+ }
@@ -0,0 +1,76 @@
1
+ <!doctype html>
2
+ <html>
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <meta http-equiv="X-UA-Compatible" content="IE=edge">
6
+ <title></title>
7
+ <link rel="stylesheet" href="demo.css">
8
+
9
+ <script src="demo.js" type="text/javascript" charset="utf-8" async defer></script>
10
+ </head>
11
+ <body>
12
+
13
+ <div style="width: 100%; height: 100%">
14
+
15
+ <div style="float: left" id="main-app">
16
+ Loading...
17
+ </div>
18
+
19
+ <div style="float: right; width: 30%">
20
+ <table>
21
+ <caption>Input controls</caption>
22
+ <tbody>
23
+ <tr>
24
+ <td>
25
+ <input id="file-load" type="file" value="Load file">
26
+ </td>
27
+ <td>
28
+ Supercell:
29
+ <input id="scell-x" type="text" size="3">
30
+ <input id="scell-y" type="text" size="3">
31
+ <input id="scell-z" type="text" size="3">
32
+ </td>
33
+ </tr>
34
+ <tr>
35
+ <td>
36
+ <input type="button" name="" value="Load file" onclick="loadFile()">
37
+ </td>
38
+ <td>
39
+ <input id="molcryst-check" type="checkbox" name="" value="" placeholder="">Load as molecular crystal
40
+ </td>
41
+ </tr>
42
+ <tr>
43
+ <td>
44
+ <input type="button" name="" value="Show unit cell" onclick="changeDisplayed({'cell': [[0,0,0]]})">
45
+ </td>
46
+ <td>
47
+ <input type="button" name="" value="Show 5 Ang sphere" onclick="changeDisplayed({'sphere': [[0,0,0], 5.0]})">
48
+ </td>
49
+ </tr>
50
+ <tr>
51
+ <td colspan="" rowspan="" headers="">
52
+ <input id="label-check" type="checkbox" name="" value="false" onchange="changeLabels()">Show labels
53
+ </td>
54
+ <td colspan="" rowspan="" headers="">
55
+ <input id="ellipsoid-check" type="checkbox" name="" value="false" onchange="changeEllipsoids()">Show ellipsoids
56
+ </td>
57
+ </tr>
58
+ <tr>
59
+ <td>
60
+ <input id="isosurf-check" type="checkbox" name="" value="false" onchange="changeIsosurface()">Show isosurface
61
+ </td>
62
+ <td>
63
+ <input type="text" id="vdw-f" size="5" value="1.0"> Van der Waals scaling
64
+ </td>
65
+ </tr>
66
+ </tbody>
67
+ </table>
68
+ <div id='colorgrid'>
69
+
70
+ </div>
71
+ </div>
72
+
73
+ </div>
74
+
75
+ </body>
76
+ </html>
package/demo/main.js ADDED
@@ -0,0 +1,143 @@
1
+ 'use strict';
2
+
3
+ const CrystVis = require('../lib/visualizer.js').CrystVis;
4
+ const Primitives = require('../lib/primitives/index.js');
5
+
6
+ const shiftCpkColor = require('../lib/utils').shiftCpkColor;
7
+
8
+ var visualizer = new CrystVis('#main-app', 0, 0);
9
+ visualizer.highlight_selected = true;
10
+
11
+ // Generate color grid (for testing shiftCpkColor)
12
+ const gridEl = document.getElementById('colorgrid');
13
+ const gridSize = 10;
14
+
15
+ function int2hex(c) {
16
+ c = c.toString(16);
17
+ return '0'.repeat(6-c.length) + c;
18
+ }
19
+
20
+ for (let i = 0; i < gridSize; ++i) {
21
+ for (let j = 0; j < gridSize; ++j) {
22
+
23
+ const hue = parseInt(j/gridSize*360);
24
+ const light = parseInt(i/(gridSize-1)*100);
25
+ const cbase = `hsl(${hue}, 100%, ${light}%)`;
26
+ const cplus = shiftCpkColor(cbase, 1.0);
27
+ const cminus = shiftCpkColor(cbase, -1.0);
28
+
29
+ let el = document.createElement('div');
30
+ el.style['background-color'] = '#' + int2hex(cminus);
31
+ gridEl.append(el);
32
+
33
+ el = document.createElement('div');
34
+ el.style['background-color'] = cbase;
35
+ gridEl.append(el);
36
+
37
+ el = document.createElement('div');
38
+ el.style['background-color'] = '#' + int2hex(cplus);
39
+ gridEl.append(el);
40
+
41
+ }
42
+ }
43
+
44
+ window.loadFile = function() {
45
+ var file = document.getElementById('file-load').files[0];
46
+ var reader = new FileReader();
47
+ var extension = file.name.split('.').pop();
48
+
49
+ var sx = parseInt(document.getElementById("scell-x").value) || 1;
50
+ var sy = parseInt(document.getElementById("scell-y").value) || 1;
51
+ var sz = parseInt(document.getElementById("scell-z").value) || 1;
52
+
53
+ var vdwf = parseFloat(document.getElementById("vdw-f").value) || 1;
54
+
55
+ reader.readAsText(file);
56
+ reader.onload = function() {
57
+ var mcryst = document.getElementById('molcryst-check').checked;
58
+ var name = file.name.split('.')[0];
59
+ var loaded = visualizer.loadModels(reader.result, extension, name, {
60
+ supercell: [sx, sy, sz],
61
+ molecularCrystal: mcryst,
62
+ vdwScaling: vdwf
63
+ });
64
+
65
+ visualizer.displayModel(Object.keys(loaded)[0]);
66
+ visualizer.displayed = visualizer.model.find({
67
+ 'all': []
68
+ });
69
+
70
+ };
71
+ }
72
+
73
+ window.changeDisplayed = function(query) {
74
+ var select = visualizer.model.find(query);
75
+ visualizer.displayed = select;
76
+ }
77
+
78
+ window.changeLabels = function() {
79
+ var val = document.getElementById('label-check').checked;
80
+ if (val) {
81
+ visualizer.displayed.addLabels((a, i) => (a.crystLabel), 'labels', (a, i) => ({
82
+ shift: [1.2*a.radius, 0, 0]
83
+ }));
84
+ } else {
85
+ visualizer.displayed.removeLabels('labels');
86
+ }
87
+ }
88
+
89
+ window.changeEllipsoids = function() {
90
+ var val = document.getElementById('ellipsoid-check').checked;
91
+ if (val) {
92
+ visualizer.displayed.find({
93
+ 'elements': 'H'
94
+ }).addEllipsoids((a) => {
95
+ return a.getArrayValue('ms');
96
+ }, 'ms', {
97
+ scalingFactor: 0.05,
98
+ opacity: 0.2
99
+ });
100
+
101
+ } else {
102
+ visualizer.displayed.removeEllipsoids('ms');
103
+ }
104
+ }
105
+
106
+ var isosurface = null;
107
+ window.changeIsosurface = function() {
108
+ var val = document.getElementById('isosurf-check').checked;
109
+
110
+ // Create the data
111
+ var field = [];
112
+ for (let x = 0; x < 30; x += 1) {
113
+ field.push([]);
114
+ for (let y = 0; y < 30; y += 1) {
115
+ field[x].push([]);
116
+ for (let z = 0; z < 30; z += 1) {
117
+ var r = Math.pow(x-15, 2);
118
+ r += Math.pow(y-15, 2);
119
+ r += Math.pow(z-15, 2);
120
+ r = Math.sqrt(r);
121
+ var phi = Math.acos((z-15)/r);
122
+ field[x][y].push(r-Math.cos(3*phi)*0.2);
123
+ }
124
+ }
125
+ }
126
+
127
+
128
+ if (val) {
129
+ var cell = visualizer.model.cell;
130
+ isosurface = new Primitives.IsosurfaceMesh(field, 7.0, cell,
131
+ {
132
+ opacityMode: Primitives.IsosurfaceMesh.RENDER_WFRAME,
133
+ isoMethod: Primitives.IsosurfaceMesh.ISO_SURFACE_NETS
134
+ });
135
+ visualizer.addPrimitive(isosurface);
136
+ isosurface.color = '#ff0000';
137
+ } else {
138
+ if (isosurface) {
139
+ visualizer.removePrimitive(isosurface);
140
+ }
141
+ }
142
+
143
+ }
package/docs/.nojekyll ADDED
File without changes
@@ -0,0 +1,57 @@
1
+ User interactions with a model in CrystVis-js can be customised through the definition of callbacks for *events*. This means it's possible to bind arbitrary JavaScript code
2
+ to the various ways in which a user can click on an atom in the model. To do this, one needs to use the `.onAtomClick()` method of a `CrystVis` object, as well as its flags.
3
+
4
+ ### Defining an event
5
+
6
+ A custom event can be set by defining a callback function, then assigning that function to a specific click event. Here is an example:
7
+
8
+ ```js
9
+ function myCallback(atom, event) {
10
+ alert(atom.element);
11
+ }
12
+
13
+ visualizer.onAtomClick(myCallback, CrystVis.LEFT_CLICK)
14
+ ```
15
+
16
+ This code will result in binding a function that causes a popup to show with the chemical symbol of an atom's element whenever you left click on one.
17
+
18
+ ### Flags
19
+
20
+ Which event a callback should be bound to is defined by the flags passed as the second argument to `.onAtomClick()`. These are the available flags:
21
+
22
+ * `CrystVis.LEFT_CLICK`
23
+ * `CrystVis.RIGHT_CLICK`
24
+ * `CrystVis.MIDDLE_CLICK`
25
+ * `CrystVis.CTRL_BUTTON`
26
+ * `CrystVis.ALT_BUTTON`
27
+ * `CrystVis.SHIFT_BUTTON`
28
+ * `CrystVis.CMD_BUTTON`
29
+
30
+ Note that `CMD_BUTTON` is only used on Macs and equivalent to `CTRL_BUTTON` on other machines. These are bit flags, so they can be combined with addition or bitwise operators. For
31
+ example, `CrystVis.LEFT_CLICK + CrystVis.SHIFT_BUTTON` represents a click with the shift key down. Each combinations of flags can only hold one callback function; if `null` is passed
32
+ instead of a callback, default behaviour is restored.
33
+
34
+ ### Default behaviour
35
+
36
+ Most events by default are bound to nothing, mean, nothing will happen unless you define a specific behaviour for them. There are only three exceptions to this:
37
+
38
+ * `CrystVis.LEFT_CLICK` defaults to selecting the clicked atom
39
+ * `CrystVis.LEFT_CLICK + CrystVis.SHIFT_BUTTON` defaults to adding the clicked atom to selection
40
+ * `CrystVis.LEFT_CLICK + CrystVis.CTRL_BUTTON` defaults to switching the clicked atom in or out of the selection
41
+
42
+ To best see how the selection changes, set `.highlightSelected = true`.
43
+
44
+ ### Box selection
45
+
46
+ In addition to the various events described above, there is a special behaviour. Clicking while pressing Shift on a point that does *not* have an atom allows the user to drag
47
+ a box around multiple atoms, for example to select them in group. This behaviour can also be customized, by setting a callback with the method `.onAtomBox()`. Here is an example:
48
+
49
+ ```js
50
+ function boxCallback(atomview) {
51
+ alert(atomview.map((atom) => atom.element));
52
+ }
53
+
54
+ visualizer.onAtomBox(boxCallback)
55
+ ```
56
+
57
+ that will create an alert popup with a list of all the elements in the selected box.
@@ -0,0 +1,50 @@
1
+ In CrystVis-js, it's possible to use the `.find()` method in `Model` and `ModelView` objects to retrieve atoms based on various search criteria. The `.find()` method takes as argument a *query*; these queries are structured in a way that's inspired by queries used for example in the MongoDB interface. It's worth taking a minute to learn how they work.
2
+
3
+ ### Basic structure of a query
4
+
5
+ A query passed to the `.find()` method has to be an object. Typically, a query unit is structured as follows:
6
+
7
+ ```js
8
+ var query = {
9
+ "query_name": ["argument_1", "argument_2", ...]
10
+ }
11
+ ```
12
+
13
+ where the appropriate actual name and arguments of course must be replaced. For example, one might use
14
+
15
+ ```js
16
+ var H_atoms = model.find({
17
+ "elements": ["H"]
18
+ })
19
+ ```
20
+
21
+ to identify all hydrogen atoms within the model. The functions accepted for queries by a model are the following:
22
+
23
+ * `all` (no arguments): return all atoms in the model
24
+ * `indices` (`indices`): return all atoms with the given index or Array of indices
25
+ * `elements` (`elems`): return all atoms with the given element or one of an Array of elements
26
+ * `cell` (`ijk`): return atoms within the cell with indices i, j and k
27
+ * `box` (`x0`, `x1`): return atoms inside a box defined by two corners (points or atoms)
28
+ * `sphere` (`x0`, `r`): return atoms inside a sphere defined by a center (point or atom) and a radius
29
+ * `bonded` (`atoms`, `distance`, `exact`): return atoms within a certain number of bonds ("distance") from one or more atoms. For example, asking for all atoms within one bond from the oxygen in a water molecule will return the whole molecule. If "exact" is set to true instead, only atoms at the exact distance will be returned. In the water molecule example, this would return only the hydrogens
30
+ * `molecule` (`atoms`): return all atoms belonging to the same molecule as one of the atoms passed as argument
31
+
32
+ ### Boolean operators
33
+
34
+ In addition to the simple functions described above, queries accept boolean operators that can be used to build more complex ones. For example one could use this query:
35
+
36
+ ```js
37
+ var query = {
38
+ "$and": [{
39
+ "elements": [["H", "C"]]
40
+ }, {
41
+ "sphere": [[0, 0, 0], 4.0]
42
+ }]
43
+ }
44
+ ```
45
+
46
+ to retrieve all atoms of either hydrogen or carbon located within a radius of 4 Angstroms from the origin of the cell. A boolean operator takes more queries as arguments, which means they can be nested further for more complex searches. The accepted boolean operators are the following:
47
+
48
+ * `$and` (`query_1`, `query_2`, ...): returns the intersection of all the passed queries
49
+ * `$or` (`query_1`, `query_2`, ...): returns the union of all the passed queries
50
+ * `$xor` (`query_1`, `query_2`, ...): return the exclusive OR of all queries (in other words, any atom that is returned by only one query but no other)
@@ -0,0 +1,93 @@
1
+ Copyright 2015 The Rubik Project Authors (https://github.com/googlefonts/rubik),
2
+
3
+ This Font Software is licensed under the SIL Open Font License, Version 1.1.
4
+ This license is copied below, and is also available with a FAQ at:
5
+ http://scripts.sil.org/OFL
6
+
7
+
8
+ -----------------------------------------------------------
9
+ SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
10
+ -----------------------------------------------------------
11
+
12
+ PREAMBLE
13
+ The goals of the Open Font License (OFL) are to stimulate worldwide
14
+ development of collaborative font projects, to support the font creation
15
+ efforts of academic and linguistic communities, and to provide a free and
16
+ open framework in which fonts may be shared and improved in partnership
17
+ with others.
18
+
19
+ The OFL allows the licensed fonts to be used, studied, modified and
20
+ redistributed freely as long as they are not sold by themselves. The
21
+ fonts, including any derivative works, can be bundled, embedded,
22
+ redistributed and/or sold with any software provided that any reserved
23
+ names are not used by derivative works. The fonts and derivatives,
24
+ however, cannot be released under any other type of license. The
25
+ requirement for fonts to remain under this license does not apply
26
+ to any document created using the fonts or their derivatives.
27
+
28
+ DEFINITIONS
29
+ "Font Software" refers to the set of files released by the Copyright
30
+ Holder(s) under this license and clearly marked as such. This may
31
+ include source files, build scripts and documentation.
32
+
33
+ "Reserved Font Name" refers to any names specified as such after the
34
+ copyright statement(s).
35
+
36
+ "Original Version" refers to the collection of Font Software components as
37
+ distributed by the Copyright Holder(s).
38
+
39
+ "Modified Version" refers to any derivative made by adding to, deleting,
40
+ or substituting -- in part or in whole -- any of the components of the
41
+ Original Version, by changing formats or by porting the Font Software to a
42
+ new environment.
43
+
44
+ "Author" refers to any designer, engineer, programmer, technical
45
+ writer or other person who contributed to the Font Software.
46
+
47
+ PERMISSION & CONDITIONS
48
+ Permission is hereby granted, free of charge, to any person obtaining
49
+ a copy of the Font Software, to use, study, copy, merge, embed, modify,
50
+ redistribute, and sell modified and unmodified copies of the Font
51
+ Software, subject to the following conditions:
52
+
53
+ 1) Neither the Font Software nor any of its individual components,
54
+ in Original or Modified Versions, may be sold by itself.
55
+
56
+ 2) Original or Modified Versions of the Font Software may be bundled,
57
+ redistributed and/or sold with any software, provided that each copy
58
+ contains the above copyright notice and this license. These can be
59
+ included either as stand-alone text files, human-readable headers or
60
+ in the appropriate machine-readable metadata fields within text or
61
+ binary files as long as those fields can be easily viewed by the user.
62
+
63
+ 3) No Modified Version of the Font Software may use the Reserved Font
64
+ Name(s) unless explicit written permission is granted by the corresponding
65
+ Copyright Holder. This restriction only applies to the primary font name as
66
+ presented to the users.
67
+
68
+ 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
69
+ Software shall not be used to promote, endorse or advertise any
70
+ Modified Version, except to acknowledge the contribution(s) of the
71
+ Copyright Holder(s) and the Author(s) or with their explicit written
72
+ permission.
73
+
74
+ 5) The Font Software, modified or unmodified, in part or in whole,
75
+ must be distributed entirely under this license, and must not be
76
+ distributed under any other license. The requirement for fonts to
77
+ remain under this license does not apply to any document created
78
+ using the Font Software.
79
+
80
+ TERMINATION
81
+ This license becomes null and void if any of the above conditions are
82
+ not met.
83
+
84
+ DISCLAIMER
85
+ THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
86
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
87
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
88
+ OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
89
+ COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
90
+ INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
91
+ DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
92
+ FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
93
+ OTHER DEALINGS IN THE FONT SOFTWARE.
@@ -0,0 +1,77 @@
1
+ Rubik Variable Font
2
+ ===================
3
+
4
+ This download contains Rubik as both variable fonts and static fonts.
5
+
6
+ Rubik is a variable font with this axis:
7
+ wght
8
+
9
+ This means all the styles are contained in these files:
10
+ Rubik-VariableFont_wght.ttf
11
+ Rubik-Italic-VariableFont_wght.ttf
12
+
13
+ If your app fully supports variable fonts, you can now pick intermediate styles
14
+ that aren’t available as static fonts. Not all apps support variable fonts, and
15
+ in those cases you can use the static font files for Rubik:
16
+ static/Rubik-Light.ttf
17
+ static/Rubik-Regular.ttf
18
+ static/Rubik-Medium.ttf
19
+ static/Rubik-SemiBold.ttf
20
+ static/Rubik-Bold.ttf
21
+ static/Rubik-ExtraBold.ttf
22
+ static/Rubik-Black.ttf
23
+ static/Rubik-LightItalic.ttf
24
+ static/Rubik-Italic.ttf
25
+ static/Rubik-MediumItalic.ttf
26
+ static/Rubik-SemiBoldItalic.ttf
27
+ static/Rubik-BoldItalic.ttf
28
+ static/Rubik-ExtraBoldItalic.ttf
29
+ static/Rubik-BlackItalic.ttf
30
+
31
+ Get started
32
+ -----------
33
+
34
+ 1. Install the font files you want to use
35
+
36
+ 2. Use your app's font picker to view the font family and all the
37
+ available styles
38
+
39
+ Learn more about variable fonts
40
+ -------------------------------
41
+
42
+ https://developers.google.com/web/fundamentals/design-and-ux/typography/variable-fonts
43
+ https://variablefonts.typenetwork.com
44
+ https://medium.com/variable-fonts
45
+
46
+ In desktop apps
47
+
48
+ https://theblog.adobe.com/can-variable-fonts-illustrator-cc
49
+ https://helpx.adobe.com/nz/photoshop/using/fonts.html#variable_fonts
50
+
51
+ Online
52
+
53
+ https://developers.google.com/fonts/docs/getting_started
54
+ https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Fonts/Variable_Fonts_Guide
55
+ https://developer.microsoft.com/en-us/microsoft-edge/testdrive/demos/variable-fonts
56
+
57
+ Installing fonts
58
+
59
+ MacOS: https://support.apple.com/en-us/HT201749
60
+ Linux: https://www.google.com/search?q=how+to+install+a+font+on+gnu%2Blinux
61
+ Windows: https://support.microsoft.com/en-us/help/314960/how-to-install-or-remove-a-font-in-windows
62
+
63
+ Android Apps
64
+
65
+ https://developers.google.com/fonts/docs/android
66
+ https://developer.android.com/guide/topics/ui/look-and-feel/downloadable-fonts
67
+
68
+ License
69
+ -------
70
+ Please read the full license text (OFL.txt) to understand the permissions,
71
+ restrictions and requirements for usage, redistribution, and modification.
72
+
73
+ You can use them freely in your products & projects - print or digital,
74
+ commercial or otherwise. However, you can't sell the fonts on their own.
75
+
76
+ This isn't legal advice, please consider consulting a lawyer and see the full
77
+ license for all details.