├── .gitignore
├── LICENSE.md
├── README.md
├── codelabs
├── intro-to-babylon
│ └── basic.html
└── intro-to-webgl
│ ├── README.md
│ ├── assets
│ └── textures
│ │ ├── earth_atmos_2048.jpg
│ │ ├── land_ocean_ice_cloud_2048.jpg
│ │ └── moon_1024.jpg
│ ├── config
│ └── prpl-server.json
│ ├── index.html
│ ├── index.js
│ ├── package-lock.json
│ └── package.json
├── experiments
├── 00-template
│ ├── .gitignore
│ ├── images
│ │ ├── favicon.ico
│ │ └── manifest
│ │ │ ├── icon-144x144.png
│ │ │ ├── icon-192x192.png
│ │ │ ├── icon-48x48.png
│ │ │ ├── icon-512x512.png
│ │ │ ├── icon-72x72.png
│ │ │ └── icon-96x96.png
│ ├── index.html
│ ├── manifest.json
│ ├── package-lock.json
│ ├── package.json
│ ├── service-worker.js
│ └── src
│ │ └── components
│ │ └── anim.js
├── 01-webgl-component
│ ├── .gitignore
│ ├── images
│ │ ├── favicon.ico
│ │ └── manifest
│ │ │ ├── icon-144x144.png
│ │ │ ├── icon-192x192.png
│ │ │ ├── icon-48x48.png
│ │ │ ├── icon-512x512.png
│ │ │ ├── icon-72x72.png
│ │ │ └── icon-96x96.png
│ ├── index.html
│ ├── manifest.json
│ ├── package-lock.json
│ ├── package.json
│ ├── polymer.json
│ ├── service-worker.js
│ └── src
│ │ └── components
│ │ └── my-anim.js
├── 02-webgl-subcomponent
│ ├── .gitignore
│ ├── images
│ │ ├── favicon.ico
│ │ └── manifest
│ │ │ ├── icon-144x144.png
│ │ │ ├── icon-192x192.png
│ │ │ ├── icon-48x48.png
│ │ │ ├── icon-512x512.png
│ │ │ ├── icon-72x72.png
│ │ │ └── icon-96x96.png
│ ├── index.html
│ ├── manifest.json
│ ├── package-lock.json
│ ├── package.json
│ ├── polymer.json
│ ├── service-worker.js
│ └── src
│ │ └── components
│ │ ├── my-anim-sub.js
│ │ └── my-anim.js
├── 03-webgl-layers
│ ├── .gitignore
│ ├── images
│ │ ├── favicon.ico
│ │ ├── manifest
│ │ │ ├── icon-144x144.png
│ │ │ ├── icon-192x192.png
│ │ │ ├── icon-48x48.png
│ │ │ ├── icon-512x512.png
│ │ │ ├── icon-72x72.png
│ │ │ └── icon-96x96.png
│ │ └── screenshot.png
│ ├── index.html
│ ├── manifest.json
│ ├── package-lock.json
│ ├── package.json
│ ├── polymer.json
│ ├── service-worker.js
│ └── src
│ │ └── components
│ │ ├── my-anim-plane.js
│ │ └── my-anim.js
├── 04-model-viewer
│ └── models
│ │ └── Astronaut.glb
└── 05-three-app
│ ├── MODEL.html
│ ├── package-lock.json
│ └── package.json
└── workshops
└── shaders-primer
├── README.md
├── bose-mouse-move.glsl
├── bose-truchet-tile.glsl
├── shadertoy-step1.glsl
├── shadertoy-step10.glsl
├── shadertoy-step11.glsl
├── shadertoy-step2.glsl
├── shadertoy-step3.glsl
├── shadertoy-step4.glsl
├── shadertoy-step5.glsl
├── shadertoy-step6.glsl
├── shadertoy-step7.glsl
├── shadertoy-step8.glsl
└── shadertoy-step9.glsl
/.gitignore:
--------------------------------------------------------------------------------
1 | .vscode/
2 | node_modules/
3 | .DS_Store
4 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | [](http://creativecommons.org/licenses/by-sa/4.0/)
2 |
3 | [Learning WebGL](https://github.com/olange/learning-webgl) de Olivier Lange est mis à disposition selon les termes de la licence [Creative Commons Paternité - Partage des Conditions Initiales à l'Identique 4.0 International](http://creativecommons.org/licenses/by-sa/4.0/).
4 |
5 | Fondé(e) sur une œuvre à https://github.com/olange/learning-webgl.
6 |
7 | Pour le texte complet de la licence, veuillez vous référer à http://creativecommons.org/licenses/by-sa/4.0/
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Learning WebGL, GLSL and Three.js
2 |
3 | Articles, useful resources, courseware, personal notes
4 |
5 | [](https://gitter.im/olange/learning-webgl?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
6 |
7 | ## Workshops
8 |
9 | * [Shader Programming Primer: Real-Time Animation and Effects with GLSL](workshops/shaders-primer/README.md)
10 | Mapping Festival 2019 / Workshop 6 · 23.05.2019 10h–19h
11 | by [Leander Herzog](https://www.shadertoy.com/user/lennyjpg) · Fonderie Kugler, Genève
12 |
13 | ## Codelabs
14 |
15 | * [Texturing a video with a moire pattern · ShaderToy](https://www.shadertoy.com/view/WlBGzW) by Olivier Lange, Leander Herzog & Nicola Papale
16 | * [First steps with WebGL and Three.js](codelabs/intro-to-webgl) _first steps and experiments, inspired by the slides
17 | of David Lyons (see [tutorials](#tutorials) hereafter)_
18 |
19 | ## Experiments
20 |
21 | * [01 · Three and Web Components](experiments/01-webgl-component/) Three.js animation in a web component
22 | * [02 · Three and embedded Web Components](experiments/02-webgl-subcomponent) Three.js animations in embedded web components
23 | * [03 · Three and plane layers](experiments/03-webgl-layers) Three.js animation of plane layers, with holes, rotating over each other
24 |
25 | ## Tutorials
26 |
27 | * [The Book of Shaders](https://thebookofshaders.com) by Patricio Gonzalez Vivo and Jen Lowe
28 | * [OpenGL Introduction](https://open.gl/introduction) by Alexander Overvoorde
29 | * [WebGL Fundamentals](https://webglfundamentals.org/webgl/lessons/webgl-fundamentals.html) (Greggman, 2012–2018 ongoing) _comprehensive collection of articles about WebGL, explained step by step_
30 | - [x] [WebGL Fundamentals](https://webglfundamentals.org/webgl/lessons/webgl-fundamentals.html)
31 | - [x] [WebGL How It Works](https://webglfundamentals.org/webgl/lessons/webgl-how-it-works.html)
32 | - [x] [WebGL Shaders and GLSL](https://webglfundamentals.org/webgl/lessons/webgl-shaders-and-glsl.html)
33 | - [x] [WebGL Image Processing](https://webglfundamentals.org/webgl/lessons/webgl-image-processing.html)
34 | - [x] [WebGL Image Processing Continued](https://webglfundamentals.org/webgl/lessons/webgl-image-processing-continued.html)
35 | - [x] [WebGL - Less Code, More Fun](https://webglfundamentals.org/webgl/lessons/webgl-less-code-more-fun.html)
36 | - [x] [WebGL - Scene Graph](https://webglfundamentals.org/webgl/lessons/webgl-scene-graph.html)
37 | - [x] [WebGL 3D Geometry - Lathe](https://webglfundamentals.org/webgl/lessons/webgl-3d-geometry-lathe.html)
38 | - [x] [WebGL Resizing the Canvas](https://webglfundamentals.org/webgl/lessons/webgl-resizing-the-canvas.html)
39 | - [x] [WebGL and Alpha](https://webglfundamentals.org/webgl/lessons/webgl-and-alpha.html)
40 | - [x] [WebGL - Rasterization vs 3D libraries](https://webglfundamentals.org/webgl/lessons/webgl-2d-vs-3d-library.html)
41 | - [x] [WebGL Anti-Patterns](https://webglfundamentals.org/webgl/lessons/webgl-anti-patterns.html)
42 | - [x] [TWGL, A tiny WebGL helper library › Examples](http://twgljs.org/#examples)
43 | * [WebGL2 Fundamentals](https://webgl2fundamentals.org) (Greggman, 2012–2018 ongoing) _the same recipe as WebGL Fundamental: comprehensive, high-quality articles, well explained, learning step by step_
44 | * [Intro to WebGL with Three.js](http://davidscottlyons.com/threejs-intro/) (David Lyons, 10-11.2014)
45 | [slides](http://davidscottlyons.com/threejs-intro/) | [vidéo 10.2014](https://youtu.be/6eLl8yQnxHQ) 18mn. | [vidéo 11.2014](https://youtu.be/-L6WWbKthvw) 43mn. | [sources](https://github.com/davidlyons/threejs-intro)
46 |
47 | ## Books
48 |
49 | * [Programming 3D Applications with HTML5 and WebGL — 3D Animation and Visualization for Web Pages](https://www.amazon.de/Programming-Applications-HTML5-WebGL-Visualization/dp/1449362966/) by Tony Parisi, O'Reilly, 2014
50 |
51 | ## Articles
52 |
53 | * [ECMAScript modules in browsers](https://jakearchibald.com/2017/es-modules-in-browsers/) (Jake Archibald, 02.05.2017)
54 | * [A Primer on Bézier Curves](https://pomax.github.io/bezierinfo/) _A free, online book for when you really need to know how to do Bézier things_
55 | * [Nvidia Developer › GPU Gems 3 › Chapter 25. Rendering Vector Art on the GPU](https://developer.nvidia.com/gpugems/GPUGems3/gpugems3_ch25.html) (Charles Loop & Jim Blinn,
56 | Microsoft Research) _Presents a method for accelerating the rendering of vector representations on the GPU_
57 | * [Wikipedia › Octree](https://en.m.wikipedia.org/wiki/Octree) _An octree is a tree data structure in which each internal node has exactly eight children. Octrees are most often used to partition a three-dimensional space by recursively subdividing it into eight octants. […]_
58 |
59 | ## Useful resources
60 |
61 | * [Shadertoy](https://www.shadertoy.com/) _A curated collection of shaders from all around the world – source, textures, editor and preview_
62 | (and a [vintage version 0.4](https://www.iquilezles.org/apps/shadertoy/index2.html)?)
63 | * [The Book of Shaders Editor](http://editor.thebookofshaders.com) _An online GLSL editor, similar to ShaderToy_
64 |
65 | ## Interesting examples
66 |
67 | * [Three examples › CSS3D › Periodic table](https://threejs.org/examples/#css3d_periodictable) ([Source](https://github.com/mrdoob/three.js/blob/master/examples/js/renderers/CSS3DRenderer.js)) Three.js coupled to a CSS 3D renderer
68 | * [Tendrils - epok | Trust - Max Cooper](https://epok.tech/work/tendrils/) _Forms in motion, interact spontaneously, knitting emergent interconnections; interactive music visuals for Max Cooper's Emergence project._
69 |
--------------------------------------------------------------------------------
/codelabs/intro-to-babylon/basic.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Babylon - Getting Started
6 |
7 |
8 |
28 |
29 |
30 | Babylon basic script
31 | Lives happily next to HTML elements
32 |
33 |
85 |
--------------------------------------------------------------------------------
/codelabs/intro-to-webgl/README.md:
--------------------------------------------------------------------------------
1 | # Codelab « First steps with WebGL and Three.js »
2 |
3 | A few WebGL and Three.js code experiments, inspired by the « [Intro to WebGL with Three.js](http://davidscottlyons.com/threejs-intro/) » slides of David Scott Lyons.
4 |
5 | 
6 |
7 | ## Experiments
8 |
9 | 1. [Setting up renderer, camera, scene](index.js#L24) and [ambient light](index.js#L28) (required for textures)
10 | 2. [Box and sphere meshes](http://davidscottlyons.com/threejs-intro/#slide-46)
11 | 3. [Dashed lines](https://threejs.org/docs/#api/materials/LineDashedMaterial) WebGL engine is a _rasterizer_ – it supports drawing dots and lines, not only triangles
12 | 4. [Mixing HTML with WebGL canvas: transparent overlay](index.html#L9) composition works quite fast!
13 | 5. [Animating the scene, every 15ms](index.js#L89)
14 | 6. [Camera orbit controls](index.js#L13) loading as an ES6 module was a bit tricky
15 | 7. Correctly setting aspect ratio and canvas dimension with CSS
16 | (using `.clientWidth/Height` CSS properties – see [WebGL Anti-patterns #2](https://webglfundamentals.org/webgl/lessons/webgl-anti-patterns.html))
17 | 8. [Texturing the sphere with a color map](http://davidscottlyons.com/threejs-intro/#slide-74) (the earth)
18 | 9. Using [PRPL HTTP2 server](https://github.com/Polymer/prpl-server-node) to serve assets (script, libraries and textures)
19 | 10. [Importing libraries as ES6 modules](https://threejs.org/docs/#manual/introduction/Import-via-modules)
20 |
21 | ## Usage
22 |
23 | Run the HTTP local server:
24 |
25 | ```
26 | cd codelabs/intro-to-webgl
27 | npm start
28 | ```
29 |
30 | and then open your browser at [`localhost:8080`](http://localhost:8080/).
31 |
32 | ## Setup
33 |
34 | Assuming you have Git and Node installed:
35 |
36 | ### Clone the repository
37 |
38 | ```
39 | git clone git@github.com:olange/learning-webgl.git
40 | cd learning-webgl
41 | ```
42 |
43 | ### Download the project dependencies
44 |
45 | ```
46 | cd codelabs/intro-to-webgl
47 | npm install
48 | ````
49 |
--------------------------------------------------------------------------------
/codelabs/intro-to-webgl/assets/textures/earth_atmos_2048.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/olange/learning-webgl/5d701dbc0788d042183642830fb4adb6f3a820ac/codelabs/intro-to-webgl/assets/textures/earth_atmos_2048.jpg
--------------------------------------------------------------------------------
/codelabs/intro-to-webgl/assets/textures/land_ocean_ice_cloud_2048.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/olange/learning-webgl/5d701dbc0788d042183642830fb4adb6f3a820ac/codelabs/intro-to-webgl/assets/textures/land_ocean_ice_cloud_2048.jpg
--------------------------------------------------------------------------------
/codelabs/intro-to-webgl/assets/textures/moon_1024.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/olange/learning-webgl/5d701dbc0788d042183642830fb4adb6f3a820ac/codelabs/intro-to-webgl/assets/textures/moon_1024.jpg
--------------------------------------------------------------------------------
/codelabs/intro-to-webgl/config/prpl-server.json:
--------------------------------------------------------------------------------
1 | {
2 | "entrypoint": "index.html",
3 | "builds": []
4 | }
--------------------------------------------------------------------------------
/codelabs/intro-to-webgl/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | My first three.js app
6 |
17 |
18 |
19 |
20 |
21 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/codelabs/intro-to-webgl/index.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | import {
4 | WebGLRenderer,
5 | Scene, PerspectiveCamera,
6 | Geometry, BoxGeometry, SphereGeometry,
7 | Mesh, MeshNormalMaterial, MeshPhongMaterial,
8 | Line, LineDashedMaterial,
9 | AmbientLight, TextureLoader,
10 | Vector3
11 | } from "./node_modules/three/build/three.module.js";
12 |
13 | import OrbitControls from "./node_modules/orbit-controls-es6/src/index.js";
14 |
15 | const container = document.getElementById( "canvas");
16 | const clientWidth = container.clientWidth;
17 | const clientHeight = container.clientHeight;
18 |
19 | const scene = new Scene();
20 | const aspect = clientWidth / clientHeight;
21 | const camera = new PerspectiveCamera( 75, aspect, 0.1, 1000);
22 | const renderer = new WebGLRenderer( { antialias: true });
23 |
24 | const canvas = renderer.domElement;
25 | renderer.setSize( clientWidth, clientHeight);
26 | container.appendChild( canvas);
27 |
28 | const light = new AmbientLight( 0xFFFFFF); // soft white light
29 | scene.add( light);
30 |
31 | const boxGeometry = new BoxGeometry( 1, 1, 1);
32 | const sphereGeometry = new SphereGeometry( 1, 60, 36);
33 |
34 | const loader = new TextureLoader();
35 | const earthTexture = loader.load( "assets/textures/land_ocean_ice_cloud_2048.jpg");
36 | const normalMaterial = new MeshNormalMaterial();
37 | const earthMaterial = new MeshPhongMaterial( {
38 | color: 0xFFFFFF,
39 | specular: 0x333333,
40 | shininess: 15.0,
41 | map: earthTexture
42 | });
43 |
44 | const box1 = new Mesh( boxGeometry, normalMaterial);
45 | const box2 = new Mesh( boxGeometry, normalMaterial);
46 | const box3 = new Mesh( boxGeometry, normalMaterial);
47 | const sphere = new Mesh( sphereGeometry, earthMaterial)
48 | sphere.rotation.x = Math.PI / 2.0;
49 | scene.add( box1);
50 | scene.add( box2);
51 | scene.add( box3);
52 | scene.add( sphere);
53 |
54 | const lineMaterial = new LineDashedMaterial({ color: 0x3399CC, dashSize: 0.5, gapSize: 0.25, scale: 2.0 });
55 | const lineGeometry = new Geometry();
56 | lineGeometry.vertices.push( new Vector3( -5, 0, 0));
57 | lineGeometry.vertices.push( new Vector3( 0, 5, 0));
58 | lineGeometry.vertices.push( new Vector3( 5, 0, 0));
59 | lineGeometry.vertices.push( new Vector3( 0, -5, 0));
60 | lineGeometry.vertices.push( new Vector3( -5, 0, 0));
61 | const line = new Line( lineGeometry, lineMaterial);
62 | line.computeLineDistances();
63 | scene.add( line);
64 |
65 | camera.position.set( 0, -7, 2);
66 | camera.lookAt( new Vector3( 0, -5, 0));
67 |
68 | const controls = new OrbitControls( camera, canvas);
69 | controls.enabled = true;
70 | controls.maxDistance = 1000;
71 | controls.minDistance = 0;
72 | controls.enableDamping = true
73 | controls.dampingFactor = 0.25
74 | controls.enableZoom = true;
75 |
76 | function update( time) {
77 | box1.rotation.x = box2.rotation.x = box3.rotation.x += 0.1;
78 | box1.rotation.y = box2.rotation.y = box3.rotation.y += 0.1;
79 | sphere.rotation.y += 0.025;
80 | box1.position.x = 2.5 * Math.cos( time / 1500.0);
81 | box1.position.y = 2.5 * Math.sin( time / 1500.0);
82 | box2.position.x = 2.5 * Math.cos( time * 0.66 * Math.PI / 1500.0);
83 | box2.position.y = 2.5 * Math.sin( time * 0.66 * Math.PI / 1500.0);
84 | box3.position.x = 2.5 * Math.cos( time * 1.33 * Math.PI / 1500.0);
85 | box3.position.y = 2.5 * Math.sin( time * 1.33 * Math.PI / 1500.0);
86 | }
87 |
88 | let lasttime = undefined;
89 | const stepduration = 1; // ms
90 |
91 | function render( time) {
92 | window.requestAnimationFrame( render);
93 | if( typeof time !== "undefined") {
94 | if( typeof lasttime === "undefined" ||( time - lasttime > stepduration)) {
95 | lasttime = time;
96 | update( time);
97 | renderer.render( scene, camera);
98 | }
99 | }
100 | };
101 |
102 | render();
103 |
--------------------------------------------------------------------------------
/codelabs/intro-to-webgl/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "intro-to-webgl",
3 | "version": "1.0.0",
4 | "lockfileVersion": 2,
5 | "requires": true,
6 | "packages": {
7 | "": {
8 | "name": "intro-to-webgl",
9 | "version": "1.0.0",
10 | "license": "CC-BY-SA-4.0",
11 | "dependencies": {
12 | "orbit-controls-es6": "^2.0.1",
13 | "three": "^0.114.0"
14 | },
15 | "devDependencies": {
16 | "prpl-server": "^1.2.0"
17 | }
18 | },
19 | "node_modules/@types/body-parser": {
20 | "version": "1.19.0",
21 | "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.0.tgz",
22 | "integrity": "sha512-W98JrE0j2K78swW4ukqMleo8R7h/pFETjM2DQ90MF6XK2i4LO4W3gQ71Lt4w3bfm2EvVSyWHplECvB5sK22yFQ==",
23 | "dev": true,
24 | "dependencies": {
25 | "@types/connect": "*",
26 | "@types/node": "*"
27 | }
28 | },
29 | "node_modules/@types/compression": {
30 | "version": "0.0.36",
31 | "resolved": "https://registry.npmjs.org/@types/compression/-/compression-0.0.36.tgz",
32 | "integrity": "sha512-B66iZCIcD2eB2F8e8YDIVtCUKgfiseOR5YOIbmMN2tM57Wu55j1xSdxdSw78aVzsPmbZ6G+hINc+1xe1tt4NBg==",
33 | "dev": true,
34 | "dependencies": {
35 | "@types/express": "*"
36 | }
37 | },
38 | "node_modules/@types/connect": {
39 | "version": "3.4.33",
40 | "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.33.tgz",
41 | "integrity": "sha512-2+FrkXY4zllzTNfJth7jOqEHC+enpLeGslEhpnTAkg21GkRrWV4SsAtqchtT4YS9/nODBU2/ZfsBY2X4J/dX7A==",
42 | "dev": true,
43 | "dependencies": {
44 | "@types/node": "*"
45 | }
46 | },
47 | "node_modules/@types/express": {
48 | "version": "4.17.3",
49 | "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.3.tgz",
50 | "integrity": "sha512-I8cGRJj3pyOLs/HndoP+25vOqhqWkAZsWMEmq1qXy/b/M3ppufecUwaK2/TVDVxcV61/iSdhykUjQQ2DLSrTdg==",
51 | "dev": true,
52 | "dependencies": {
53 | "@types/body-parser": "*",
54 | "@types/express-serve-static-core": "*",
55 | "@types/serve-static": "*"
56 | }
57 | },
58 | "node_modules/@types/express-serve-static-core": {
59 | "version": "4.17.2",
60 | "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.2.tgz",
61 | "integrity": "sha512-El9yMpctM6tORDAiBwZVLMcxoTMcqqRO9dVyYcn7ycLWbvR8klrDn8CAOwRfZujZtWD7yS/mshTdz43jMOejbg==",
62 | "dev": true,
63 | "dependencies": {
64 | "@types/node": "*",
65 | "@types/range-parser": "*"
66 | }
67 | },
68 | "node_modules/@types/http-errors": {
69 | "version": "1.6.3",
70 | "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-1.6.3.tgz",
71 | "integrity": "sha512-4KCE/agIcoQ9bIfa4sBxbZdnORzRjIw8JNQPLfqoNv7wQl/8f8mRbW68Q8wBsQFoJkPUHGlQYZ9sqi5WpfGSEQ==",
72 | "dev": true
73 | },
74 | "node_modules/@types/mime": {
75 | "version": "2.0.1",
76 | "resolved": "https://registry.npmjs.org/@types/mime/-/mime-2.0.1.tgz",
77 | "integrity": "sha512-FwI9gX75FgVBJ7ywgnq/P7tw+/o1GUbtP0KzbtusLigAOgIgNISRK0ZPl4qertvXSIE8YbsVJueQ90cDt9YYyw==",
78 | "dev": true
79 | },
80 | "node_modules/@types/node": {
81 | "version": "8.10.59",
82 | "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.59.tgz",
83 | "integrity": "sha512-8RkBivJrDCyPpBXhVZcjh7cQxVBSmRk9QM7hOketZzp6Tg79c0N8kkpAIito9bnJ3HCVCHVYz+KHTEbfQNfeVQ==",
84 | "dev": true
85 | },
86 | "node_modules/@types/range-parser": {
87 | "version": "1.2.3",
88 | "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.3.tgz",
89 | "integrity": "sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA==",
90 | "dev": true
91 | },
92 | "node_modules/@types/send": {
93 | "version": "0.14.5",
94 | "resolved": "https://registry.npmjs.org/@types/send/-/send-0.14.5.tgz",
95 | "integrity": "sha512-0mwoiK3DXXBu0GIfo+jBv4Wo5s1AcsxdpdwNUtflKm99VEMvmBPJ+/NBNRZy2R5JEYfWL/u4nAHuTUTA3wFecQ==",
96 | "dev": true,
97 | "dependencies": {
98 | "@types/mime": "*",
99 | "@types/node": "*"
100 | }
101 | },
102 | "node_modules/@types/serve-static": {
103 | "version": "1.13.3",
104 | "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.3.tgz",
105 | "integrity": "sha512-oprSwp094zOglVrXdlo/4bAHtKTAxX6VT8FOZlBKrmyLbNvE1zxZyJ6yikMVtHIvwP45+ZQGJn+FdXGKTozq0g==",
106 | "dev": true,
107 | "dependencies": {
108 | "@types/express-serve-static-core": "*",
109 | "@types/mime": "*"
110 | }
111 | },
112 | "node_modules/@types/statuses": {
113 | "version": "1.5.0",
114 | "resolved": "https://registry.npmjs.org/@types/statuses/-/statuses-1.5.0.tgz",
115 | "integrity": "sha512-4zJN5gJH+Km6hA36z8MnOKas6EU0qwxItTXNijYDPuZUsSk4EpIAB56fwnxZIhi3tHx42J7wqNdQTqt49Ar9FQ==",
116 | "dev": true
117 | },
118 | "node_modules/@types/ua-parser-js": {
119 | "version": "0.7.33",
120 | "resolved": "https://registry.npmjs.org/@types/ua-parser-js/-/ua-parser-js-0.7.33.tgz",
121 | "integrity": "sha512-ngUKcHnytUodUCL7C6EZ+lVXUjTMQb+9p/e1JjV5tN9TVzS98lHozWEFRPY1QcCdwFeMsmVWfZ3DPPT/udCyIw==",
122 | "dev": true
123 | },
124 | "node_modules/@types/valid-url": {
125 | "version": "1.0.2",
126 | "resolved": "https://registry.npmjs.org/@types/valid-url/-/valid-url-1.0.2.tgz",
127 | "integrity": "sha1-YPpDXOJL/VuhB7jSqAeWrq86j0U=",
128 | "dev": true
129 | },
130 | "node_modules/accepts": {
131 | "version": "1.3.7",
132 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz",
133 | "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==",
134 | "dev": true,
135 | "dependencies": {
136 | "mime-types": "~2.1.24",
137 | "negotiator": "0.6.2"
138 | },
139 | "engines": {
140 | "node": ">= 0.6"
141 | }
142 | },
143 | "node_modules/ajv": {
144 | "version": "6.12.0",
145 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.0.tgz",
146 | "integrity": "sha512-D6gFiFA0RRLyUbvijN74DWAjXSFxWKaWP7mldxkVhyhAV3+SWA9HEJPHQ2c9soIeTFJqcSdFDGFgdqs1iUU2Hw==",
147 | "dev": true,
148 | "dependencies": {
149 | "fast-deep-equal": "^3.1.1",
150 | "fast-json-stable-stringify": "^2.0.0",
151 | "json-schema-traverse": "^0.4.1",
152 | "uri-js": "^4.2.2"
153 | }
154 | },
155 | "node_modules/ansi-escape-sequences": {
156 | "version": "4.1.0",
157 | "resolved": "https://registry.npmjs.org/ansi-escape-sequences/-/ansi-escape-sequences-4.1.0.tgz",
158 | "integrity": "sha512-dzW9kHxH011uBsidTXd14JXgzye/YLb2LzeKZ4bsgl/Knwx8AtbSFkkGxagdNOoh0DlqHCmfiEjWKBaqjOanVw==",
159 | "dev": true,
160 | "dependencies": {
161 | "array-back": "^3.0.1"
162 | },
163 | "engines": {
164 | "node": ">=8.0.0"
165 | }
166 | },
167 | "node_modules/ansi-styles": {
168 | "version": "3.2.1",
169 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
170 | "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
171 | "dev": true,
172 | "dependencies": {
173 | "color-convert": "^1.9.0"
174 | },
175 | "engines": {
176 | "node": ">=4"
177 | }
178 | },
179 | "node_modules/array-back": {
180 | "version": "3.1.0",
181 | "resolved": "https://registry.npmjs.org/array-back/-/array-back-3.1.0.tgz",
182 | "integrity": "sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==",
183 | "dev": true,
184 | "engines": {
185 | "node": ">=6"
186 | }
187 | },
188 | "node_modules/array-flatten": {
189 | "version": "1.1.1",
190 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
191 | "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=",
192 | "dev": true
193 | },
194 | "node_modules/asn1": {
195 | "version": "0.2.4",
196 | "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz",
197 | "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==",
198 | "dev": true,
199 | "dependencies": {
200 | "safer-buffer": "~2.1.0"
201 | }
202 | },
203 | "node_modules/assert-plus": {
204 | "version": "1.0.0",
205 | "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
206 | "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
207 | "dev": true,
208 | "engines": {
209 | "node": ">=0.8"
210 | }
211 | },
212 | "node_modules/asynckit": {
213 | "version": "0.4.0",
214 | "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
215 | "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=",
216 | "dev": true
217 | },
218 | "node_modules/aws-sign2": {
219 | "version": "0.7.0",
220 | "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
221 | "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=",
222 | "dev": true,
223 | "engines": {
224 | "node": "*"
225 | }
226 | },
227 | "node_modules/aws4": {
228 | "version": "1.9.1",
229 | "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.9.1.tgz",
230 | "integrity": "sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug==",
231 | "dev": true
232 | },
233 | "node_modules/bcrypt-pbkdf": {
234 | "version": "1.0.2",
235 | "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
236 | "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=",
237 | "dev": true,
238 | "dependencies": {
239 | "tweetnacl": "^0.14.3"
240 | }
241 | },
242 | "node_modules/body-parser": {
243 | "version": "1.19.0",
244 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz",
245 | "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==",
246 | "dev": true,
247 | "dependencies": {
248 | "bytes": "3.1.0",
249 | "content-type": "~1.0.4",
250 | "debug": "2.6.9",
251 | "depd": "~1.1.2",
252 | "http-errors": "1.7.2",
253 | "iconv-lite": "0.4.24",
254 | "on-finished": "~2.3.0",
255 | "qs": "6.7.0",
256 | "raw-body": "2.4.0",
257 | "type-is": "~1.6.17"
258 | },
259 | "engines": {
260 | "node": ">= 0.8"
261 | }
262 | },
263 | "node_modules/body-parser/node_modules/bytes": {
264 | "version": "3.1.0",
265 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz",
266 | "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==",
267 | "dev": true,
268 | "engines": {
269 | "node": ">= 0.8"
270 | }
271 | },
272 | "node_modules/body-parser/node_modules/http-errors": {
273 | "version": "1.7.2",
274 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz",
275 | "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==",
276 | "dev": true,
277 | "dependencies": {
278 | "depd": "~1.1.2",
279 | "inherits": "2.0.3",
280 | "setprototypeof": "1.1.1",
281 | "statuses": ">= 1.5.0 < 2",
282 | "toidentifier": "1.0.0"
283 | },
284 | "engines": {
285 | "node": ">= 0.6"
286 | }
287 | },
288 | "node_modules/browser-capabilities": {
289 | "version": "1.1.4",
290 | "resolved": "https://registry.npmjs.org/browser-capabilities/-/browser-capabilities-1.1.4.tgz",
291 | "integrity": "sha512-BezMQhbQklxjRQpZZQ8tnbzEo6AldUwMh8/PeWt5/CTBSwByQRXZEAK2fbnEahQ4poeeaI0suAYRq25A1YGOmw==",
292 | "dev": true,
293 | "dependencies": {
294 | "@types/ua-parser-js": "^0.7.31",
295 | "ua-parser-js": "^0.7.15"
296 | },
297 | "engines": {
298 | "node": ">=8.0"
299 | }
300 | },
301 | "node_modules/bytes": {
302 | "version": "3.0.0",
303 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz",
304 | "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=",
305 | "dev": true,
306 | "engines": {
307 | "node": ">= 0.8"
308 | }
309 | },
310 | "node_modules/caseless": {
311 | "version": "0.12.0",
312 | "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
313 | "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=",
314 | "dev": true
315 | },
316 | "node_modules/chalk": {
317 | "version": "2.4.2",
318 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
319 | "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
320 | "dev": true,
321 | "dependencies": {
322 | "ansi-styles": "^3.2.1",
323 | "escape-string-regexp": "^1.0.5",
324 | "supports-color": "^5.3.0"
325 | },
326 | "engines": {
327 | "node": ">=4"
328 | }
329 | },
330 | "node_modules/color-convert": {
331 | "version": "1.9.3",
332 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
333 | "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
334 | "dev": true,
335 | "dependencies": {
336 | "color-name": "1.1.3"
337 | }
338 | },
339 | "node_modules/color-name": {
340 | "version": "1.1.3",
341 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
342 | "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
343 | "dev": true
344 | },
345 | "node_modules/combined-stream": {
346 | "version": "1.0.8",
347 | "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
348 | "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
349 | "dev": true,
350 | "dependencies": {
351 | "delayed-stream": "~1.0.0"
352 | },
353 | "engines": {
354 | "node": ">= 0.8"
355 | }
356 | },
357 | "node_modules/command-line-args": {
358 | "version": "5.1.1",
359 | "resolved": "https://registry.npmjs.org/command-line-args/-/command-line-args-5.1.1.tgz",
360 | "integrity": "sha512-hL/eG8lrll1Qy1ezvkant+trihbGnaKaeEjj6Scyr3DN+RC7iQ5Rz84IeLERfAWDGo0HBSNAakczwgCilDXnWg==",
361 | "dev": true,
362 | "dependencies": {
363 | "array-back": "^3.0.1",
364 | "find-replace": "^3.0.0",
365 | "lodash.camelcase": "^4.3.0",
366 | "typical": "^4.0.0"
367 | },
368 | "engines": {
369 | "node": ">=4.0.0"
370 | }
371 | },
372 | "node_modules/command-line-usage": {
373 | "version": "5.0.5",
374 | "resolved": "https://registry.npmjs.org/command-line-usage/-/command-line-usage-5.0.5.tgz",
375 | "integrity": "sha512-d8NrGylA5oCXSbGoKz05FkehDAzSmIm4K03S5VDh4d5lZAtTWfc3D1RuETtuQCn8129nYfJfDdF7P/lwcz1BlA==",
376 | "dev": true,
377 | "dependencies": {
378 | "array-back": "^2.0.0",
379 | "chalk": "^2.4.1",
380 | "table-layout": "^0.4.3",
381 | "typical": "^2.6.1"
382 | },
383 | "engines": {
384 | "node": ">=4.0.0"
385 | }
386 | },
387 | "node_modules/command-line-usage/node_modules/array-back": {
388 | "version": "2.0.0",
389 | "resolved": "https://registry.npmjs.org/array-back/-/array-back-2.0.0.tgz",
390 | "integrity": "sha512-eJv4pLLufP3g5kcZry0j6WXpIbzYw9GUB4mVJZno9wfwiBxbizTnHCw3VJb07cBihbFX48Y7oSrW9y+gt4glyw==",
391 | "dev": true,
392 | "dependencies": {
393 | "typical": "^2.6.1"
394 | },
395 | "engines": {
396 | "node": ">=4"
397 | }
398 | },
399 | "node_modules/command-line-usage/node_modules/typical": {
400 | "version": "2.6.1",
401 | "resolved": "https://registry.npmjs.org/typical/-/typical-2.6.1.tgz",
402 | "integrity": "sha1-XAgOXWYcu+OCWdLnCjxyU+hziB0=",
403 | "dev": true
404 | },
405 | "node_modules/compressible": {
406 | "version": "2.0.18",
407 | "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz",
408 | "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==",
409 | "dev": true,
410 | "dependencies": {
411 | "mime-db": ">= 1.43.0 < 2"
412 | },
413 | "engines": {
414 | "node": ">= 0.6"
415 | }
416 | },
417 | "node_modules/compression": {
418 | "version": "1.7.4",
419 | "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz",
420 | "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==",
421 | "dev": true,
422 | "dependencies": {
423 | "accepts": "~1.3.5",
424 | "bytes": "3.0.0",
425 | "compressible": "~2.0.16",
426 | "debug": "2.6.9",
427 | "on-headers": "~1.0.2",
428 | "safe-buffer": "5.1.2",
429 | "vary": "~1.1.2"
430 | },
431 | "engines": {
432 | "node": ">= 0.8.0"
433 | }
434 | },
435 | "node_modules/content-disposition": {
436 | "version": "0.5.3",
437 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz",
438 | "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==",
439 | "dev": true,
440 | "dependencies": {
441 | "safe-buffer": "5.1.2"
442 | },
443 | "engines": {
444 | "node": ">= 0.6"
445 | }
446 | },
447 | "node_modules/content-type": {
448 | "version": "1.0.4",
449 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
450 | "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==",
451 | "dev": true,
452 | "engines": {
453 | "node": ">= 0.6"
454 | }
455 | },
456 | "node_modules/cookie": {
457 | "version": "0.4.0",
458 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz",
459 | "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==",
460 | "dev": true,
461 | "engines": {
462 | "node": ">= 0.6"
463 | }
464 | },
465 | "node_modules/cookie-signature": {
466 | "version": "1.0.6",
467 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
468 | "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=",
469 | "dev": true
470 | },
471 | "node_modules/core-util-is": {
472 | "version": "1.0.2",
473 | "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
474 | "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
475 | "dev": true
476 | },
477 | "node_modules/dashdash": {
478 | "version": "1.14.1",
479 | "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
480 | "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
481 | "dev": true,
482 | "dependencies": {
483 | "assert-plus": "^1.0.0"
484 | },
485 | "engines": {
486 | "node": ">=0.10"
487 | }
488 | },
489 | "node_modules/debug": {
490 | "version": "2.6.9",
491 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
492 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
493 | "dev": true,
494 | "dependencies": {
495 | "ms": "2.0.0"
496 | }
497 | },
498 | "node_modules/deep-extend": {
499 | "version": "0.6.0",
500 | "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
501 | "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==",
502 | "dev": true,
503 | "engines": {
504 | "node": ">=4.0.0"
505 | }
506 | },
507 | "node_modules/delayed-stream": {
508 | "version": "1.0.0",
509 | "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
510 | "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
511 | "dev": true,
512 | "engines": {
513 | "node": ">=0.4.0"
514 | }
515 | },
516 | "node_modules/depd": {
517 | "version": "1.1.2",
518 | "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
519 | "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=",
520 | "dev": true,
521 | "engines": {
522 | "node": ">= 0.6"
523 | }
524 | },
525 | "node_modules/destroy": {
526 | "version": "1.0.4",
527 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
528 | "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=",
529 | "dev": true
530 | },
531 | "node_modules/ecc-jsbn": {
532 | "version": "0.1.2",
533 | "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
534 | "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=",
535 | "dev": true,
536 | "dependencies": {
537 | "jsbn": "~0.1.0",
538 | "safer-buffer": "^2.1.0"
539 | }
540 | },
541 | "node_modules/ee-first": {
542 | "version": "1.1.1",
543 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
544 | "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=",
545 | "dev": true
546 | },
547 | "node_modules/encodeurl": {
548 | "version": "1.0.2",
549 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
550 | "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=",
551 | "dev": true,
552 | "engines": {
553 | "node": ">= 0.8"
554 | }
555 | },
556 | "node_modules/escape-html": {
557 | "version": "1.0.3",
558 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
559 | "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=",
560 | "dev": true
561 | },
562 | "node_modules/escape-string-regexp": {
563 | "version": "1.0.5",
564 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
565 | "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
566 | "dev": true,
567 | "engines": {
568 | "node": ">=0.8.0"
569 | }
570 | },
571 | "node_modules/etag": {
572 | "version": "1.8.1",
573 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
574 | "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=",
575 | "dev": true,
576 | "engines": {
577 | "node": ">= 0.6"
578 | }
579 | },
580 | "node_modules/express": {
581 | "version": "4.17.1",
582 | "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz",
583 | "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==",
584 | "dev": true,
585 | "dependencies": {
586 | "accepts": "~1.3.7",
587 | "array-flatten": "1.1.1",
588 | "body-parser": "1.19.0",
589 | "content-disposition": "0.5.3",
590 | "content-type": "~1.0.4",
591 | "cookie": "0.4.0",
592 | "cookie-signature": "1.0.6",
593 | "debug": "2.6.9",
594 | "depd": "~1.1.2",
595 | "encodeurl": "~1.0.2",
596 | "escape-html": "~1.0.3",
597 | "etag": "~1.8.1",
598 | "finalhandler": "~1.1.2",
599 | "fresh": "0.5.2",
600 | "merge-descriptors": "1.0.1",
601 | "methods": "~1.1.2",
602 | "on-finished": "~2.3.0",
603 | "parseurl": "~1.3.3",
604 | "path-to-regexp": "0.1.7",
605 | "proxy-addr": "~2.0.5",
606 | "qs": "6.7.0",
607 | "range-parser": "~1.2.1",
608 | "safe-buffer": "5.1.2",
609 | "send": "0.17.1",
610 | "serve-static": "1.14.1",
611 | "setprototypeof": "1.1.1",
612 | "statuses": "~1.5.0",
613 | "type-is": "~1.6.18",
614 | "utils-merge": "1.0.1",
615 | "vary": "~1.1.2"
616 | },
617 | "engines": {
618 | "node": ">= 0.10.0"
619 | }
620 | },
621 | "node_modules/express/node_modules/ms": {
622 | "version": "2.1.1",
623 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
624 | "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==",
625 | "dev": true
626 | },
627 | "node_modules/express/node_modules/send": {
628 | "version": "0.17.1",
629 | "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz",
630 | "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==",
631 | "dev": true,
632 | "dependencies": {
633 | "debug": "2.6.9",
634 | "depd": "~1.1.2",
635 | "destroy": "~1.0.4",
636 | "encodeurl": "~1.0.2",
637 | "escape-html": "~1.0.3",
638 | "etag": "~1.8.1",
639 | "fresh": "0.5.2",
640 | "http-errors": "~1.7.2",
641 | "mime": "1.6.0",
642 | "ms": "2.1.1",
643 | "on-finished": "~2.3.0",
644 | "range-parser": "~1.2.1",
645 | "statuses": "~1.5.0"
646 | },
647 | "engines": {
648 | "node": ">= 0.8.0"
649 | }
650 | },
651 | "node_modules/extend": {
652 | "version": "3.0.2",
653 | "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
654 | "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==",
655 | "dev": true
656 | },
657 | "node_modules/extsprintf": {
658 | "version": "1.3.0",
659 | "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
660 | "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=",
661 | "dev": true,
662 | "engines": [
663 | "node >=0.6.0"
664 | ]
665 | },
666 | "node_modules/fast-deep-equal": {
667 | "version": "3.1.1",
668 | "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz",
669 | "integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA==",
670 | "dev": true
671 | },
672 | "node_modules/fast-json-stable-stringify": {
673 | "version": "2.1.0",
674 | "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
675 | "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
676 | "dev": true
677 | },
678 | "node_modules/finalhandler": {
679 | "version": "1.1.2",
680 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz",
681 | "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==",
682 | "dev": true,
683 | "dependencies": {
684 | "debug": "2.6.9",
685 | "encodeurl": "~1.0.2",
686 | "escape-html": "~1.0.3",
687 | "on-finished": "~2.3.0",
688 | "parseurl": "~1.3.3",
689 | "statuses": "~1.5.0",
690 | "unpipe": "~1.0.0"
691 | },
692 | "engines": {
693 | "node": ">= 0.8"
694 | }
695 | },
696 | "node_modules/find-replace": {
697 | "version": "3.0.0",
698 | "resolved": "https://registry.npmjs.org/find-replace/-/find-replace-3.0.0.tgz",
699 | "integrity": "sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ==",
700 | "dev": true,
701 | "dependencies": {
702 | "array-back": "^3.0.1"
703 | },
704 | "engines": {
705 | "node": ">=4.0.0"
706 | }
707 | },
708 | "node_modules/forever-agent": {
709 | "version": "0.6.1",
710 | "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
711 | "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=",
712 | "dev": true,
713 | "engines": {
714 | "node": "*"
715 | }
716 | },
717 | "node_modules/form-data": {
718 | "version": "2.3.3",
719 | "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz",
720 | "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==",
721 | "dev": true,
722 | "dependencies": {
723 | "asynckit": "^0.4.0",
724 | "combined-stream": "^1.0.6",
725 | "mime-types": "^2.1.12"
726 | },
727 | "engines": {
728 | "node": ">= 0.12"
729 | }
730 | },
731 | "node_modules/forwarded": {
732 | "version": "0.1.2",
733 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz",
734 | "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=",
735 | "dev": true,
736 | "engines": {
737 | "node": ">= 0.6"
738 | }
739 | },
740 | "node_modules/fresh": {
741 | "version": "0.5.2",
742 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
743 | "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=",
744 | "dev": true,
745 | "engines": {
746 | "node": ">= 0.6"
747 | }
748 | },
749 | "node_modules/getpass": {
750 | "version": "0.1.7",
751 | "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
752 | "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
753 | "dev": true,
754 | "dependencies": {
755 | "assert-plus": "^1.0.0"
756 | }
757 | },
758 | "node_modules/har-schema": {
759 | "version": "2.0.0",
760 | "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
761 | "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=",
762 | "dev": true,
763 | "engines": {
764 | "node": ">=4"
765 | }
766 | },
767 | "node_modules/har-validator": {
768 | "version": "5.1.3",
769 | "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz",
770 | "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==",
771 | "deprecated": "this library is no longer supported",
772 | "dev": true,
773 | "dependencies": {
774 | "ajv": "^6.5.5",
775 | "har-schema": "^2.0.0"
776 | },
777 | "engines": {
778 | "node": ">=6"
779 | }
780 | },
781 | "node_modules/has-flag": {
782 | "version": "3.0.0",
783 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
784 | "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
785 | "dev": true,
786 | "engines": {
787 | "node": ">=4"
788 | }
789 | },
790 | "node_modules/http-errors": {
791 | "version": "1.7.3",
792 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.3.tgz",
793 | "integrity": "sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw==",
794 | "dev": true,
795 | "dependencies": {
796 | "depd": "~1.1.2",
797 | "inherits": "2.0.4",
798 | "setprototypeof": "1.1.1",
799 | "statuses": ">= 1.5.0 < 2",
800 | "toidentifier": "1.0.0"
801 | },
802 | "engines": {
803 | "node": ">= 0.6"
804 | }
805 | },
806 | "node_modules/http-errors/node_modules/inherits": {
807 | "version": "2.0.4",
808 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
809 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
810 | "dev": true
811 | },
812 | "node_modules/http-signature": {
813 | "version": "1.2.0",
814 | "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
815 | "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
816 | "dev": true,
817 | "dependencies": {
818 | "assert-plus": "^1.0.0",
819 | "jsprim": "^1.2.2",
820 | "sshpk": "^1.7.0"
821 | },
822 | "engines": {
823 | "node": ">=0.8",
824 | "npm": ">=1.3.7"
825 | }
826 | },
827 | "node_modules/iconv-lite": {
828 | "version": "0.4.24",
829 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
830 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
831 | "dev": true,
832 | "dependencies": {
833 | "safer-buffer": ">= 2.1.2 < 3"
834 | },
835 | "engines": {
836 | "node": ">=0.10.0"
837 | }
838 | },
839 | "node_modules/inherits": {
840 | "version": "2.0.3",
841 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
842 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
843 | "dev": true
844 | },
845 | "node_modules/ipaddr.js": {
846 | "version": "1.9.1",
847 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
848 | "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
849 | "dev": true,
850 | "engines": {
851 | "node": ">= 0.10"
852 | }
853 | },
854 | "node_modules/is-typedarray": {
855 | "version": "1.0.0",
856 | "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
857 | "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=",
858 | "dev": true
859 | },
860 | "node_modules/isstream": {
861 | "version": "0.1.2",
862 | "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
863 | "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=",
864 | "dev": true
865 | },
866 | "node_modules/jsbn": {
867 | "version": "0.1.1",
868 | "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
869 | "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
870 | "dev": true
871 | },
872 | "node_modules/json-schema": {
873 | "version": "0.2.3",
874 | "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
875 | "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=",
876 | "dev": true
877 | },
878 | "node_modules/json-schema-traverse": {
879 | "version": "0.4.1",
880 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
881 | "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
882 | "dev": true
883 | },
884 | "node_modules/json-stringify-safe": {
885 | "version": "5.0.1",
886 | "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
887 | "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=",
888 | "dev": true
889 | },
890 | "node_modules/jsprim": {
891 | "version": "1.4.1",
892 | "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
893 | "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=",
894 | "dev": true,
895 | "engines": [
896 | "node >=0.6.0"
897 | ],
898 | "dependencies": {
899 | "assert-plus": "1.0.0",
900 | "extsprintf": "1.3.0",
901 | "json-schema": "0.2.3",
902 | "verror": "1.10.0"
903 | }
904 | },
905 | "node_modules/lodash.camelcase": {
906 | "version": "4.3.0",
907 | "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz",
908 | "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=",
909 | "dev": true
910 | },
911 | "node_modules/lodash.padend": {
912 | "version": "4.6.1",
913 | "resolved": "https://registry.npmjs.org/lodash.padend/-/lodash.padend-4.6.1.tgz",
914 | "integrity": "sha1-U8y6BH0G4VjTEfRdpiX05J5vFm4=",
915 | "dev": true
916 | },
917 | "node_modules/media-typer": {
918 | "version": "0.3.0",
919 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
920 | "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=",
921 | "dev": true,
922 | "engines": {
923 | "node": ">= 0.6"
924 | }
925 | },
926 | "node_modules/merge-descriptors": {
927 | "version": "1.0.1",
928 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
929 | "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=",
930 | "dev": true
931 | },
932 | "node_modules/methods": {
933 | "version": "1.1.2",
934 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
935 | "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=",
936 | "dev": true,
937 | "engines": {
938 | "node": ">= 0.6"
939 | }
940 | },
941 | "node_modules/mime": {
942 | "version": "1.6.0",
943 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
944 | "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
945 | "dev": true,
946 | "bin": {
947 | "mime": "cli.js"
948 | },
949 | "engines": {
950 | "node": ">=4"
951 | }
952 | },
953 | "node_modules/mime-db": {
954 | "version": "1.43.0",
955 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.43.0.tgz",
956 | "integrity": "sha512-+5dsGEEovYbT8UY9yD7eE4XTc4UwJ1jBYlgaQQF38ENsKR3wj/8q8RFZrF9WIZpB2V1ArTVFUva8sAul1NzRzQ==",
957 | "dev": true,
958 | "engines": {
959 | "node": ">= 0.6"
960 | }
961 | },
962 | "node_modules/mime-types": {
963 | "version": "2.1.26",
964 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.26.tgz",
965 | "integrity": "sha512-01paPWYgLrkqAyrlDorC1uDwl2p3qZT7yl806vW7DvDoxwXi46jsjFbg+WdwotBIk6/MbEhO/dh5aZ5sNj/dWQ==",
966 | "dev": true,
967 | "dependencies": {
968 | "mime-db": "1.43.0"
969 | },
970 | "engines": {
971 | "node": ">= 0.6"
972 | }
973 | },
974 | "node_modules/ms": {
975 | "version": "2.0.0",
976 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
977 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
978 | "dev": true
979 | },
980 | "node_modules/negotiator": {
981 | "version": "0.6.2",
982 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz",
983 | "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==",
984 | "dev": true,
985 | "engines": {
986 | "node": ">= 0.6"
987 | }
988 | },
989 | "node_modules/oauth-sign": {
990 | "version": "0.9.0",
991 | "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
992 | "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==",
993 | "dev": true,
994 | "engines": {
995 | "node": "*"
996 | }
997 | },
998 | "node_modules/on-finished": {
999 | "version": "2.3.0",
1000 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
1001 | "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
1002 | "dev": true,
1003 | "dependencies": {
1004 | "ee-first": "1.1.1"
1005 | },
1006 | "engines": {
1007 | "node": ">= 0.8"
1008 | }
1009 | },
1010 | "node_modules/on-headers": {
1011 | "version": "1.0.2",
1012 | "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz",
1013 | "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==",
1014 | "dev": true,
1015 | "engines": {
1016 | "node": ">= 0.8"
1017 | }
1018 | },
1019 | "node_modules/orbit-controls-es6": {
1020 | "version": "2.0.1",
1021 | "resolved": "https://registry.npmjs.org/orbit-controls-es6/-/orbit-controls-es6-2.0.1.tgz",
1022 | "integrity": "sha512-Np+XREwlIFl7tSpMSqHuJ20ySonCwCJO+vxyMGmijCJv5+I1SqGQMNfn2fwJC3TVvakXRIxa4ayxJdzeF5dPAA==",
1023 | "peerDependencies": {
1024 | "three": "0.108.0"
1025 | }
1026 | },
1027 | "node_modules/parseurl": {
1028 | "version": "1.3.3",
1029 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
1030 | "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
1031 | "dev": true,
1032 | "engines": {
1033 | "node": ">= 0.8"
1034 | }
1035 | },
1036 | "node_modules/path-to-regexp": {
1037 | "version": "0.1.7",
1038 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
1039 | "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=",
1040 | "dev": true
1041 | },
1042 | "node_modules/performance-now": {
1043 | "version": "2.1.0",
1044 | "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
1045 | "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=",
1046 | "dev": true
1047 | },
1048 | "node_modules/proxy-addr": {
1049 | "version": "2.0.6",
1050 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz",
1051 | "integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==",
1052 | "dev": true,
1053 | "dependencies": {
1054 | "forwarded": "~0.1.2",
1055 | "ipaddr.js": "1.9.1"
1056 | },
1057 | "engines": {
1058 | "node": ">= 0.10"
1059 | }
1060 | },
1061 | "node_modules/prpl-server": {
1062 | "version": "1.4.0",
1063 | "resolved": "https://registry.npmjs.org/prpl-server/-/prpl-server-1.4.0.tgz",
1064 | "integrity": "sha512-nyLjYI00bf5M4O6Cel5uE4AuRh3IzkIPf8jtywta2YIOJJ7yGb5SI1tKdcHDn8LdNc/qn1/6ZudPJdceew1BIg==",
1065 | "deprecated": "prpl-server is deprecated. Please see https://github.com/Polymer/prpl-server#deprecation for details and recommended alternatives.",
1066 | "dev": true,
1067 | "dependencies": {
1068 | "@types/compression": "0.0.36",
1069 | "@types/express": "^4.0.35",
1070 | "@types/http-errors": "^1.6.1",
1071 | "@types/node": "^8.0.47",
1072 | "@types/send": "^0.14.2",
1073 | "@types/statuses": "^1.3.0",
1074 | "@types/valid-url": "^1.0.2",
1075 | "ansi-escape-sequences": "^4.0.0",
1076 | "browser-capabilities": "^1.0.0",
1077 | "command-line-args": "^5.0.2",
1078 | "command-line-usage": "^5.0.4",
1079 | "compression": "^1.6.2",
1080 | "express": "^4.15.2",
1081 | "http-errors": "^1.6.2",
1082 | "rendertron-middleware": "^0.1.1",
1083 | "send": "^0.16.1",
1084 | "statuses": "^1.4.0",
1085 | "tsc-then": "^1.1.0",
1086 | "valid-url": "^1.0.9"
1087 | },
1088 | "bin": {
1089 | "prpl-server": "bin/prpl-server"
1090 | },
1091 | "engines": {
1092 | "node": ">=6.0"
1093 | }
1094 | },
1095 | "node_modules/psl": {
1096 | "version": "1.7.0",
1097 | "resolved": "https://registry.npmjs.org/psl/-/psl-1.7.0.tgz",
1098 | "integrity": "sha512-5NsSEDv8zY70ScRnOTn7bK7eanl2MvFrOrS/R6x+dBt5g1ghnj9Zv90kO8GwT8gxcu2ANyFprnFYB85IogIJOQ==",
1099 | "dev": true
1100 | },
1101 | "node_modules/punycode": {
1102 | "version": "2.1.1",
1103 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
1104 | "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
1105 | "dev": true,
1106 | "engines": {
1107 | "node": ">=6"
1108 | }
1109 | },
1110 | "node_modules/qs": {
1111 | "version": "6.7.0",
1112 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
1113 | "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==",
1114 | "dev": true,
1115 | "engines": {
1116 | "node": ">=0.6"
1117 | }
1118 | },
1119 | "node_modules/range-parser": {
1120 | "version": "1.2.1",
1121 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
1122 | "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
1123 | "dev": true,
1124 | "engines": {
1125 | "node": ">= 0.6"
1126 | }
1127 | },
1128 | "node_modules/raw-body": {
1129 | "version": "2.4.0",
1130 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz",
1131 | "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==",
1132 | "dev": true,
1133 | "dependencies": {
1134 | "bytes": "3.1.0",
1135 | "http-errors": "1.7.2",
1136 | "iconv-lite": "0.4.24",
1137 | "unpipe": "1.0.0"
1138 | },
1139 | "engines": {
1140 | "node": ">= 0.8"
1141 | }
1142 | },
1143 | "node_modules/raw-body/node_modules/bytes": {
1144 | "version": "3.1.0",
1145 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz",
1146 | "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==",
1147 | "dev": true,
1148 | "engines": {
1149 | "node": ">= 0.8"
1150 | }
1151 | },
1152 | "node_modules/raw-body/node_modules/http-errors": {
1153 | "version": "1.7.2",
1154 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz",
1155 | "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==",
1156 | "dev": true,
1157 | "dependencies": {
1158 | "depd": "~1.1.2",
1159 | "inherits": "2.0.3",
1160 | "setprototypeof": "1.1.1",
1161 | "statuses": ">= 1.5.0 < 2",
1162 | "toidentifier": "1.0.0"
1163 | },
1164 | "engines": {
1165 | "node": ">= 0.6"
1166 | }
1167 | },
1168 | "node_modules/reduce-flatten": {
1169 | "version": "1.0.1",
1170 | "resolved": "https://registry.npmjs.org/reduce-flatten/-/reduce-flatten-1.0.1.tgz",
1171 | "integrity": "sha1-JYx479FT3fk8tWEjf2EYTzaW4yc=",
1172 | "dev": true,
1173 | "engines": {
1174 | "node": ">=0.10.0"
1175 | }
1176 | },
1177 | "node_modules/rendertron-middleware": {
1178 | "version": "0.1.5",
1179 | "resolved": "https://registry.npmjs.org/rendertron-middleware/-/rendertron-middleware-0.1.5.tgz",
1180 | "integrity": "sha512-YTwWJ+vP07w0jdpHsKMhM8RQ6q7Xa2AKmZMMIUzFFbqFnAtso6o6nxWEk/S0axLFPEFfrGMxTqewOtM4Cy8KNQ==",
1181 | "dev": true,
1182 | "dependencies": {
1183 | "@types/express": "^4.16.0",
1184 | "request": "^2.87.0"
1185 | },
1186 | "engines": {
1187 | "node": ">=6"
1188 | }
1189 | },
1190 | "node_modules/request": {
1191 | "version": "2.88.2",
1192 | "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz",
1193 | "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==",
1194 | "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142",
1195 | "dev": true,
1196 | "dependencies": {
1197 | "aws-sign2": "~0.7.0",
1198 | "aws4": "^1.8.0",
1199 | "caseless": "~0.12.0",
1200 | "combined-stream": "~1.0.6",
1201 | "extend": "~3.0.2",
1202 | "forever-agent": "~0.6.1",
1203 | "form-data": "~2.3.2",
1204 | "har-validator": "~5.1.3",
1205 | "http-signature": "~1.2.0",
1206 | "is-typedarray": "~1.0.0",
1207 | "isstream": "~0.1.2",
1208 | "json-stringify-safe": "~5.0.1",
1209 | "mime-types": "~2.1.19",
1210 | "oauth-sign": "~0.9.0",
1211 | "performance-now": "^2.1.0",
1212 | "qs": "~6.5.2",
1213 | "safe-buffer": "^5.1.2",
1214 | "tough-cookie": "~2.5.0",
1215 | "tunnel-agent": "^0.6.0",
1216 | "uuid": "^3.3.2"
1217 | },
1218 | "engines": {
1219 | "node": ">= 6"
1220 | }
1221 | },
1222 | "node_modules/request/node_modules/qs": {
1223 | "version": "6.5.2",
1224 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz",
1225 | "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==",
1226 | "dev": true,
1227 | "engines": {
1228 | "node": ">=0.6"
1229 | }
1230 | },
1231 | "node_modules/safe-buffer": {
1232 | "version": "5.1.2",
1233 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
1234 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
1235 | "dev": true
1236 | },
1237 | "node_modules/safer-buffer": {
1238 | "version": "2.1.2",
1239 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
1240 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
1241 | "dev": true
1242 | },
1243 | "node_modules/semver": {
1244 | "version": "5.7.1",
1245 | "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
1246 | "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
1247 | "dev": true,
1248 | "bin": {
1249 | "semver": "bin/semver"
1250 | }
1251 | },
1252 | "node_modules/send": {
1253 | "version": "0.16.2",
1254 | "resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz",
1255 | "integrity": "sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw==",
1256 | "dev": true,
1257 | "dependencies": {
1258 | "debug": "2.6.9",
1259 | "depd": "~1.1.2",
1260 | "destroy": "~1.0.4",
1261 | "encodeurl": "~1.0.2",
1262 | "escape-html": "~1.0.3",
1263 | "etag": "~1.8.1",
1264 | "fresh": "0.5.2",
1265 | "http-errors": "~1.6.2",
1266 | "mime": "1.4.1",
1267 | "ms": "2.0.0",
1268 | "on-finished": "~2.3.0",
1269 | "range-parser": "~1.2.0",
1270 | "statuses": "~1.4.0"
1271 | },
1272 | "engines": {
1273 | "node": ">= 0.8.0"
1274 | }
1275 | },
1276 | "node_modules/send/node_modules/http-errors": {
1277 | "version": "1.6.3",
1278 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz",
1279 | "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=",
1280 | "dev": true,
1281 | "dependencies": {
1282 | "depd": "~1.1.2",
1283 | "inherits": "2.0.3",
1284 | "setprototypeof": "1.1.0",
1285 | "statuses": ">= 1.4.0 < 2"
1286 | },
1287 | "engines": {
1288 | "node": ">= 0.6"
1289 | }
1290 | },
1291 | "node_modules/send/node_modules/mime": {
1292 | "version": "1.4.1",
1293 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz",
1294 | "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==",
1295 | "dev": true,
1296 | "bin": {
1297 | "mime": "cli.js"
1298 | }
1299 | },
1300 | "node_modules/send/node_modules/setprototypeof": {
1301 | "version": "1.1.0",
1302 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz",
1303 | "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==",
1304 | "dev": true
1305 | },
1306 | "node_modules/send/node_modules/statuses": {
1307 | "version": "1.4.0",
1308 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz",
1309 | "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==",
1310 | "dev": true,
1311 | "engines": {
1312 | "node": ">= 0.6"
1313 | }
1314 | },
1315 | "node_modules/serve-static": {
1316 | "version": "1.14.1",
1317 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz",
1318 | "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==",
1319 | "dev": true,
1320 | "dependencies": {
1321 | "encodeurl": "~1.0.2",
1322 | "escape-html": "~1.0.3",
1323 | "parseurl": "~1.3.3",
1324 | "send": "0.17.1"
1325 | },
1326 | "engines": {
1327 | "node": ">= 0.8.0"
1328 | }
1329 | },
1330 | "node_modules/serve-static/node_modules/ms": {
1331 | "version": "2.1.1",
1332 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
1333 | "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==",
1334 | "dev": true
1335 | },
1336 | "node_modules/serve-static/node_modules/send": {
1337 | "version": "0.17.1",
1338 | "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz",
1339 | "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==",
1340 | "dev": true,
1341 | "dependencies": {
1342 | "debug": "2.6.9",
1343 | "depd": "~1.1.2",
1344 | "destroy": "~1.0.4",
1345 | "encodeurl": "~1.0.2",
1346 | "escape-html": "~1.0.3",
1347 | "etag": "~1.8.1",
1348 | "fresh": "0.5.2",
1349 | "http-errors": "~1.7.2",
1350 | "mime": "1.6.0",
1351 | "ms": "2.1.1",
1352 | "on-finished": "~2.3.0",
1353 | "range-parser": "~1.2.1",
1354 | "statuses": "~1.5.0"
1355 | },
1356 | "engines": {
1357 | "node": ">= 0.8.0"
1358 | }
1359 | },
1360 | "node_modules/setprototypeof": {
1361 | "version": "1.1.1",
1362 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz",
1363 | "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==",
1364 | "dev": true
1365 | },
1366 | "node_modules/sshpk": {
1367 | "version": "1.16.1",
1368 | "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz",
1369 | "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==",
1370 | "dev": true,
1371 | "dependencies": {
1372 | "asn1": "~0.2.3",
1373 | "assert-plus": "^1.0.0",
1374 | "bcrypt-pbkdf": "^1.0.0",
1375 | "dashdash": "^1.12.0",
1376 | "ecc-jsbn": "~0.1.1",
1377 | "getpass": "^0.1.1",
1378 | "jsbn": "~0.1.0",
1379 | "safer-buffer": "^2.0.2",
1380 | "tweetnacl": "~0.14.0"
1381 | },
1382 | "bin": {
1383 | "sshpk-conv": "bin/sshpk-conv",
1384 | "sshpk-sign": "bin/sshpk-sign",
1385 | "sshpk-verify": "bin/sshpk-verify"
1386 | },
1387 | "engines": {
1388 | "node": ">=0.10.0"
1389 | }
1390 | },
1391 | "node_modules/statuses": {
1392 | "version": "1.5.0",
1393 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
1394 | "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=",
1395 | "dev": true,
1396 | "engines": {
1397 | "node": ">= 0.6"
1398 | }
1399 | },
1400 | "node_modules/supports-color": {
1401 | "version": "5.5.0",
1402 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
1403 | "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
1404 | "dev": true,
1405 | "dependencies": {
1406 | "has-flag": "^3.0.0"
1407 | },
1408 | "engines": {
1409 | "node": ">=4"
1410 | }
1411 | },
1412 | "node_modules/table-layout": {
1413 | "version": "0.4.5",
1414 | "resolved": "https://registry.npmjs.org/table-layout/-/table-layout-0.4.5.tgz",
1415 | "integrity": "sha512-zTvf0mcggrGeTe/2jJ6ECkJHAQPIYEwDoqsiqBjI24mvRmQbInK5jq33fyypaCBxX08hMkfmdOqj6haT33EqWw==",
1416 | "dev": true,
1417 | "dependencies": {
1418 | "array-back": "^2.0.0",
1419 | "deep-extend": "~0.6.0",
1420 | "lodash.padend": "^4.6.1",
1421 | "typical": "^2.6.1",
1422 | "wordwrapjs": "^3.0.0"
1423 | },
1424 | "engines": {
1425 | "node": ">=4.0.0"
1426 | }
1427 | },
1428 | "node_modules/table-layout/node_modules/array-back": {
1429 | "version": "2.0.0",
1430 | "resolved": "https://registry.npmjs.org/array-back/-/array-back-2.0.0.tgz",
1431 | "integrity": "sha512-eJv4pLLufP3g5kcZry0j6WXpIbzYw9GUB4mVJZno9wfwiBxbizTnHCw3VJb07cBihbFX48Y7oSrW9y+gt4glyw==",
1432 | "dev": true,
1433 | "dependencies": {
1434 | "typical": "^2.6.1"
1435 | },
1436 | "engines": {
1437 | "node": ">=4"
1438 | }
1439 | },
1440 | "node_modules/table-layout/node_modules/typical": {
1441 | "version": "2.6.1",
1442 | "resolved": "https://registry.npmjs.org/typical/-/typical-2.6.1.tgz",
1443 | "integrity": "sha1-XAgOXWYcu+OCWdLnCjxyU+hziB0=",
1444 | "dev": true
1445 | },
1446 | "node_modules/three": {
1447 | "version": "0.114.0",
1448 | "resolved": "https://registry.npmjs.org/three/-/three-0.114.0.tgz",
1449 | "integrity": "sha512-3av45FxJeqYm7Rl02dfGBoqTaf2a934oUB4zMNrN8xjmASoSGeeykYoAr35+UntTdJDY/STw6CY3KuXFBWETig=="
1450 | },
1451 | "node_modules/toidentifier": {
1452 | "version": "1.0.0",
1453 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz",
1454 | "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==",
1455 | "dev": true,
1456 | "engines": {
1457 | "node": ">=0.6"
1458 | }
1459 | },
1460 | "node_modules/tough-cookie": {
1461 | "version": "2.5.0",
1462 | "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz",
1463 | "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==",
1464 | "dev": true,
1465 | "dependencies": {
1466 | "psl": "^1.1.28",
1467 | "punycode": "^2.1.1"
1468 | },
1469 | "engines": {
1470 | "node": ">=0.8"
1471 | }
1472 | },
1473 | "node_modules/tsc-then": {
1474 | "version": "1.1.0",
1475 | "resolved": "https://registry.npmjs.org/tsc-then/-/tsc-then-1.1.0.tgz",
1476 | "integrity": "sha512-830G8SK8tewOxfKVBC5YWqZ2C7wS1D4dh9267ebLxR7Gvh3UuI6aKU5Hxo+L3Kkcy6CuxZp4PMGl066DZ3Hlmw==",
1477 | "dev": true,
1478 | "dependencies": {
1479 | "@types/node": "^8.0.53",
1480 | "semver": "^5.4.1"
1481 | },
1482 | "bin": {
1483 | "tsc-then": "bin/tsc-then.js"
1484 | }
1485 | },
1486 | "node_modules/tunnel-agent": {
1487 | "version": "0.6.0",
1488 | "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
1489 | "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
1490 | "dev": true,
1491 | "dependencies": {
1492 | "safe-buffer": "^5.0.1"
1493 | },
1494 | "engines": {
1495 | "node": "*"
1496 | }
1497 | },
1498 | "node_modules/tweetnacl": {
1499 | "version": "0.14.5",
1500 | "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
1501 | "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=",
1502 | "dev": true
1503 | },
1504 | "node_modules/type-is": {
1505 | "version": "1.6.18",
1506 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
1507 | "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
1508 | "dev": true,
1509 | "dependencies": {
1510 | "media-typer": "0.3.0",
1511 | "mime-types": "~2.1.24"
1512 | },
1513 | "engines": {
1514 | "node": ">= 0.6"
1515 | }
1516 | },
1517 | "node_modules/typical": {
1518 | "version": "4.0.0",
1519 | "resolved": "https://registry.npmjs.org/typical/-/typical-4.0.0.tgz",
1520 | "integrity": "sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw==",
1521 | "dev": true,
1522 | "engines": {
1523 | "node": ">=8"
1524 | }
1525 | },
1526 | "node_modules/ua-parser-js": {
1527 | "version": "0.7.21",
1528 | "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.21.tgz",
1529 | "integrity": "sha512-+O8/qh/Qj8CgC6eYBVBykMrNtp5Gebn4dlGD/kKXVkJNDwyrAwSIqwz8CDf+tsAIWVycKcku6gIXJ0qwx/ZXaQ==",
1530 | "dev": true,
1531 | "engines": {
1532 | "node": "*"
1533 | }
1534 | },
1535 | "node_modules/unpipe": {
1536 | "version": "1.0.0",
1537 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
1538 | "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=",
1539 | "dev": true,
1540 | "engines": {
1541 | "node": ">= 0.8"
1542 | }
1543 | },
1544 | "node_modules/uri-js": {
1545 | "version": "4.2.2",
1546 | "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz",
1547 | "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==",
1548 | "dev": true,
1549 | "dependencies": {
1550 | "punycode": "^2.1.0"
1551 | }
1552 | },
1553 | "node_modules/utils-merge": {
1554 | "version": "1.0.1",
1555 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
1556 | "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=",
1557 | "dev": true,
1558 | "engines": {
1559 | "node": ">= 0.4.0"
1560 | }
1561 | },
1562 | "node_modules/uuid": {
1563 | "version": "3.4.0",
1564 | "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
1565 | "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==",
1566 | "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.",
1567 | "dev": true,
1568 | "bin": {
1569 | "uuid": "bin/uuid"
1570 | }
1571 | },
1572 | "node_modules/valid-url": {
1573 | "version": "1.0.9",
1574 | "resolved": "https://registry.npmjs.org/valid-url/-/valid-url-1.0.9.tgz",
1575 | "integrity": "sha1-HBRHm0DxOXp1eC8RXkCGRHQzogA=",
1576 | "dev": true
1577 | },
1578 | "node_modules/vary": {
1579 | "version": "1.1.2",
1580 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
1581 | "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=",
1582 | "dev": true,
1583 | "engines": {
1584 | "node": ">= 0.8"
1585 | }
1586 | },
1587 | "node_modules/verror": {
1588 | "version": "1.10.0",
1589 | "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
1590 | "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
1591 | "dev": true,
1592 | "engines": [
1593 | "node >=0.6.0"
1594 | ],
1595 | "dependencies": {
1596 | "assert-plus": "^1.0.0",
1597 | "core-util-is": "1.0.2",
1598 | "extsprintf": "^1.2.0"
1599 | }
1600 | },
1601 | "node_modules/wordwrapjs": {
1602 | "version": "3.0.0",
1603 | "resolved": "https://registry.npmjs.org/wordwrapjs/-/wordwrapjs-3.0.0.tgz",
1604 | "integrity": "sha512-mO8XtqyPvykVCsrwj5MlOVWvSnCdT+C+QVbm6blradR7JExAhbkZ7hZ9A+9NUtwzSqrlUo9a67ws0EiILrvRpw==",
1605 | "dev": true,
1606 | "dependencies": {
1607 | "reduce-flatten": "^1.0.1",
1608 | "typical": "^2.6.1"
1609 | },
1610 | "engines": {
1611 | "node": ">=4.0.0"
1612 | }
1613 | },
1614 | "node_modules/wordwrapjs/node_modules/typical": {
1615 | "version": "2.6.1",
1616 | "resolved": "https://registry.npmjs.org/typical/-/typical-2.6.1.tgz",
1617 | "integrity": "sha1-XAgOXWYcu+OCWdLnCjxyU+hziB0=",
1618 | "dev": true
1619 | }
1620 | },
1621 | "dependencies": {
1622 | "@types/body-parser": {
1623 | "version": "1.19.0",
1624 | "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.0.tgz",
1625 | "integrity": "sha512-W98JrE0j2K78swW4ukqMleo8R7h/pFETjM2DQ90MF6XK2i4LO4W3gQ71Lt4w3bfm2EvVSyWHplECvB5sK22yFQ==",
1626 | "dev": true,
1627 | "requires": {
1628 | "@types/connect": "*",
1629 | "@types/node": "*"
1630 | }
1631 | },
1632 | "@types/compression": {
1633 | "version": "0.0.36",
1634 | "resolved": "https://registry.npmjs.org/@types/compression/-/compression-0.0.36.tgz",
1635 | "integrity": "sha512-B66iZCIcD2eB2F8e8YDIVtCUKgfiseOR5YOIbmMN2tM57Wu55j1xSdxdSw78aVzsPmbZ6G+hINc+1xe1tt4NBg==",
1636 | "dev": true,
1637 | "requires": {
1638 | "@types/express": "*"
1639 | }
1640 | },
1641 | "@types/connect": {
1642 | "version": "3.4.33",
1643 | "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.33.tgz",
1644 | "integrity": "sha512-2+FrkXY4zllzTNfJth7jOqEHC+enpLeGslEhpnTAkg21GkRrWV4SsAtqchtT4YS9/nODBU2/ZfsBY2X4J/dX7A==",
1645 | "dev": true,
1646 | "requires": {
1647 | "@types/node": "*"
1648 | }
1649 | },
1650 | "@types/express": {
1651 | "version": "4.17.3",
1652 | "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.3.tgz",
1653 | "integrity": "sha512-I8cGRJj3pyOLs/HndoP+25vOqhqWkAZsWMEmq1qXy/b/M3ppufecUwaK2/TVDVxcV61/iSdhykUjQQ2DLSrTdg==",
1654 | "dev": true,
1655 | "requires": {
1656 | "@types/body-parser": "*",
1657 | "@types/express-serve-static-core": "*",
1658 | "@types/serve-static": "*"
1659 | }
1660 | },
1661 | "@types/express-serve-static-core": {
1662 | "version": "4.17.2",
1663 | "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.2.tgz",
1664 | "integrity": "sha512-El9yMpctM6tORDAiBwZVLMcxoTMcqqRO9dVyYcn7ycLWbvR8klrDn8CAOwRfZujZtWD7yS/mshTdz43jMOejbg==",
1665 | "dev": true,
1666 | "requires": {
1667 | "@types/node": "*",
1668 | "@types/range-parser": "*"
1669 | }
1670 | },
1671 | "@types/http-errors": {
1672 | "version": "1.6.3",
1673 | "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-1.6.3.tgz",
1674 | "integrity": "sha512-4KCE/agIcoQ9bIfa4sBxbZdnORzRjIw8JNQPLfqoNv7wQl/8f8mRbW68Q8wBsQFoJkPUHGlQYZ9sqi5WpfGSEQ==",
1675 | "dev": true
1676 | },
1677 | "@types/mime": {
1678 | "version": "2.0.1",
1679 | "resolved": "https://registry.npmjs.org/@types/mime/-/mime-2.0.1.tgz",
1680 | "integrity": "sha512-FwI9gX75FgVBJ7ywgnq/P7tw+/o1GUbtP0KzbtusLigAOgIgNISRK0ZPl4qertvXSIE8YbsVJueQ90cDt9YYyw==",
1681 | "dev": true
1682 | },
1683 | "@types/node": {
1684 | "version": "8.10.59",
1685 | "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.59.tgz",
1686 | "integrity": "sha512-8RkBivJrDCyPpBXhVZcjh7cQxVBSmRk9QM7hOketZzp6Tg79c0N8kkpAIito9bnJ3HCVCHVYz+KHTEbfQNfeVQ==",
1687 | "dev": true
1688 | },
1689 | "@types/range-parser": {
1690 | "version": "1.2.3",
1691 | "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.3.tgz",
1692 | "integrity": "sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA==",
1693 | "dev": true
1694 | },
1695 | "@types/send": {
1696 | "version": "0.14.5",
1697 | "resolved": "https://registry.npmjs.org/@types/send/-/send-0.14.5.tgz",
1698 | "integrity": "sha512-0mwoiK3DXXBu0GIfo+jBv4Wo5s1AcsxdpdwNUtflKm99VEMvmBPJ+/NBNRZy2R5JEYfWL/u4nAHuTUTA3wFecQ==",
1699 | "dev": true,
1700 | "requires": {
1701 | "@types/mime": "*",
1702 | "@types/node": "*"
1703 | }
1704 | },
1705 | "@types/serve-static": {
1706 | "version": "1.13.3",
1707 | "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.3.tgz",
1708 | "integrity": "sha512-oprSwp094zOglVrXdlo/4bAHtKTAxX6VT8FOZlBKrmyLbNvE1zxZyJ6yikMVtHIvwP45+ZQGJn+FdXGKTozq0g==",
1709 | "dev": true,
1710 | "requires": {
1711 | "@types/express-serve-static-core": "*",
1712 | "@types/mime": "*"
1713 | }
1714 | },
1715 | "@types/statuses": {
1716 | "version": "1.5.0",
1717 | "resolved": "https://registry.npmjs.org/@types/statuses/-/statuses-1.5.0.tgz",
1718 | "integrity": "sha512-4zJN5gJH+Km6hA36z8MnOKas6EU0qwxItTXNijYDPuZUsSk4EpIAB56fwnxZIhi3tHx42J7wqNdQTqt49Ar9FQ==",
1719 | "dev": true
1720 | },
1721 | "@types/ua-parser-js": {
1722 | "version": "0.7.33",
1723 | "resolved": "https://registry.npmjs.org/@types/ua-parser-js/-/ua-parser-js-0.7.33.tgz",
1724 | "integrity": "sha512-ngUKcHnytUodUCL7C6EZ+lVXUjTMQb+9p/e1JjV5tN9TVzS98lHozWEFRPY1QcCdwFeMsmVWfZ3DPPT/udCyIw==",
1725 | "dev": true
1726 | },
1727 | "@types/valid-url": {
1728 | "version": "1.0.2",
1729 | "resolved": "https://registry.npmjs.org/@types/valid-url/-/valid-url-1.0.2.tgz",
1730 | "integrity": "sha1-YPpDXOJL/VuhB7jSqAeWrq86j0U=",
1731 | "dev": true
1732 | },
1733 | "accepts": {
1734 | "version": "1.3.7",
1735 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz",
1736 | "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==",
1737 | "dev": true,
1738 | "requires": {
1739 | "mime-types": "~2.1.24",
1740 | "negotiator": "0.6.2"
1741 | }
1742 | },
1743 | "ajv": {
1744 | "version": "6.12.0",
1745 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.0.tgz",
1746 | "integrity": "sha512-D6gFiFA0RRLyUbvijN74DWAjXSFxWKaWP7mldxkVhyhAV3+SWA9HEJPHQ2c9soIeTFJqcSdFDGFgdqs1iUU2Hw==",
1747 | "dev": true,
1748 | "requires": {
1749 | "fast-deep-equal": "^3.1.1",
1750 | "fast-json-stable-stringify": "^2.0.0",
1751 | "json-schema-traverse": "^0.4.1",
1752 | "uri-js": "^4.2.2"
1753 | }
1754 | },
1755 | "ansi-escape-sequences": {
1756 | "version": "4.1.0",
1757 | "resolved": "https://registry.npmjs.org/ansi-escape-sequences/-/ansi-escape-sequences-4.1.0.tgz",
1758 | "integrity": "sha512-dzW9kHxH011uBsidTXd14JXgzye/YLb2LzeKZ4bsgl/Knwx8AtbSFkkGxagdNOoh0DlqHCmfiEjWKBaqjOanVw==",
1759 | "dev": true,
1760 | "requires": {
1761 | "array-back": "^3.0.1"
1762 | }
1763 | },
1764 | "ansi-styles": {
1765 | "version": "3.2.1",
1766 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
1767 | "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
1768 | "dev": true,
1769 | "requires": {
1770 | "color-convert": "^1.9.0"
1771 | }
1772 | },
1773 | "array-back": {
1774 | "version": "3.1.0",
1775 | "resolved": "https://registry.npmjs.org/array-back/-/array-back-3.1.0.tgz",
1776 | "integrity": "sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==",
1777 | "dev": true
1778 | },
1779 | "array-flatten": {
1780 | "version": "1.1.1",
1781 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
1782 | "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=",
1783 | "dev": true
1784 | },
1785 | "asn1": {
1786 | "version": "0.2.4",
1787 | "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz",
1788 | "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==",
1789 | "dev": true,
1790 | "requires": {
1791 | "safer-buffer": "~2.1.0"
1792 | }
1793 | },
1794 | "assert-plus": {
1795 | "version": "1.0.0",
1796 | "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
1797 | "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
1798 | "dev": true
1799 | },
1800 | "asynckit": {
1801 | "version": "0.4.0",
1802 | "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
1803 | "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=",
1804 | "dev": true
1805 | },
1806 | "aws-sign2": {
1807 | "version": "0.7.0",
1808 | "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
1809 | "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=",
1810 | "dev": true
1811 | },
1812 | "aws4": {
1813 | "version": "1.9.1",
1814 | "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.9.1.tgz",
1815 | "integrity": "sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug==",
1816 | "dev": true
1817 | },
1818 | "bcrypt-pbkdf": {
1819 | "version": "1.0.2",
1820 | "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
1821 | "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=",
1822 | "dev": true,
1823 | "requires": {
1824 | "tweetnacl": "^0.14.3"
1825 | }
1826 | },
1827 | "body-parser": {
1828 | "version": "1.19.0",
1829 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz",
1830 | "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==",
1831 | "dev": true,
1832 | "requires": {
1833 | "bytes": "3.1.0",
1834 | "content-type": "~1.0.4",
1835 | "debug": "2.6.9",
1836 | "depd": "~1.1.2",
1837 | "http-errors": "1.7.2",
1838 | "iconv-lite": "0.4.24",
1839 | "on-finished": "~2.3.0",
1840 | "qs": "6.7.0",
1841 | "raw-body": "2.4.0",
1842 | "type-is": "~1.6.17"
1843 | },
1844 | "dependencies": {
1845 | "bytes": {
1846 | "version": "3.1.0",
1847 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz",
1848 | "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==",
1849 | "dev": true
1850 | },
1851 | "http-errors": {
1852 | "version": "1.7.2",
1853 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz",
1854 | "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==",
1855 | "dev": true,
1856 | "requires": {
1857 | "depd": "~1.1.2",
1858 | "inherits": "2.0.3",
1859 | "setprototypeof": "1.1.1",
1860 | "statuses": ">= 1.5.0 < 2",
1861 | "toidentifier": "1.0.0"
1862 | }
1863 | }
1864 | }
1865 | },
1866 | "browser-capabilities": {
1867 | "version": "1.1.4",
1868 | "resolved": "https://registry.npmjs.org/browser-capabilities/-/browser-capabilities-1.1.4.tgz",
1869 | "integrity": "sha512-BezMQhbQklxjRQpZZQ8tnbzEo6AldUwMh8/PeWt5/CTBSwByQRXZEAK2fbnEahQ4poeeaI0suAYRq25A1YGOmw==",
1870 | "dev": true,
1871 | "requires": {
1872 | "@types/ua-parser-js": "^0.7.31",
1873 | "ua-parser-js": "^0.7.15"
1874 | }
1875 | },
1876 | "bytes": {
1877 | "version": "3.0.0",
1878 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz",
1879 | "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=",
1880 | "dev": true
1881 | },
1882 | "caseless": {
1883 | "version": "0.12.0",
1884 | "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
1885 | "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=",
1886 | "dev": true
1887 | },
1888 | "chalk": {
1889 | "version": "2.4.2",
1890 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
1891 | "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
1892 | "dev": true,
1893 | "requires": {
1894 | "ansi-styles": "^3.2.1",
1895 | "escape-string-regexp": "^1.0.5",
1896 | "supports-color": "^5.3.0"
1897 | }
1898 | },
1899 | "color-convert": {
1900 | "version": "1.9.3",
1901 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
1902 | "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
1903 | "dev": true,
1904 | "requires": {
1905 | "color-name": "1.1.3"
1906 | }
1907 | },
1908 | "color-name": {
1909 | "version": "1.1.3",
1910 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
1911 | "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
1912 | "dev": true
1913 | },
1914 | "combined-stream": {
1915 | "version": "1.0.8",
1916 | "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
1917 | "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
1918 | "dev": true,
1919 | "requires": {
1920 | "delayed-stream": "~1.0.0"
1921 | }
1922 | },
1923 | "command-line-args": {
1924 | "version": "5.1.1",
1925 | "resolved": "https://registry.npmjs.org/command-line-args/-/command-line-args-5.1.1.tgz",
1926 | "integrity": "sha512-hL/eG8lrll1Qy1ezvkant+trihbGnaKaeEjj6Scyr3DN+RC7iQ5Rz84IeLERfAWDGo0HBSNAakczwgCilDXnWg==",
1927 | "dev": true,
1928 | "requires": {
1929 | "array-back": "^3.0.1",
1930 | "find-replace": "^3.0.0",
1931 | "lodash.camelcase": "^4.3.0",
1932 | "typical": "^4.0.0"
1933 | }
1934 | },
1935 | "command-line-usage": {
1936 | "version": "5.0.5",
1937 | "resolved": "https://registry.npmjs.org/command-line-usage/-/command-line-usage-5.0.5.tgz",
1938 | "integrity": "sha512-d8NrGylA5oCXSbGoKz05FkehDAzSmIm4K03S5VDh4d5lZAtTWfc3D1RuETtuQCn8129nYfJfDdF7P/lwcz1BlA==",
1939 | "dev": true,
1940 | "requires": {
1941 | "array-back": "^2.0.0",
1942 | "chalk": "^2.4.1",
1943 | "table-layout": "^0.4.3",
1944 | "typical": "^2.6.1"
1945 | },
1946 | "dependencies": {
1947 | "array-back": {
1948 | "version": "2.0.0",
1949 | "resolved": "https://registry.npmjs.org/array-back/-/array-back-2.0.0.tgz",
1950 | "integrity": "sha512-eJv4pLLufP3g5kcZry0j6WXpIbzYw9GUB4mVJZno9wfwiBxbizTnHCw3VJb07cBihbFX48Y7oSrW9y+gt4glyw==",
1951 | "dev": true,
1952 | "requires": {
1953 | "typical": "^2.6.1"
1954 | }
1955 | },
1956 | "typical": {
1957 | "version": "2.6.1",
1958 | "resolved": "https://registry.npmjs.org/typical/-/typical-2.6.1.tgz",
1959 | "integrity": "sha1-XAgOXWYcu+OCWdLnCjxyU+hziB0=",
1960 | "dev": true
1961 | }
1962 | }
1963 | },
1964 | "compressible": {
1965 | "version": "2.0.18",
1966 | "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz",
1967 | "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==",
1968 | "dev": true,
1969 | "requires": {
1970 | "mime-db": ">= 1.43.0 < 2"
1971 | }
1972 | },
1973 | "compression": {
1974 | "version": "1.7.4",
1975 | "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz",
1976 | "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==",
1977 | "dev": true,
1978 | "requires": {
1979 | "accepts": "~1.3.5",
1980 | "bytes": "3.0.0",
1981 | "compressible": "~2.0.16",
1982 | "debug": "2.6.9",
1983 | "on-headers": "~1.0.2",
1984 | "safe-buffer": "5.1.2",
1985 | "vary": "~1.1.2"
1986 | }
1987 | },
1988 | "content-disposition": {
1989 | "version": "0.5.3",
1990 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz",
1991 | "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==",
1992 | "dev": true,
1993 | "requires": {
1994 | "safe-buffer": "5.1.2"
1995 | }
1996 | },
1997 | "content-type": {
1998 | "version": "1.0.4",
1999 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
2000 | "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==",
2001 | "dev": true
2002 | },
2003 | "cookie": {
2004 | "version": "0.4.0",
2005 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz",
2006 | "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==",
2007 | "dev": true
2008 | },
2009 | "cookie-signature": {
2010 | "version": "1.0.6",
2011 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
2012 | "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=",
2013 | "dev": true
2014 | },
2015 | "core-util-is": {
2016 | "version": "1.0.2",
2017 | "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
2018 | "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
2019 | "dev": true
2020 | },
2021 | "dashdash": {
2022 | "version": "1.14.1",
2023 | "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
2024 | "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
2025 | "dev": true,
2026 | "requires": {
2027 | "assert-plus": "^1.0.0"
2028 | }
2029 | },
2030 | "debug": {
2031 | "version": "2.6.9",
2032 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
2033 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
2034 | "dev": true,
2035 | "requires": {
2036 | "ms": "2.0.0"
2037 | }
2038 | },
2039 | "deep-extend": {
2040 | "version": "0.6.0",
2041 | "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
2042 | "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==",
2043 | "dev": true
2044 | },
2045 | "delayed-stream": {
2046 | "version": "1.0.0",
2047 | "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
2048 | "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
2049 | "dev": true
2050 | },
2051 | "depd": {
2052 | "version": "1.1.2",
2053 | "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
2054 | "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=",
2055 | "dev": true
2056 | },
2057 | "destroy": {
2058 | "version": "1.0.4",
2059 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
2060 | "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=",
2061 | "dev": true
2062 | },
2063 | "ecc-jsbn": {
2064 | "version": "0.1.2",
2065 | "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
2066 | "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=",
2067 | "dev": true,
2068 | "requires": {
2069 | "jsbn": "~0.1.0",
2070 | "safer-buffer": "^2.1.0"
2071 | }
2072 | },
2073 | "ee-first": {
2074 | "version": "1.1.1",
2075 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
2076 | "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=",
2077 | "dev": true
2078 | },
2079 | "encodeurl": {
2080 | "version": "1.0.2",
2081 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
2082 | "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=",
2083 | "dev": true
2084 | },
2085 | "escape-html": {
2086 | "version": "1.0.3",
2087 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
2088 | "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=",
2089 | "dev": true
2090 | },
2091 | "escape-string-regexp": {
2092 | "version": "1.0.5",
2093 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
2094 | "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
2095 | "dev": true
2096 | },
2097 | "etag": {
2098 | "version": "1.8.1",
2099 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
2100 | "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=",
2101 | "dev": true
2102 | },
2103 | "express": {
2104 | "version": "4.17.1",
2105 | "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz",
2106 | "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==",
2107 | "dev": true,
2108 | "requires": {
2109 | "accepts": "~1.3.7",
2110 | "array-flatten": "1.1.1",
2111 | "body-parser": "1.19.0",
2112 | "content-disposition": "0.5.3",
2113 | "content-type": "~1.0.4",
2114 | "cookie": "0.4.0",
2115 | "cookie-signature": "1.0.6",
2116 | "debug": "2.6.9",
2117 | "depd": "~1.1.2",
2118 | "encodeurl": "~1.0.2",
2119 | "escape-html": "~1.0.3",
2120 | "etag": "~1.8.1",
2121 | "finalhandler": "~1.1.2",
2122 | "fresh": "0.5.2",
2123 | "merge-descriptors": "1.0.1",
2124 | "methods": "~1.1.2",
2125 | "on-finished": "~2.3.0",
2126 | "parseurl": "~1.3.3",
2127 | "path-to-regexp": "0.1.7",
2128 | "proxy-addr": "~2.0.5",
2129 | "qs": "6.7.0",
2130 | "range-parser": "~1.2.1",
2131 | "safe-buffer": "5.1.2",
2132 | "send": "0.17.1",
2133 | "serve-static": "1.14.1",
2134 | "setprototypeof": "1.1.1",
2135 | "statuses": "~1.5.0",
2136 | "type-is": "~1.6.18",
2137 | "utils-merge": "1.0.1",
2138 | "vary": "~1.1.2"
2139 | },
2140 | "dependencies": {
2141 | "ms": {
2142 | "version": "2.1.1",
2143 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
2144 | "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==",
2145 | "dev": true
2146 | },
2147 | "send": {
2148 | "version": "0.17.1",
2149 | "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz",
2150 | "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==",
2151 | "dev": true,
2152 | "requires": {
2153 | "debug": "2.6.9",
2154 | "depd": "~1.1.2",
2155 | "destroy": "~1.0.4",
2156 | "encodeurl": "~1.0.2",
2157 | "escape-html": "~1.0.3",
2158 | "etag": "~1.8.1",
2159 | "fresh": "0.5.2",
2160 | "http-errors": "~1.7.2",
2161 | "mime": "1.6.0",
2162 | "ms": "2.1.1",
2163 | "on-finished": "~2.3.0",
2164 | "range-parser": "~1.2.1",
2165 | "statuses": "~1.5.0"
2166 | }
2167 | }
2168 | }
2169 | },
2170 | "extend": {
2171 | "version": "3.0.2",
2172 | "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
2173 | "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==",
2174 | "dev": true
2175 | },
2176 | "extsprintf": {
2177 | "version": "1.3.0",
2178 | "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
2179 | "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=",
2180 | "dev": true
2181 | },
2182 | "fast-deep-equal": {
2183 | "version": "3.1.1",
2184 | "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz",
2185 | "integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA==",
2186 | "dev": true
2187 | },
2188 | "fast-json-stable-stringify": {
2189 | "version": "2.1.0",
2190 | "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
2191 | "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
2192 | "dev": true
2193 | },
2194 | "finalhandler": {
2195 | "version": "1.1.2",
2196 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz",
2197 | "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==",
2198 | "dev": true,
2199 | "requires": {
2200 | "debug": "2.6.9",
2201 | "encodeurl": "~1.0.2",
2202 | "escape-html": "~1.0.3",
2203 | "on-finished": "~2.3.0",
2204 | "parseurl": "~1.3.3",
2205 | "statuses": "~1.5.0",
2206 | "unpipe": "~1.0.0"
2207 | }
2208 | },
2209 | "find-replace": {
2210 | "version": "3.0.0",
2211 | "resolved": "https://registry.npmjs.org/find-replace/-/find-replace-3.0.0.tgz",
2212 | "integrity": "sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ==",
2213 | "dev": true,
2214 | "requires": {
2215 | "array-back": "^3.0.1"
2216 | }
2217 | },
2218 | "forever-agent": {
2219 | "version": "0.6.1",
2220 | "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
2221 | "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=",
2222 | "dev": true
2223 | },
2224 | "form-data": {
2225 | "version": "2.3.3",
2226 | "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz",
2227 | "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==",
2228 | "dev": true,
2229 | "requires": {
2230 | "asynckit": "^0.4.0",
2231 | "combined-stream": "^1.0.6",
2232 | "mime-types": "^2.1.12"
2233 | }
2234 | },
2235 | "forwarded": {
2236 | "version": "0.1.2",
2237 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz",
2238 | "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=",
2239 | "dev": true
2240 | },
2241 | "fresh": {
2242 | "version": "0.5.2",
2243 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
2244 | "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=",
2245 | "dev": true
2246 | },
2247 | "getpass": {
2248 | "version": "0.1.7",
2249 | "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
2250 | "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
2251 | "dev": true,
2252 | "requires": {
2253 | "assert-plus": "^1.0.0"
2254 | }
2255 | },
2256 | "har-schema": {
2257 | "version": "2.0.0",
2258 | "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
2259 | "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=",
2260 | "dev": true
2261 | },
2262 | "har-validator": {
2263 | "version": "5.1.3",
2264 | "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz",
2265 | "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==",
2266 | "dev": true,
2267 | "requires": {
2268 | "ajv": "^6.5.5",
2269 | "har-schema": "^2.0.0"
2270 | }
2271 | },
2272 | "has-flag": {
2273 | "version": "3.0.0",
2274 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
2275 | "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
2276 | "dev": true
2277 | },
2278 | "http-errors": {
2279 | "version": "1.7.3",
2280 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.3.tgz",
2281 | "integrity": "sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw==",
2282 | "dev": true,
2283 | "requires": {
2284 | "depd": "~1.1.2",
2285 | "inherits": "2.0.4",
2286 | "setprototypeof": "1.1.1",
2287 | "statuses": ">= 1.5.0 < 2",
2288 | "toidentifier": "1.0.0"
2289 | },
2290 | "dependencies": {
2291 | "inherits": {
2292 | "version": "2.0.4",
2293 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
2294 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
2295 | "dev": true
2296 | }
2297 | }
2298 | },
2299 | "http-signature": {
2300 | "version": "1.2.0",
2301 | "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
2302 | "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
2303 | "dev": true,
2304 | "requires": {
2305 | "assert-plus": "^1.0.0",
2306 | "jsprim": "^1.2.2",
2307 | "sshpk": "^1.7.0"
2308 | }
2309 | },
2310 | "iconv-lite": {
2311 | "version": "0.4.24",
2312 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
2313 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
2314 | "dev": true,
2315 | "requires": {
2316 | "safer-buffer": ">= 2.1.2 < 3"
2317 | }
2318 | },
2319 | "inherits": {
2320 | "version": "2.0.3",
2321 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
2322 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
2323 | "dev": true
2324 | },
2325 | "ipaddr.js": {
2326 | "version": "1.9.1",
2327 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
2328 | "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
2329 | "dev": true
2330 | },
2331 | "is-typedarray": {
2332 | "version": "1.0.0",
2333 | "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
2334 | "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=",
2335 | "dev": true
2336 | },
2337 | "isstream": {
2338 | "version": "0.1.2",
2339 | "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
2340 | "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=",
2341 | "dev": true
2342 | },
2343 | "jsbn": {
2344 | "version": "0.1.1",
2345 | "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
2346 | "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
2347 | "dev": true
2348 | },
2349 | "json-schema": {
2350 | "version": "0.2.3",
2351 | "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
2352 | "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=",
2353 | "dev": true
2354 | },
2355 | "json-schema-traverse": {
2356 | "version": "0.4.1",
2357 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
2358 | "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
2359 | "dev": true
2360 | },
2361 | "json-stringify-safe": {
2362 | "version": "5.0.1",
2363 | "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
2364 | "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=",
2365 | "dev": true
2366 | },
2367 | "jsprim": {
2368 | "version": "1.4.1",
2369 | "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
2370 | "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=",
2371 | "dev": true,
2372 | "requires": {
2373 | "assert-plus": "1.0.0",
2374 | "extsprintf": "1.3.0",
2375 | "json-schema": "0.2.3",
2376 | "verror": "1.10.0"
2377 | }
2378 | },
2379 | "lodash.camelcase": {
2380 | "version": "4.3.0",
2381 | "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz",
2382 | "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=",
2383 | "dev": true
2384 | },
2385 | "lodash.padend": {
2386 | "version": "4.6.1",
2387 | "resolved": "https://registry.npmjs.org/lodash.padend/-/lodash.padend-4.6.1.tgz",
2388 | "integrity": "sha1-U8y6BH0G4VjTEfRdpiX05J5vFm4=",
2389 | "dev": true
2390 | },
2391 | "media-typer": {
2392 | "version": "0.3.0",
2393 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
2394 | "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=",
2395 | "dev": true
2396 | },
2397 | "merge-descriptors": {
2398 | "version": "1.0.1",
2399 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
2400 | "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=",
2401 | "dev": true
2402 | },
2403 | "methods": {
2404 | "version": "1.1.2",
2405 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
2406 | "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=",
2407 | "dev": true
2408 | },
2409 | "mime": {
2410 | "version": "1.6.0",
2411 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
2412 | "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
2413 | "dev": true
2414 | },
2415 | "mime-db": {
2416 | "version": "1.43.0",
2417 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.43.0.tgz",
2418 | "integrity": "sha512-+5dsGEEovYbT8UY9yD7eE4XTc4UwJ1jBYlgaQQF38ENsKR3wj/8q8RFZrF9WIZpB2V1ArTVFUva8sAul1NzRzQ==",
2419 | "dev": true
2420 | },
2421 | "mime-types": {
2422 | "version": "2.1.26",
2423 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.26.tgz",
2424 | "integrity": "sha512-01paPWYgLrkqAyrlDorC1uDwl2p3qZT7yl806vW7DvDoxwXi46jsjFbg+WdwotBIk6/MbEhO/dh5aZ5sNj/dWQ==",
2425 | "dev": true,
2426 | "requires": {
2427 | "mime-db": "1.43.0"
2428 | }
2429 | },
2430 | "ms": {
2431 | "version": "2.0.0",
2432 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
2433 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
2434 | "dev": true
2435 | },
2436 | "negotiator": {
2437 | "version": "0.6.2",
2438 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz",
2439 | "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==",
2440 | "dev": true
2441 | },
2442 | "oauth-sign": {
2443 | "version": "0.9.0",
2444 | "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
2445 | "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==",
2446 | "dev": true
2447 | },
2448 | "on-finished": {
2449 | "version": "2.3.0",
2450 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
2451 | "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
2452 | "dev": true,
2453 | "requires": {
2454 | "ee-first": "1.1.1"
2455 | }
2456 | },
2457 | "on-headers": {
2458 | "version": "1.0.2",
2459 | "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz",
2460 | "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==",
2461 | "dev": true
2462 | },
2463 | "orbit-controls-es6": {
2464 | "version": "2.0.1",
2465 | "resolved": "https://registry.npmjs.org/orbit-controls-es6/-/orbit-controls-es6-2.0.1.tgz",
2466 | "integrity": "sha512-Np+XREwlIFl7tSpMSqHuJ20ySonCwCJO+vxyMGmijCJv5+I1SqGQMNfn2fwJC3TVvakXRIxa4ayxJdzeF5dPAA==",
2467 | "requires": {}
2468 | },
2469 | "parseurl": {
2470 | "version": "1.3.3",
2471 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
2472 | "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
2473 | "dev": true
2474 | },
2475 | "path-to-regexp": {
2476 | "version": "0.1.7",
2477 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
2478 | "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=",
2479 | "dev": true
2480 | },
2481 | "performance-now": {
2482 | "version": "2.1.0",
2483 | "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
2484 | "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=",
2485 | "dev": true
2486 | },
2487 | "proxy-addr": {
2488 | "version": "2.0.6",
2489 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz",
2490 | "integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==",
2491 | "dev": true,
2492 | "requires": {
2493 | "forwarded": "~0.1.2",
2494 | "ipaddr.js": "1.9.1"
2495 | }
2496 | },
2497 | "prpl-server": {
2498 | "version": "1.4.0",
2499 | "resolved": "https://registry.npmjs.org/prpl-server/-/prpl-server-1.4.0.tgz",
2500 | "integrity": "sha512-nyLjYI00bf5M4O6Cel5uE4AuRh3IzkIPf8jtywta2YIOJJ7yGb5SI1tKdcHDn8LdNc/qn1/6ZudPJdceew1BIg==",
2501 | "dev": true,
2502 | "requires": {
2503 | "@types/compression": "0.0.36",
2504 | "@types/express": "^4.0.35",
2505 | "@types/http-errors": "^1.6.1",
2506 | "@types/node": "^8.0.47",
2507 | "@types/send": "^0.14.2",
2508 | "@types/statuses": "^1.3.0",
2509 | "@types/valid-url": "^1.0.2",
2510 | "ansi-escape-sequences": "^4.0.0",
2511 | "browser-capabilities": "^1.0.0",
2512 | "command-line-args": "^5.0.2",
2513 | "command-line-usage": "^5.0.4",
2514 | "compression": "^1.6.2",
2515 | "express": "^4.15.2",
2516 | "http-errors": "^1.6.2",
2517 | "rendertron-middleware": "^0.1.1",
2518 | "send": "^0.16.1",
2519 | "statuses": "^1.4.0",
2520 | "tsc-then": "^1.1.0",
2521 | "valid-url": "^1.0.9"
2522 | }
2523 | },
2524 | "psl": {
2525 | "version": "1.7.0",
2526 | "resolved": "https://registry.npmjs.org/psl/-/psl-1.7.0.tgz",
2527 | "integrity": "sha512-5NsSEDv8zY70ScRnOTn7bK7eanl2MvFrOrS/R6x+dBt5g1ghnj9Zv90kO8GwT8gxcu2ANyFprnFYB85IogIJOQ==",
2528 | "dev": true
2529 | },
2530 | "punycode": {
2531 | "version": "2.1.1",
2532 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
2533 | "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
2534 | "dev": true
2535 | },
2536 | "qs": {
2537 | "version": "6.7.0",
2538 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
2539 | "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==",
2540 | "dev": true
2541 | },
2542 | "range-parser": {
2543 | "version": "1.2.1",
2544 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
2545 | "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
2546 | "dev": true
2547 | },
2548 | "raw-body": {
2549 | "version": "2.4.0",
2550 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz",
2551 | "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==",
2552 | "dev": true,
2553 | "requires": {
2554 | "bytes": "3.1.0",
2555 | "http-errors": "1.7.2",
2556 | "iconv-lite": "0.4.24",
2557 | "unpipe": "1.0.0"
2558 | },
2559 | "dependencies": {
2560 | "bytes": {
2561 | "version": "3.1.0",
2562 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz",
2563 | "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==",
2564 | "dev": true
2565 | },
2566 | "http-errors": {
2567 | "version": "1.7.2",
2568 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz",
2569 | "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==",
2570 | "dev": true,
2571 | "requires": {
2572 | "depd": "~1.1.2",
2573 | "inherits": "2.0.3",
2574 | "setprototypeof": "1.1.1",
2575 | "statuses": ">= 1.5.0 < 2",
2576 | "toidentifier": "1.0.0"
2577 | }
2578 | }
2579 | }
2580 | },
2581 | "reduce-flatten": {
2582 | "version": "1.0.1",
2583 | "resolved": "https://registry.npmjs.org/reduce-flatten/-/reduce-flatten-1.0.1.tgz",
2584 | "integrity": "sha1-JYx479FT3fk8tWEjf2EYTzaW4yc=",
2585 | "dev": true
2586 | },
2587 | "rendertron-middleware": {
2588 | "version": "0.1.5",
2589 | "resolved": "https://registry.npmjs.org/rendertron-middleware/-/rendertron-middleware-0.1.5.tgz",
2590 | "integrity": "sha512-YTwWJ+vP07w0jdpHsKMhM8RQ6q7Xa2AKmZMMIUzFFbqFnAtso6o6nxWEk/S0axLFPEFfrGMxTqewOtM4Cy8KNQ==",
2591 | "dev": true,
2592 | "requires": {
2593 | "@types/express": "^4.16.0",
2594 | "request": "^2.87.0"
2595 | }
2596 | },
2597 | "request": {
2598 | "version": "2.88.2",
2599 | "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz",
2600 | "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==",
2601 | "dev": true,
2602 | "requires": {
2603 | "aws-sign2": "~0.7.0",
2604 | "aws4": "^1.8.0",
2605 | "caseless": "~0.12.0",
2606 | "combined-stream": "~1.0.6",
2607 | "extend": "~3.0.2",
2608 | "forever-agent": "~0.6.1",
2609 | "form-data": "~2.3.2",
2610 | "har-validator": "~5.1.3",
2611 | "http-signature": "~1.2.0",
2612 | "is-typedarray": "~1.0.0",
2613 | "isstream": "~0.1.2",
2614 | "json-stringify-safe": "~5.0.1",
2615 | "mime-types": "~2.1.19",
2616 | "oauth-sign": "~0.9.0",
2617 | "performance-now": "^2.1.0",
2618 | "qs": "~6.5.2",
2619 | "safe-buffer": "^5.1.2",
2620 | "tough-cookie": "~2.5.0",
2621 | "tunnel-agent": "^0.6.0",
2622 | "uuid": "^3.3.2"
2623 | },
2624 | "dependencies": {
2625 | "qs": {
2626 | "version": "6.5.2",
2627 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz",
2628 | "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==",
2629 | "dev": true
2630 | }
2631 | }
2632 | },
2633 | "safe-buffer": {
2634 | "version": "5.1.2",
2635 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
2636 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
2637 | "dev": true
2638 | },
2639 | "safer-buffer": {
2640 | "version": "2.1.2",
2641 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
2642 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
2643 | "dev": true
2644 | },
2645 | "semver": {
2646 | "version": "5.7.1",
2647 | "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
2648 | "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
2649 | "dev": true
2650 | },
2651 | "send": {
2652 | "version": "0.16.2",
2653 | "resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz",
2654 | "integrity": "sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw==",
2655 | "dev": true,
2656 | "requires": {
2657 | "debug": "2.6.9",
2658 | "depd": "~1.1.2",
2659 | "destroy": "~1.0.4",
2660 | "encodeurl": "~1.0.2",
2661 | "escape-html": "~1.0.3",
2662 | "etag": "~1.8.1",
2663 | "fresh": "0.5.2",
2664 | "http-errors": "~1.6.2",
2665 | "mime": "1.4.1",
2666 | "ms": "2.0.0",
2667 | "on-finished": "~2.3.0",
2668 | "range-parser": "~1.2.0",
2669 | "statuses": "~1.4.0"
2670 | },
2671 | "dependencies": {
2672 | "http-errors": {
2673 | "version": "1.6.3",
2674 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz",
2675 | "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=",
2676 | "dev": true,
2677 | "requires": {
2678 | "depd": "~1.1.2",
2679 | "inherits": "2.0.3",
2680 | "setprototypeof": "1.1.0",
2681 | "statuses": ">= 1.4.0 < 2"
2682 | }
2683 | },
2684 | "mime": {
2685 | "version": "1.4.1",
2686 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz",
2687 | "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==",
2688 | "dev": true
2689 | },
2690 | "setprototypeof": {
2691 | "version": "1.1.0",
2692 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz",
2693 | "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==",
2694 | "dev": true
2695 | },
2696 | "statuses": {
2697 | "version": "1.4.0",
2698 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz",
2699 | "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==",
2700 | "dev": true
2701 | }
2702 | }
2703 | },
2704 | "serve-static": {
2705 | "version": "1.14.1",
2706 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz",
2707 | "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==",
2708 | "dev": true,
2709 | "requires": {
2710 | "encodeurl": "~1.0.2",
2711 | "escape-html": "~1.0.3",
2712 | "parseurl": "~1.3.3",
2713 | "send": "0.17.1"
2714 | },
2715 | "dependencies": {
2716 | "ms": {
2717 | "version": "2.1.1",
2718 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
2719 | "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==",
2720 | "dev": true
2721 | },
2722 | "send": {
2723 | "version": "0.17.1",
2724 | "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz",
2725 | "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==",
2726 | "dev": true,
2727 | "requires": {
2728 | "debug": "2.6.9",
2729 | "depd": "~1.1.2",
2730 | "destroy": "~1.0.4",
2731 | "encodeurl": "~1.0.2",
2732 | "escape-html": "~1.0.3",
2733 | "etag": "~1.8.1",
2734 | "fresh": "0.5.2",
2735 | "http-errors": "~1.7.2",
2736 | "mime": "1.6.0",
2737 | "ms": "2.1.1",
2738 | "on-finished": "~2.3.0",
2739 | "range-parser": "~1.2.1",
2740 | "statuses": "~1.5.0"
2741 | }
2742 | }
2743 | }
2744 | },
2745 | "setprototypeof": {
2746 | "version": "1.1.1",
2747 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz",
2748 | "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==",
2749 | "dev": true
2750 | },
2751 | "sshpk": {
2752 | "version": "1.16.1",
2753 | "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz",
2754 | "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==",
2755 | "dev": true,
2756 | "requires": {
2757 | "asn1": "~0.2.3",
2758 | "assert-plus": "^1.0.0",
2759 | "bcrypt-pbkdf": "^1.0.0",
2760 | "dashdash": "^1.12.0",
2761 | "ecc-jsbn": "~0.1.1",
2762 | "getpass": "^0.1.1",
2763 | "jsbn": "~0.1.0",
2764 | "safer-buffer": "^2.0.2",
2765 | "tweetnacl": "~0.14.0"
2766 | }
2767 | },
2768 | "statuses": {
2769 | "version": "1.5.0",
2770 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
2771 | "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=",
2772 | "dev": true
2773 | },
2774 | "supports-color": {
2775 | "version": "5.5.0",
2776 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
2777 | "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
2778 | "dev": true,
2779 | "requires": {
2780 | "has-flag": "^3.0.0"
2781 | }
2782 | },
2783 | "table-layout": {
2784 | "version": "0.4.5",
2785 | "resolved": "https://registry.npmjs.org/table-layout/-/table-layout-0.4.5.tgz",
2786 | "integrity": "sha512-zTvf0mcggrGeTe/2jJ6ECkJHAQPIYEwDoqsiqBjI24mvRmQbInK5jq33fyypaCBxX08hMkfmdOqj6haT33EqWw==",
2787 | "dev": true,
2788 | "requires": {
2789 | "array-back": "^2.0.0",
2790 | "deep-extend": "~0.6.0",
2791 | "lodash.padend": "^4.6.1",
2792 | "typical": "^2.6.1",
2793 | "wordwrapjs": "^3.0.0"
2794 | },
2795 | "dependencies": {
2796 | "array-back": {
2797 | "version": "2.0.0",
2798 | "resolved": "https://registry.npmjs.org/array-back/-/array-back-2.0.0.tgz",
2799 | "integrity": "sha512-eJv4pLLufP3g5kcZry0j6WXpIbzYw9GUB4mVJZno9wfwiBxbizTnHCw3VJb07cBihbFX48Y7oSrW9y+gt4glyw==",
2800 | "dev": true,
2801 | "requires": {
2802 | "typical": "^2.6.1"
2803 | }
2804 | },
2805 | "typical": {
2806 | "version": "2.6.1",
2807 | "resolved": "https://registry.npmjs.org/typical/-/typical-2.6.1.tgz",
2808 | "integrity": "sha1-XAgOXWYcu+OCWdLnCjxyU+hziB0=",
2809 | "dev": true
2810 | }
2811 | }
2812 | },
2813 | "three": {
2814 | "version": "0.114.0",
2815 | "resolved": "https://registry.npmjs.org/three/-/three-0.114.0.tgz",
2816 | "integrity": "sha512-3av45FxJeqYm7Rl02dfGBoqTaf2a934oUB4zMNrN8xjmASoSGeeykYoAr35+UntTdJDY/STw6CY3KuXFBWETig=="
2817 | },
2818 | "toidentifier": {
2819 | "version": "1.0.0",
2820 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz",
2821 | "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==",
2822 | "dev": true
2823 | },
2824 | "tough-cookie": {
2825 | "version": "2.5.0",
2826 | "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz",
2827 | "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==",
2828 | "dev": true,
2829 | "requires": {
2830 | "psl": "^1.1.28",
2831 | "punycode": "^2.1.1"
2832 | }
2833 | },
2834 | "tsc-then": {
2835 | "version": "1.1.0",
2836 | "resolved": "https://registry.npmjs.org/tsc-then/-/tsc-then-1.1.0.tgz",
2837 | "integrity": "sha512-830G8SK8tewOxfKVBC5YWqZ2C7wS1D4dh9267ebLxR7Gvh3UuI6aKU5Hxo+L3Kkcy6CuxZp4PMGl066DZ3Hlmw==",
2838 | "dev": true,
2839 | "requires": {
2840 | "@types/node": "^8.0.53",
2841 | "semver": "^5.4.1"
2842 | }
2843 | },
2844 | "tunnel-agent": {
2845 | "version": "0.6.0",
2846 | "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
2847 | "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
2848 | "dev": true,
2849 | "requires": {
2850 | "safe-buffer": "^5.0.1"
2851 | }
2852 | },
2853 | "tweetnacl": {
2854 | "version": "0.14.5",
2855 | "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
2856 | "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=",
2857 | "dev": true
2858 | },
2859 | "type-is": {
2860 | "version": "1.6.18",
2861 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
2862 | "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
2863 | "dev": true,
2864 | "requires": {
2865 | "media-typer": "0.3.0",
2866 | "mime-types": "~2.1.24"
2867 | }
2868 | },
2869 | "typical": {
2870 | "version": "4.0.0",
2871 | "resolved": "https://registry.npmjs.org/typical/-/typical-4.0.0.tgz",
2872 | "integrity": "sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw==",
2873 | "dev": true
2874 | },
2875 | "ua-parser-js": {
2876 | "version": "0.7.21",
2877 | "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.21.tgz",
2878 | "integrity": "sha512-+O8/qh/Qj8CgC6eYBVBykMrNtp5Gebn4dlGD/kKXVkJNDwyrAwSIqwz8CDf+tsAIWVycKcku6gIXJ0qwx/ZXaQ==",
2879 | "dev": true
2880 | },
2881 | "unpipe": {
2882 | "version": "1.0.0",
2883 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
2884 | "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=",
2885 | "dev": true
2886 | },
2887 | "uri-js": {
2888 | "version": "4.2.2",
2889 | "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz",
2890 | "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==",
2891 | "dev": true,
2892 | "requires": {
2893 | "punycode": "^2.1.0"
2894 | }
2895 | },
2896 | "utils-merge": {
2897 | "version": "1.0.1",
2898 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
2899 | "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=",
2900 | "dev": true
2901 | },
2902 | "uuid": {
2903 | "version": "3.4.0",
2904 | "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
2905 | "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==",
2906 | "dev": true
2907 | },
2908 | "valid-url": {
2909 | "version": "1.0.9",
2910 | "resolved": "https://registry.npmjs.org/valid-url/-/valid-url-1.0.9.tgz",
2911 | "integrity": "sha1-HBRHm0DxOXp1eC8RXkCGRHQzogA=",
2912 | "dev": true
2913 | },
2914 | "vary": {
2915 | "version": "1.1.2",
2916 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
2917 | "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=",
2918 | "dev": true
2919 | },
2920 | "verror": {
2921 | "version": "1.10.0",
2922 | "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
2923 | "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
2924 | "dev": true,
2925 | "requires": {
2926 | "assert-plus": "^1.0.0",
2927 | "core-util-is": "1.0.2",
2928 | "extsprintf": "^1.2.0"
2929 | }
2930 | },
2931 | "wordwrapjs": {
2932 | "version": "3.0.0",
2933 | "resolved": "https://registry.npmjs.org/wordwrapjs/-/wordwrapjs-3.0.0.tgz",
2934 | "integrity": "sha512-mO8XtqyPvykVCsrwj5MlOVWvSnCdT+C+QVbm6blradR7JExAhbkZ7hZ9A+9NUtwzSqrlUo9a67ws0EiILrvRpw==",
2935 | "dev": true,
2936 | "requires": {
2937 | "reduce-flatten": "^1.0.1",
2938 | "typical": "^2.6.1"
2939 | },
2940 | "dependencies": {
2941 | "typical": {
2942 | "version": "2.6.1",
2943 | "resolved": "https://registry.npmjs.org/typical/-/typical-2.6.1.tgz",
2944 | "integrity": "sha1-XAgOXWYcu+OCWdLnCjxyU+hziB0=",
2945 | "dev": true
2946 | }
2947 | }
2948 | }
2949 | }
2950 | }
2951 |
--------------------------------------------------------------------------------
/codelabs/intro-to-webgl/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "intro-to-webgl",
3 | "version": "1.0.0",
4 | "description": "Sample codebits from « Intro to WebGL with Three.js » (http://davidscottlyons.com/threejs-intro/)",
5 | "main": "index.js",
6 | "scripts": {
7 | "start": "prpl-server --root . --config config/prpl-server.json",
8 | "test": "echo \"Error: no test specified\" && exit 1"
9 | },
10 | "repository": {
11 | "type": "git",
12 | "url": "https://github.com/olange/learning-webgl/tree/master/codelabs/intro-to-webgl"
13 | },
14 | "keywords": [
15 | "three",
16 | "webgl",
17 | "tutorial"
18 | ],
19 | "author": "Olivier Lange",
20 | "license": "CC-BY-SA-4.0",
21 | "dependencies": {
22 | "orbit-controls-es6": "^2.0.1",
23 | "three": "^0.114.0"
24 | },
25 | "devDependencies": {
26 | "prpl-server": "^1.2.0"
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/experiments/00-template/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 | .DS_Store
3 |
--------------------------------------------------------------------------------
/experiments/00-template/images/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/olange/learning-webgl/5d701dbc0788d042183642830fb4adb6f3a820ac/experiments/00-template/images/favicon.ico
--------------------------------------------------------------------------------
/experiments/00-template/images/manifest/icon-144x144.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/olange/learning-webgl/5d701dbc0788d042183642830fb4adb6f3a820ac/experiments/00-template/images/manifest/icon-144x144.png
--------------------------------------------------------------------------------
/experiments/00-template/images/manifest/icon-192x192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/olange/learning-webgl/5d701dbc0788d042183642830fb4adb6f3a820ac/experiments/00-template/images/manifest/icon-192x192.png
--------------------------------------------------------------------------------
/experiments/00-template/images/manifest/icon-48x48.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/olange/learning-webgl/5d701dbc0788d042183642830fb4adb6f3a820ac/experiments/00-template/images/manifest/icon-48x48.png
--------------------------------------------------------------------------------
/experiments/00-template/images/manifest/icon-512x512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/olange/learning-webgl/5d701dbc0788d042183642830fb4adb6f3a820ac/experiments/00-template/images/manifest/icon-512x512.png
--------------------------------------------------------------------------------
/experiments/00-template/images/manifest/icon-72x72.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/olange/learning-webgl/5d701dbc0788d042183642830fb4adb6f3a820ac/experiments/00-template/images/manifest/icon-72x72.png
--------------------------------------------------------------------------------
/experiments/00-template/images/manifest/icon-96x96.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/olange/learning-webgl/5d701dbc0788d042183642830fb4adb6f3a820ac/experiments/00-template/images/manifest/icon-96x96.png
--------------------------------------------------------------------------------
/experiments/00-template/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Petit Atelier showcase
6 |
7 |
8 |
9 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
65 |
66 |
67 |
70 |
71 | Three
72 |
73 |
74 |
75 |
--------------------------------------------------------------------------------
/experiments/00-template/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Organize",
3 | "short_name": "Organize",
4 | "description": "Organize documents, using automatic classification, learning from your hints",
5 | "start_url": "/",
6 | "display": "standalone",
7 | "theme_color": "#3f51b5",
8 | "background_color": "#3f51b5",
9 | "icons": [
10 | {
11 | "src": "images/manifest/icon-192x192.png",
12 | "sizes": "192x192",
13 | "type": "image/png"
14 | },
15 | {
16 | "src": "images/manifest/icon-512x512.png",
17 | "sizes": "512x512",
18 | "type": "image/png"
19 | }
20 | ]
21 | }
22 |
--------------------------------------------------------------------------------
/experiments/00-template/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "00-template",
3 | "version": "1.0.0",
4 | "lockfileVersion": 2,
5 | "requires": true,
6 | "packages": {
7 | "": {
8 | "name": "00-template",
9 | "version": "1.0.0",
10 | "license": "AGPL-3.0-or-later",
11 | "dependencies": {
12 | "three": "^0.141.0"
13 | }
14 | },
15 | "node_modules/three": {
16 | "version": "0.141.0",
17 | "resolved": "https://registry.npmjs.org/three/-/three-0.141.0.tgz",
18 | "integrity": "sha512-JaSDAPWuk4RTzG5BYRQm8YZbERUxTfTDVouWgHMisS2to4E5fotMS9F2zPFNOIJyEFTTQDDKPpsgZVThKU3pXA=="
19 | }
20 | },
21 | "dependencies": {
22 | "three": {
23 | "version": "0.141.0",
24 | "resolved": "https://registry.npmjs.org/three/-/three-0.141.0.tgz",
25 | "integrity": "sha512-JaSDAPWuk4RTzG5BYRQm8YZbERUxTfTDVouWgHMisS2to4E5fotMS9F2zPFNOIJyEFTTQDDKPpsgZVThKU3pXA=="
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/experiments/00-template/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "00-template",
3 | "version": "1.0.0",
4 | "description": "An experiment with WebGL and Three.js",
5 | "main": "index.html",
6 | "scripts": {
7 | "start": "python -m SimpleHTTPServer",
8 | "test": "echo \"Error: no test specified\" && exit 1"
9 | },
10 | "repository": {
11 | "type": "git",
12 | "url": "git+ssh://git@github.com:olange/learning-webgl.git"
13 | },
14 | "author": "Olivier Lange",
15 | "license": "AGPL-3.0-or-later",
16 | "bugs": {
17 | "url": "https://github.com/olange/learning-webgl/issues"
18 | },
19 | "homepage": "https://github.com/olange/learning-webgl#readme",
20 | "dependencies": {
21 | "three": "^0.141.0"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/experiments/00-template/service-worker.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @license
3 | * Copyright (c) 2016 The Polymer Project Authors. All rights reserved.
4 | * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
5 | * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
6 | * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
7 | * Code distributed by Google as part of the polymer project is also
8 | * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
9 | */
10 |
11 | console.info('Service worker disabled for development, will be generated at build time.');
12 |
--------------------------------------------------------------------------------
/experiments/00-template/src/components/anim.js:
--------------------------------------------------------------------------------
1 | var camera, scene, renderer;
2 | var geometry, material, mesh;
3 |
4 | init();
5 | animate();
6 |
7 | function init() {
8 |
9 | camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 0.01, 10 );
10 | camera.position.z = 1;
11 |
12 | scene = new THREE.Scene();
13 |
14 | geometry = new THREE.BoxGeometry( 0.2, 0.2, 0.2 );
15 | material = new THREE.MeshNormalMaterial();
16 |
17 | mesh = new THREE.Mesh( geometry, material );
18 | scene.add( mesh );
19 |
20 | renderer = new THREE.WebGLRenderer( { antialias: true } );
21 | renderer.setSize( window.innerWidth, window.innerHeight );
22 | document.body.appendChild( renderer.domElement );
23 |
24 | }
25 |
26 | function animate() {
27 | requestAnimationFrame( animate );
28 |
29 | mesh.rotation.x += 0.01;
30 | mesh.rotation.y += 0.02;
31 |
32 | renderer.render( scene, camera );
33 | }
34 |
35 | // eof
--------------------------------------------------------------------------------
/experiments/01-webgl-component/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 | .DS_Store
3 |
--------------------------------------------------------------------------------
/experiments/01-webgl-component/images/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/olange/learning-webgl/5d701dbc0788d042183642830fb4adb6f3a820ac/experiments/01-webgl-component/images/favicon.ico
--------------------------------------------------------------------------------
/experiments/01-webgl-component/images/manifest/icon-144x144.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/olange/learning-webgl/5d701dbc0788d042183642830fb4adb6f3a820ac/experiments/01-webgl-component/images/manifest/icon-144x144.png
--------------------------------------------------------------------------------
/experiments/01-webgl-component/images/manifest/icon-192x192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/olange/learning-webgl/5d701dbc0788d042183642830fb4adb6f3a820ac/experiments/01-webgl-component/images/manifest/icon-192x192.png
--------------------------------------------------------------------------------
/experiments/01-webgl-component/images/manifest/icon-48x48.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/olange/learning-webgl/5d701dbc0788d042183642830fb4adb6f3a820ac/experiments/01-webgl-component/images/manifest/icon-48x48.png
--------------------------------------------------------------------------------
/experiments/01-webgl-component/images/manifest/icon-512x512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/olange/learning-webgl/5d701dbc0788d042183642830fb4adb6f3a820ac/experiments/01-webgl-component/images/manifest/icon-512x512.png
--------------------------------------------------------------------------------
/experiments/01-webgl-component/images/manifest/icon-72x72.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/olange/learning-webgl/5d701dbc0788d042183642830fb4adb6f3a820ac/experiments/01-webgl-component/images/manifest/icon-72x72.png
--------------------------------------------------------------------------------
/experiments/01-webgl-component/images/manifest/icon-96x96.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/olange/learning-webgl/5d701dbc0788d042183642830fb4adb6f3a820ac/experiments/01-webgl-component/images/manifest/icon-96x96.png
--------------------------------------------------------------------------------
/experiments/01-webgl-component/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Experiment 01 – Three in a Web Component
6 |
7 |
8 |
9 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
66 |
67 |
68 |
71 |
72 |
73 | Experience 01
74 | Three in a Web Component
75 |
76 |
77 |
78 |
79 |
80 |
81 |
--------------------------------------------------------------------------------
/experiments/01-webgl-component/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Organize",
3 | "short_name": "Organize",
4 | "description": "Organize documents, using automatic classification, learning from your hints",
5 | "start_url": "/",
6 | "display": "standalone",
7 | "theme_color": "#3f51b5",
8 | "background_color": "#3f51b5",
9 | "icons": [
10 | {
11 | "src": "images/manifest/icon-192x192.png",
12 | "sizes": "192x192",
13 | "type": "image/png"
14 | },
15 | {
16 | "src": "images/manifest/icon-512x512.png",
17 | "sizes": "512x512",
18 | "type": "image/png"
19 | }
20 | ]
21 | }
22 |
--------------------------------------------------------------------------------
/experiments/01-webgl-component/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "01-webgl-component",
3 | "version": "1.0.0",
4 | "description": "An experiment with WebGL and Three.js",
5 | "main": "index.html",
6 | "scripts": {
7 | "start": "polymer serve --port 8001",
8 | "test": "echo \"Error: no test specified\" && exit 1"
9 | },
10 | "repository": {
11 | "type": "git",
12 | "url": "git+ssh://git@github.com/olange/learning-webgl.git"
13 | },
14 | "author": "Olivier Lange",
15 | "license": "AGPL-3.0-or-later",
16 | "bugs": {
17 | "url": "https://github.com/olange/learning-webgl/issues"
18 | },
19 | "homepage": "https://github.com/olange/learning-webgl#readme",
20 | "dependencies": {
21 | "@polymer/lit-element": "^0.7.1",
22 | "three": "^0.141.0"
23 | },
24 | "devDependencies": {
25 | "@webcomponents/webcomponentsjs": "^2.6.0",
26 | "polymer-cli": "^1.9.11"
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/experiments/01-webgl-component/polymer.json:
--------------------------------------------------------------------------------
1 | {
2 | "entrypoint": "index.html",
3 | "shell": "src/components/my-app.js",
4 | "sources": [
5 | "images/**/*"
6 | ],
7 | "extraDependencies": [
8 | "manifest.json",
9 | "node_modules/@webcomponents/webcomponentsjs/**"
10 | ],
11 | "moduleResolution": "node",
12 | "npm": true
13 | }
14 |
--------------------------------------------------------------------------------
/experiments/01-webgl-component/service-worker.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @license
3 | * Copyright (c) 2016 The Polymer Project Authors. All rights reserved.
4 | * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
5 | * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
6 | * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
7 | * Code distributed by Google as part of the polymer project is also
8 | * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
9 | */
10 |
11 | console.info('Service worker disabled for development, will be generated at build time.');
12 |
--------------------------------------------------------------------------------
/experiments/01-webgl-component/src/components/my-anim.js:
--------------------------------------------------------------------------------
1 | import { LitElement, html } from "@polymer/lit-element";
2 | import * as THREE from "three";
3 |
4 | class MyAnim extends LitElement {
5 | render() {
6 | console.log( "render()");
7 | return html`
8 |
13 |
14 |
15 |
16 |
17 | `;
18 | }
19 |
20 | static get properties() {
21 | return {
22 | interval: { type: Number }
23 | };
24 | }
25 |
26 | constructor() {
27 | console.log( "constructor()");
28 | super();
29 |
30 | // Element attributes
31 | this.interval = 10.0; // ms
32 |
33 | // Element private properties
34 | this.camera = null;
35 | this.scene = null;
36 | this.renderer = null;
37 | this.mesh = null
38 |
39 | this.canvasElement = null;
40 | this.lastTime = null;
41 |
42 | this._boundAnimateFn = this.animate.bind( this);
43 | }
44 |
45 | firstUpdated() {
46 | console.log( "firstUpdated()");
47 | this.canvasElement = this.shadowRoot.getElementById( "animation");
48 | this.init();
49 | this.animate();
50 | }
51 |
52 | init() {
53 | console.log( "init()");
54 | const displayWidth = this.canvasElement.clientWidth;
55 | const displayHeight = this.canvasElement.clientHeight;
56 | const displayRatio = displayWidth / displayHeight;
57 |
58 | this.camera = new THREE.PerspectiveCamera( 70, displayRatio, 0.01, 10);
59 | this.camera.position.z = 1;
60 |
61 | const geometry = new THREE.BoxGeometry( 0.2, 0.2, 0.2);
62 | const material = new THREE.MeshNormalMaterial();
63 | this.mesh = new THREE.Mesh( geometry, material);
64 |
65 | this.scene = new THREE.Scene();
66 | this.scene.add( this.mesh);
67 |
68 | this.renderer = new THREE.WebGLRenderer(
69 | { antialias: true, canvas: this.canvasElement });
70 | }
71 |
72 | resize() {
73 | const displayWidth = this.canvasElement.clientWidth;
74 | const displayHeight = this.canvasElement.clientHeight;
75 | const displayRatio = displayWidth / displayHeight;
76 | console.log( `resize() to ${displayWidth}x${displayHeight} (1:${displayRatio})`);
77 | this.camera.aspect = displayRatio;
78 | this.camera.updateProjectionMatrix();
79 | this.renderer.setSize( displayWidth, displayHeight, false);
80 | }
81 |
82 | needsResize() {
83 | const displayWidth = this.canvasElement.clientWidth;
84 | const displayHeight = this.canvasElement.clientHeight;
85 | const renderSize = this.renderer.getSize();
86 | return( renderSize.width != displayWidth || renderSize.height != displayHeight);
87 | }
88 |
89 | updateScene( time) {
90 | this.mesh.rotation.x += 0.01;
91 | this.mesh.rotation.y += 0.02;
92 | this.mesh.position.x = 0.5 * Math.cos( time / 1500.0);
93 | this.mesh.position.y = 0.5 * Math.sin( time / 1500.0);
94 | }
95 |
96 | animate( time) {
97 | const firstTime = typeof time === "undefined";
98 | const currTime = firstTime ? 0.0 : time;
99 |
100 | if( firstTime || this.needsResize.call( this)) {
101 | this.resize.call( this);
102 | }
103 |
104 | this.updateScene.call( this, currTime);
105 |
106 | if( firstTime || time - this.lastTime > this.interval) {
107 | this.renderer.render( this.scene, this.camera);
108 | this.lastTime = currTime;
109 | }
110 |
111 | window.requestAnimationFrame( this._boundAnimateFn);
112 | }
113 | }
114 |
115 | window.customElements.define( "my-anim", MyAnim);
116 |
117 | // eof
--------------------------------------------------------------------------------
/experiments/02-webgl-subcomponent/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 | .DS_Store
3 |
--------------------------------------------------------------------------------
/experiments/02-webgl-subcomponent/images/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/olange/learning-webgl/5d701dbc0788d042183642830fb4adb6f3a820ac/experiments/02-webgl-subcomponent/images/favicon.ico
--------------------------------------------------------------------------------
/experiments/02-webgl-subcomponent/images/manifest/icon-144x144.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/olange/learning-webgl/5d701dbc0788d042183642830fb4adb6f3a820ac/experiments/02-webgl-subcomponent/images/manifest/icon-144x144.png
--------------------------------------------------------------------------------
/experiments/02-webgl-subcomponent/images/manifest/icon-192x192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/olange/learning-webgl/5d701dbc0788d042183642830fb4adb6f3a820ac/experiments/02-webgl-subcomponent/images/manifest/icon-192x192.png
--------------------------------------------------------------------------------
/experiments/02-webgl-subcomponent/images/manifest/icon-48x48.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/olange/learning-webgl/5d701dbc0788d042183642830fb4adb6f3a820ac/experiments/02-webgl-subcomponent/images/manifest/icon-48x48.png
--------------------------------------------------------------------------------
/experiments/02-webgl-subcomponent/images/manifest/icon-512x512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/olange/learning-webgl/5d701dbc0788d042183642830fb4adb6f3a820ac/experiments/02-webgl-subcomponent/images/manifest/icon-512x512.png
--------------------------------------------------------------------------------
/experiments/02-webgl-subcomponent/images/manifest/icon-72x72.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/olange/learning-webgl/5d701dbc0788d042183642830fb4adb6f3a820ac/experiments/02-webgl-subcomponent/images/manifest/icon-72x72.png
--------------------------------------------------------------------------------
/experiments/02-webgl-subcomponent/images/manifest/icon-96x96.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/olange/learning-webgl/5d701dbc0788d042183642830fb4adb6f3a820ac/experiments/02-webgl-subcomponent/images/manifest/icon-96x96.png
--------------------------------------------------------------------------------
/experiments/02-webgl-subcomponent/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Experiment 02 – Three in a Web Component with subcomponents
6 |
7 |
9 |
10 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
67 |
68 |
69 |
70 |
71 |
72 | Experience 02
73 | Three in a Web Component
with two subcomponents
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
--------------------------------------------------------------------------------
/experiments/02-webgl-subcomponent/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Organize",
3 | "short_name": "Organize",
4 | "description": "Organize documents, using automatic classification, learning from your hints",
5 | "start_url": "/",
6 | "display": "standalone",
7 | "theme_color": "#3f51b5",
8 | "background_color": "#3f51b5",
9 | "icons": [
10 | {
11 | "src": "images/manifest/icon-192x192.png",
12 | "sizes": "192x192",
13 | "type": "image/png"
14 | },
15 | {
16 | "src": "images/manifest/icon-512x512.png",
17 | "sizes": "512x512",
18 | "type": "image/png"
19 | }
20 | ]
21 | }
22 |
--------------------------------------------------------------------------------
/experiments/02-webgl-subcomponent/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "02-webgl-subcomponent",
3 | "version": "1.0.0",
4 | "description": "An experiment with WebGL and Three.js",
5 | "main": "index.html",
6 | "scripts": {
7 | "start": "polymer serve --port 8001",
8 | "test": "echo \"Error: no test specified\" && exit 1"
9 | },
10 | "repository": {
11 | "type": "git",
12 | "url": "git+ssh://git@github.com/olange/learning-webgl.git"
13 | },
14 | "author": "Olivier Lange",
15 | "license": "AGPL-3.0-or-later",
16 | "bugs": {
17 | "url": "https://github.com/olange/learning-webgl/issues"
18 | },
19 | "homepage": "https://github.com/olange/learning-webgl#readme",
20 | "dependencies": {
21 | "@polymer/lit-element": "^0.7.1",
22 | "three": "^0.141.0"
23 | },
24 | "devDependencies": {
25 | "@webcomponents/webcomponentsjs": "^2.2.4",
26 | "polymer-cli": "^1.9.11"
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/experiments/02-webgl-subcomponent/polymer.json:
--------------------------------------------------------------------------------
1 | {
2 | "entrypoint": "index.html",
3 | "shell": "src/components/my-app.js",
4 | "sources": [
5 | "images/**/*"
6 | ],
7 | "extraDependencies": [
8 | "manifest.json",
9 | "node_modules/@webcomponents/webcomponentsjs/**"
10 | ],
11 | "moduleResolution": "node",
12 | "npm": true
13 | }
14 |
--------------------------------------------------------------------------------
/experiments/02-webgl-subcomponent/service-worker.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @license
3 | * Copyright (c) 2016 The Polymer Project Authors. All rights reserved.
4 | * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
5 | * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
6 | * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
7 | * Code distributed by Google as part of the polymer project is also
8 | * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
9 | */
10 |
11 | console.info('Service worker disabled for development, will be generated at build time.');
12 |
--------------------------------------------------------------------------------
/experiments/02-webgl-subcomponent/src/components/my-anim-sub.js:
--------------------------------------------------------------------------------
1 | import { LitElement, html } from "@polymer/lit-element";
2 | import * as THREE from "three";
3 |
4 | class MyAnimSub extends LitElement {
5 | render() {
6 | console.log( "my-anim-sub › render()");
7 | return html`
8 |
13 |
14 | Subcomponent ${this.name} with a wireframe sphere
15 |
16 |
17 | `;
18 | }
19 |
20 | static get properties() {
21 | return {
22 | name: { type: String, reflect: true },
23 | color: { type: Number, reflect: true },
24 | speed: { type: Number, reflect: true },
25 |
26 | scene: { type: Object, reflect: false },
27 | camera: { type: Object, reflect: false },
28 | renderer: { type: Object, reflect: false }
29 | };
30 | }
31 |
32 | constructor() {
33 | console.log( "my-anim-sub › constructor()");
34 | super();
35 |
36 | this.name = "";
37 | this.color = 0x6699ff;
38 | this.speed = 1;
39 | this.scene = null;
40 | this.camera = null;
41 | this.renderer = null;
42 | this._parentAnim = null;
43 | this._lines = null;
44 | this._boundAnimateFn = this.animate.bind( this);
45 | }
46 |
47 | firstUpdated() {
48 | console.log( "my-anim-sub › firstUpdated()");
49 | this.animate();
50 | }
51 |
52 | connectedCallback() {
53 | console.log( "my-anim-sub › connectedCallback()");
54 | super.connectedCallback();
55 |
56 | // Get reference to parent animation, and its scene, camera and renderer
57 | this._parentAnim = this.closest( "my-anim");
58 | if( !( this._parentAnim instanceof HTMLElement)) {
59 | throw new Error( " element needs a element within its ancestors");
60 | }
61 | this.scene = this._parentAnim.scene;
62 | this.camera = this._parentAnim.camera;
63 | this.renderer = this._parentAnim.renderer;
64 |
65 | // @see https://threejs.org/docs/#api/en/geometries/SphereBufferGeometry
66 | const geometry = new THREE.SphereBufferGeometry( 0.25, 0.25, 0.25);
67 | // @see https://threejs.org/docs/#api/en/geometries/WireframeGeometry
68 | const wireframe = new THREE.WireframeGeometry( geometry);
69 | // @see https://threejs.org/docs/#api/en/materials/LineBasicMaterial
70 | const material = new THREE.LineBasicMaterial(
71 | { color: this.color, depthTest: false, opacity: 0.8, transparent: true });
72 | // @see https://threejs.org/docs/#api/en/objects/LineSegments
73 | this._lines = new THREE.LineSegments( wireframe, material);
74 |
75 | this.scene.add( this._lines);
76 | }
77 |
78 | disconnectedCallback() {
79 | console.log( "my-anim-sub › disconnectedCallback()");
80 |
81 | this.scene.remove( this._lines);
82 | this._lines.material.dispose();
83 | this._lines.geometry.dispose();
84 | this._lines = null;
85 |
86 | this._parentAnim = null;
87 | this.scene = null;
88 | this.camera = null;
89 | this.renderer = null;
90 |
91 | super.disconnectedCallback();
92 | }
93 |
94 | animate( time) {
95 | this._lines.rotation.x += 0.001 * this.speed;
96 | this._lines.rotation.y += 0.010 * this.speed;
97 | this._lines.rotation.z += 0.005 * this.speed;
98 | window.requestAnimationFrame( this._boundAnimateFn);
99 | }
100 | }
101 |
102 | window.customElements.define( "my-anim-sub", MyAnimSub);
103 |
104 | // eof
--------------------------------------------------------------------------------
/experiments/02-webgl-subcomponent/src/components/my-anim.js:
--------------------------------------------------------------------------------
1 | import { LitElement, html } from "@polymer/lit-element";
2 | import * as THREE from "three";
3 |
4 | class MyAnim extends LitElement {
5 | render() {
6 | console.log( "my-anim › render()");
7 | return html`
8 |
13 |
14 |
15 |
16 |
17 | `;
18 | }
19 |
20 | static get properties() {
21 | return {
22 | // Observed properties, reflected to attributes
23 | interval: { type: Number, reflect: true },
24 | // Observed properties, not reflected to attributes
25 | scene: { type: Object, reflect: false },
26 | camera: { type: Object, reflect: false },
27 | renderer: { type: Object, reflect: false }
28 | };
29 | }
30 |
31 | constructor() {
32 | console.log( "my-anim › constructor()");
33 | super();
34 |
35 | // Element public properties
36 | this.interval = 10.0; // ms
37 | this.camera = null;
38 | this.scene = null;
39 | this.renderer = null;
40 |
41 | // Element private properties
42 | this._canvasElement = null;
43 | this._lastTime = null;
44 | this._mesh = null
45 | this._boundAnimateFn = this.animate.bind( this);
46 | }
47 |
48 | firstUpdated() {
49 | console.log( "my-anim › firstUpdated()");
50 | this._canvasElement = this.shadowRoot.getElementById( "animation");
51 | this.init();
52 | this.animate();
53 | }
54 |
55 | init() {
56 | console.log( "my-anim › init()");
57 | const displayWidth = this._canvasElement.clientWidth;
58 | const displayHeight = this._canvasElement.clientHeight;
59 | const displayRatio = displayWidth / displayHeight;
60 |
61 | this.camera = new THREE.PerspectiveCamera( 70, displayRatio, 0.01, 10);
62 | this.camera.position.z = 1;
63 |
64 | const geometry = new THREE.BoxGeometry( 0.2, 0.2, 0.2);
65 | const material = new THREE.MeshNormalMaterial();
66 | this._mesh = new THREE.Mesh( geometry, material);
67 |
68 | this.scene = new THREE.Scene();
69 | this.scene.add( this._mesh);
70 |
71 | this.renderer = new THREE.WebGLRenderer(
72 | { antialias: true, canvas: this._canvasElement });
73 | }
74 |
75 | resize() {
76 | const displayWidth = this._canvasElement.clientWidth;
77 | const displayHeight = this._canvasElement.clientHeight;
78 | const displayRatio = displayWidth / displayHeight;
79 | console.log( `my-anim › resize() to ${displayWidth}x${displayHeight} (1:${displayRatio})`);
80 | this.camera.aspect = displayRatio;
81 | this.camera.updateProjectionMatrix();
82 | this.renderer.setSize( displayWidth, displayHeight, false);
83 | }
84 |
85 | needsResize() {
86 | const displayWidth = this._canvasElement.clientWidth;
87 | const displayHeight = this._canvasElement.clientHeight;
88 | const renderSize = this.renderer.getSize();
89 | return( renderSize.width != displayWidth || renderSize.height != displayHeight);
90 | }
91 |
92 | updateScene( time) {
93 | this._mesh.rotation.x += 0.01;
94 | this._mesh.rotation.y += 0.02;
95 | this._mesh.position.x = 0.5 * Math.cos( time / 1500.0);
96 | this._mesh.position.y = 0.5 * Math.sin( time / 1500.0);
97 | }
98 |
99 | animate( time) {
100 | const firstTime = typeof time === "undefined";
101 | const currTime = firstTime ? 0.0 : time;
102 |
103 | if( firstTime || this.needsResize.call( this)) {
104 | this.resize.call( this);
105 | }
106 |
107 | this.updateScene.call( this, currTime);
108 |
109 | if( firstTime || time - this._lastTime > this.interval) {
110 | this.renderer.render( this.scene, this.camera);
111 | this._lastTime = currTime;
112 | }
113 |
114 | window.requestAnimationFrame( this._boundAnimateFn);
115 | }
116 | }
117 |
118 | window.customElements.define( "my-anim", MyAnim);
119 |
120 | // eof
--------------------------------------------------------------------------------
/experiments/03-webgl-layers/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 | .DS_Store
3 |
--------------------------------------------------------------------------------
/experiments/03-webgl-layers/images/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/olange/learning-webgl/5d701dbc0788d042183642830fb4adb6f3a820ac/experiments/03-webgl-layers/images/favicon.ico
--------------------------------------------------------------------------------
/experiments/03-webgl-layers/images/manifest/icon-144x144.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/olange/learning-webgl/5d701dbc0788d042183642830fb4adb6f3a820ac/experiments/03-webgl-layers/images/manifest/icon-144x144.png
--------------------------------------------------------------------------------
/experiments/03-webgl-layers/images/manifest/icon-192x192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/olange/learning-webgl/5d701dbc0788d042183642830fb4adb6f3a820ac/experiments/03-webgl-layers/images/manifest/icon-192x192.png
--------------------------------------------------------------------------------
/experiments/03-webgl-layers/images/manifest/icon-48x48.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/olange/learning-webgl/5d701dbc0788d042183642830fb4adb6f3a820ac/experiments/03-webgl-layers/images/manifest/icon-48x48.png
--------------------------------------------------------------------------------
/experiments/03-webgl-layers/images/manifest/icon-512x512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/olange/learning-webgl/5d701dbc0788d042183642830fb4adb6f3a820ac/experiments/03-webgl-layers/images/manifest/icon-512x512.png
--------------------------------------------------------------------------------
/experiments/03-webgl-layers/images/manifest/icon-72x72.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/olange/learning-webgl/5d701dbc0788d042183642830fb4adb6f3a820ac/experiments/03-webgl-layers/images/manifest/icon-72x72.png
--------------------------------------------------------------------------------
/experiments/03-webgl-layers/images/manifest/icon-96x96.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/olange/learning-webgl/5d701dbc0788d042183642830fb4adb6f3a820ac/experiments/03-webgl-layers/images/manifest/icon-96x96.png
--------------------------------------------------------------------------------
/experiments/03-webgl-layers/images/screenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/olange/learning-webgl/5d701dbc0788d042183642830fb4adb6f3a820ac/experiments/03-webgl-layers/images/screenshot.png
--------------------------------------------------------------------------------
/experiments/03-webgl-layers/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Experiment 03 – Layers
6 |
7 |
8 |
9 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
66 |
67 |
68 |
69 |
70 |
71 | Experience 03
72 | Layers with holes
73 |
75 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
--------------------------------------------------------------------------------
/experiments/03-webgl-layers/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Organize",
3 | "short_name": "Organize",
4 | "description": "Organize documents, using automatic classification, learning from your hints",
5 | "start_url": "/",
6 | "display": "standalone",
7 | "theme_color": "#3f51b5",
8 | "background_color": "#3f51b5",
9 | "icons": [
10 | {
11 | "src": "images/manifest/icon-192x192.png",
12 | "sizes": "192x192",
13 | "type": "image/png"
14 | },
15 | {
16 | "src": "images/manifest/icon-512x512.png",
17 | "sizes": "512x512",
18 | "type": "image/png"
19 | }
20 | ]
21 | }
22 |
--------------------------------------------------------------------------------
/experiments/03-webgl-layers/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "03-webgl-layers",
3 | "version": "1.0.0",
4 | "description": "Layers on top of each other, as WebComponents in WebGL and Three.js",
5 | "main": "index.html",
6 | "scripts": {
7 | "start": "polymer serve --port 8001",
8 | "test": "echo \"Error: no test specified\" && exit 1"
9 | },
10 | "repository": {
11 | "type": "git",
12 | "url": "git+ssh://git@github.com/olange/learning-webgl.git"
13 | },
14 | "author": "Olivier Lange",
15 | "license": "AGPL-3.0-or-later",
16 | "bugs": {
17 | "url": "https://github.com/olange/learning-webgl/issues"
18 | },
19 | "homepage": "https://github.com/olange/learning-webgl#readme",
20 | "dependencies": {
21 | "@polymer/lit-element": "^0.7.1",
22 | "three": "^0.141.0"
23 | },
24 | "devDependencies": {
25 | "@webcomponents/webcomponentsjs": "^2.6.0",
26 | "polymer-cli": "^1.9.11"
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/experiments/03-webgl-layers/polymer.json:
--------------------------------------------------------------------------------
1 | {
2 | "entrypoint": "index.html",
3 | "shell": "src/components/my-app.js",
4 | "sources": [
5 | "images/**/*"
6 | ],
7 | "extraDependencies": [
8 | "manifest.json",
9 | "node_modules/@webcomponents/webcomponentsjs/**"
10 | ],
11 | "moduleResolution": "node",
12 | "npm": true
13 | }
14 |
--------------------------------------------------------------------------------
/experiments/03-webgl-layers/service-worker.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @license
3 | * Copyright (c) 2016 The Polymer Project Authors. All rights reserved.
4 | * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
5 | * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
6 | * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
7 | * Code distributed by Google as part of the polymer project is also
8 | * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
9 | */
10 |
11 | console.info('Service worker disabled for development, will be generated at build time.');
12 |
--------------------------------------------------------------------------------
/experiments/03-webgl-layers/src/components/my-anim-plane.js:
--------------------------------------------------------------------------------
1 | import { LitElement, html } from "@polymer/lit-element";
2 | import * as THREE from "three";
3 |
4 | class MyAnimPlane extends LitElement {
5 | render() {
6 | console.log( "my-anim-plane › render()");
7 | return html`
8 |
13 |
14 | Subcomponent ${this.name} with a rotating plane geometry
15 |
16 |
17 | `;
18 | }
19 |
20 | static get properties() {
21 | return {
22 | name: { type: String, reflect: true },
23 | color: { type: Number, reflect: true },
24 | speed: { type: Number, reflect: true },
25 | size: { type: Number, reflect: true },
26 | segments: { type: Number, reflect: true },
27 | offset: { type: Number, reflect: true },
28 | rotation: { type: Number, reflect: true },
29 |
30 | scene: { type: Object, reflect: false },
31 | camera: { type: Object, reflect: false },
32 | renderer: { type: Object, reflect: false }
33 | };
34 | }
35 |
36 | static dropSomeFaces( geometry) {
37 | const geometryClone = geometry.clone();
38 | geometryClone.faces = geometryClone.faces.filter( _ => Math.random() > 0.2);
39 | geometryClone.elementsNeedUpdate = true;
40 | return geometryClone;
41 | }
42 |
43 | constructor() {
44 | console.log( "my-anim-plane › constructor()");
45 | super();
46 |
47 | this.name = "";
48 | this.color = 0xffff00;
49 | this.speed = 1;
50 | this.size = 1;
51 | this.segments = 2;
52 | this.offset = 0;
53 | this.rotation = 0;
54 |
55 | this.scene = null;
56 | this.camera = null;
57 | this.renderer = null;
58 | this._parentAnim = null;
59 |
60 | this._group = null;
61 |
62 | this._boundAnimateFn = this.animate.bind( this);
63 | }
64 |
65 | firstUpdated() {
66 | console.log( "my-anim-plane › firstUpdated()");
67 |
68 | const geometry = MyAnimPlane.dropSomeFaces(
69 | new THREE.PlaneGeometry( this.size, this.size, this.segments, this.segments));
70 | const wireframe = new THREE.WireframeGeometry( geometry);
71 |
72 | const lineMaterial = new THREE.LineBasicMaterial( { color: 0xffffff, depthTest: true, opacity: 0.65, transparent: true });
73 | const meshMaterial = new THREE.MeshBasicMaterial( { color: this.color, side: THREE.DoubleSide });
74 |
75 | const lineMesh = new THREE.LineSegments( wireframe, lineMaterial);
76 | const planeMesh = new THREE.Mesh( geometry, meshMaterial);
77 |
78 | this._group = new THREE.Group();
79 | this._group.add( lineMesh);
80 | this._group.add( planeMesh);
81 | this._group.rotation.x = THREE.Math.DEG2RAD * this.rotation;
82 | this._group.translateZ( this.offset);
83 |
84 | this.scene.add( this._group);
85 |
86 | this.animate();
87 | }
88 |
89 | connectedCallback() {
90 | console.log( "my-anim-plane › connectedCallback()");
91 | super.connectedCallback();
92 |
93 | // Get reference to parent animation, and its scene, camera and renderer
94 | this._parentAnim = this.closest( "my-anim");
95 | if( !( this._parentAnim instanceof HTMLElement)) {
96 | throw new Error( " element needs a element within its ancestors");
97 | }
98 | this.scene = this._parentAnim.scene;
99 | this.camera = this._parentAnim.camera;
100 | this.renderer = this._parentAnim.renderer;
101 | }
102 |
103 | disconnectedCallback() {
104 | console.log( "my-anim-plane › disconnectedCallback()");
105 |
106 | this.scene.remove( this._group);
107 | for( let mesh of this._group.children) {
108 | mesh.material.dispose();
109 | mesh.geometry.dispose();
110 | this._group.remove( mesh);
111 | }
112 | this._group = null;
113 |
114 | this._parentAnim = null;
115 | this.scene = null;
116 | this.camera = null;
117 | this.renderer = null;
118 |
119 | super.disconnectedCallback();
120 | }
121 |
122 | animate( time) {
123 | this._group.rotation.z = Math.sin( time * 0.0001) * this.speed;
124 | window.requestAnimationFrame( this._boundAnimateFn);
125 | }
126 | }
127 |
128 | window.customElements.define( "my-anim-plane", MyAnimPlane);
129 |
130 | // eof
--------------------------------------------------------------------------------
/experiments/03-webgl-layers/src/components/my-anim.js:
--------------------------------------------------------------------------------
1 | import { LitElement, html } from "@polymer/lit-element";
2 | import * as THREE from "three";
3 |
4 | class MyAnim extends LitElement {
5 | render() {
6 | console.log( "my-anim › render()");
7 | return html`
8 |
13 |
14 |
15 |
16 |
17 | `;
18 | }
19 |
20 | static get properties() {
21 | return {
22 | // Observed properties, reflected to attributes
23 | interval: { type: Number, reflect: true },
24 | // Observed properties, not reflected to attributes
25 | scene: { type: Object, reflect: false },
26 | camera: { type: Object, reflect: false },
27 | renderer: { type: Object, reflect: false }
28 | };
29 | }
30 |
31 | constructor() {
32 | console.log( "my-anim › constructor()");
33 | super();
34 |
35 | // Element public properties
36 | this.interval = 10.0; // ms
37 | this.camera = null;
38 | this.scene = null;
39 | this.renderer = null;
40 |
41 | // Element private properties
42 | this._canvasElement = null;
43 | this._lastTime = null;
44 | this._mesh = null
45 | this._boundAnimateFn = this.animate.bind( this);
46 | }
47 |
48 | firstUpdated() {
49 | console.log( "my-anim › firstUpdated()");
50 | this._canvasElement = this.shadowRoot.getElementById( "animation");
51 | this.init();
52 | this.animate();
53 | }
54 |
55 | init() {
56 | console.log( "my-anim › init()");
57 | const displayWidth = this._canvasElement.clientWidth;
58 | const displayHeight = this._canvasElement.clientHeight;
59 | const displayRatio = displayWidth / displayHeight;
60 |
61 | this.camera = new THREE.PerspectiveCamera( 70, displayRatio, 0.01, 10);
62 | this.camera.position.z = 1;
63 |
64 | const geometry = new THREE.BoxGeometry( 0.2, 0.2, 0.2);
65 | const material = new THREE.MeshNormalMaterial();
66 | this._mesh = new THREE.Mesh( geometry, material);
67 |
68 | this.scene = new THREE.Scene();
69 | this.scene.add( this._mesh);
70 |
71 | this.renderer = new THREE.WebGLRenderer(
72 | { antialias: true, canvas: this._canvasElement });
73 | }
74 |
75 | resize() {
76 | const displayWidth = this._canvasElement.clientWidth;
77 | const displayHeight = this._canvasElement.clientHeight;
78 | const displayRatio = displayWidth / displayHeight;
79 | console.log( `my-anim › resize() to ${displayWidth}x${displayHeight} (1:${displayRatio})`);
80 | this.camera.aspect = displayRatio;
81 | this.camera.updateProjectionMatrix();
82 | this.renderer.setSize( displayWidth, displayHeight, false);
83 | }
84 |
85 | needsResize() {
86 | const displayWidth = this._canvasElement.clientWidth;
87 | const displayHeight = this._canvasElement.clientHeight;
88 | const renderSize = this.renderer.getSize();
89 | return( renderSize.width != displayWidth || renderSize.height != displayHeight);
90 | }
91 |
92 | updateScene( time) {
93 | this._mesh.rotation.x += 0.01;
94 | this._mesh.rotation.y += 0.02;
95 | this._mesh.position.x = 0.5 * Math.cos( time / 1500.0);
96 | this._mesh.position.y = 0.5 * Math.sin( time / 1500.0);
97 | }
98 |
99 | animate( time) {
100 | const firstTime = typeof time === "undefined";
101 | const currTime = firstTime ? 0.0 : time;
102 |
103 | if( firstTime || this.needsResize.call( this)) {
104 | this.resize.call( this);
105 | }
106 |
107 | this.updateScene.call( this, currTime);
108 |
109 | if( firstTime || time - this._lastTime > this.interval) {
110 | this.renderer.render( this.scene, this.camera);
111 | this._lastTime = currTime;
112 | }
113 |
114 | window.requestAnimationFrame( this._boundAnimateFn);
115 | }
116 | }
117 |
118 | window.customElements.define( "my-anim", MyAnim);
119 |
120 | // eof
--------------------------------------------------------------------------------
/experiments/04-model-viewer/models/Astronaut.glb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/olange/learning-webgl/5d701dbc0788d042183642830fb4adb6f3a820ac/experiments/04-model-viewer/models/Astronaut.glb
--------------------------------------------------------------------------------
/experiments/05-three-app/MODEL.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Experiment 03 – Layers
6 |
7 |
8 |
9 |
10 |
19 |
20 |
21 |
22 |
23 |
24 |
27 |
30 |
32 |
33 |
36 |
39 |
40 |
41 |
42 |
43 | …
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
--------------------------------------------------------------------------------
/experiments/05-three-app/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "05-three-app",
3 | "version": "0.1.0",
4 | "description": "Sample web app using a collection of Three.js Web Components",
5 | "main": "MODEL.html",
6 | "scripts": {
7 | "start": "polyserve --npm --module-resolution=node --open-path=MODEL.html",
8 | "test": "echo \"Error: no test specified\" && exit 1"
9 | },
10 | "author": "Olivier Lange",
11 | "license": "BSD-3-Clause",
12 | "dependencies": {
13 | "@petitatelier/three-app": "^0.2.1",
14 | "@webcomponents/webcomponentsjs": "^2.6.0"
15 | },
16 | "devDependencies": {
17 | "polyserve": "^0.27.15"
18 | },
19 | "repository": {
20 | "type": "git",
21 | "url": "git+ssh://git@github.com/olange/learning-webgl.git"
22 | },
23 | "bugs": {
24 | "url": "https://github.com/olange/learning-webgl/issues"
25 | },
26 | "homepage": "https://github.com/olange/learning-webgl/tree/master/experiments/05-three-app#readme"
27 | }
28 |
--------------------------------------------------------------------------------
/workshops/shaders-primer/README.md:
--------------------------------------------------------------------------------
1 | # Shader Programming Primer — Real-Time Animation and Effects with GLSL
2 |
3 | [Mapping Festival 2019 · Workshop 6](https://2019.mappingfestival.com/workshop/376) · 23.05.2019 10h–19h
4 | by [Leander Herzog](https://www.shadertoy.com/user/lennyjpg) · Fonderie Kugler, Genève
5 |
6 | ## GLSL code fragments
7 |
8 | ### Shadertoy
9 |
10 | [Fragment 1](shadertoy-step1.glsl) ·
11 | [Fragment 2](shadertoy-step2.glsl) ·
12 | [Fragment 3](shadertoy-step3.glsl) ·
13 | [Fragment 4](shadertoy-step4.glsl) ·
14 | [Fragment 5](shadertoy-step5.glsl) ·
15 | [Fragment 6](shadertoy-step6.glsl) ·
16 | [Fragment 7](shadertoy-step7.glsl) ·
17 | [Truchet Tile](shadertoy-step8.glsl)
18 |
19 | ### Book Of Shaders Editor
20 |
21 | [Mouse move](bose-mouse-move.glsl) ·
22 | [Truchet Tile](bose-truchet-tile.glsl)
23 |
24 | ### Interesting samples
25 |
26 | [jutawzj](https://leanderherzog.ch/jutawzj/#code) ·
27 | [pjkarlik/TruchetTiles](https://github.com/pjkarlik/TruchetTiles) ·
28 | [THREE.MeshLine](https://www.clicktorelease.com/code/THREE.MeshLine/demo/index.html)
29 |
30 | ## Workshop resources
31 |
32 | * Leander's workshop codepen
33 | https://codepen.io/herlea/full/QRQbyL
34 | * Shadertoy
35 | https://www.shadertoy.com/new
36 | * Shader Programming Primer: Real-Time Animation and Effects with GLSL – these notes
37 | https://github.com/olange/learning-webgl/blob/master/workshops/shaders-primer/
38 |
39 | ## Recommended readings
40 |
41 | * [The Book of Shaders](https://thebookofshaders.com)
42 | by Patricio Gonzalez Vivo and Jen Lowe
43 |
44 | * [NVScene 2015: How to Create Content with Signed Distance Functions](https://www.youtube.com/watch?v=s8nFqwOho-s) by Johann Korndörfer, video 51mn.
45 |
46 | More on the [Learning section](https://codepen.io/herlea/pen/QRQbyL) of Leander's codepen.
47 |
48 | * [Writing GLSL with three.js — Part 1](https://medium.com/@pailhead011/writing-glsl-with-three-js-part-1-1acb1de77e5c) by Dusan Bosnjak
49 | * [Drawing Lines is Hard](https://mattdesl.svbtle.com/drawing-lines-is-hard) by Matt Deslauriers, 09.03.2015
50 |
51 | ## Resources we talked about while hacking
52 |
53 | * [Vanilla JS Shader template](https://codepen.io/desandro/details/GzvbJN)
54 | * [Shader Graph](https://unity.com/shader-graph) Unity Shadergraph tutorial
55 | * [hg_sdf](http://mercury.sexy/hg_sdf/) A GLSL library for building signed distance functions
56 | * [MadMapper › Tools › Material Editor](https://www.youtube.com/watch?v=UCnxYCFVrZw) and [MadMapper › Docs › Material Editor](http://madmapper.com/doc/materials/) mentioned by Boris Edelstein and tested with Mickaël
57 | * [ISF · Interactive Shader Format](https://www.interactiveshaderformat.com/) for describing Shader program inputs
58 | * [KodeLife](https://hexler.net/products/kodelife) Real-time GPU shader editor
59 | * [Algorave](https://algorave.com)
--------------------------------------------------------------------------------
/workshops/shaders-primer/bose-mouse-move.glsl:
--------------------------------------------------------------------------------
1 | // Title: Vanilla WebGL Shader - Basic mouse move
2 | // Author: Dave de Sandro
3 | // Source: https://codepen.io/desandro/pen/GzvbJN
4 |
5 | #ifdef GL_ES
6 | precision mediump float;
7 | #endif
8 |
9 | uniform vec2 u_resolution;
10 | uniform vec2 u_mouse;
11 | uniform float u_time;
12 |
13 | float lessCoord = min( u_resolution.x, u_resolution.y );
14 | vec2 resRatio = u_resolution / vec2( lessCoord );
15 |
16 | void main() {
17 | vec2 grad = abs( ( gl_FragCoord.xy - u_mouse ) / u_resolution * resRatio );
18 | // could do something fun with u_time
19 | // float theta = sin( u_time ) * 0.5 + 0.5;
20 | float screenX = gl_FragCoord.x / u_resolution.x;
21 | gl_FragColor = vec4( grad.x, grad.y, screenX, 1.0 );
22 | }
23 |
24 | // How-to run: copy & past into http://editor.thebookofshaders.com
--------------------------------------------------------------------------------
/workshops/shaders-primer/bose-truchet-tile.glsl:
--------------------------------------------------------------------------------
1 | // Title: A Truchet Tile pattern
2 | // Author: pjkarlik
3 | // Adapted from https://github.com/pjkarlik/TruchetTiles/blob/master/src/shader/truchet/fragmentShader.js
4 |
5 | #ifdef GL_ES
6 | precision mediump float;
7 | #endif
8 |
9 | #define PI 3.14159265358979323846264
10 |
11 | uniform vec2 u_resolution; // Canvas size (width,height)
12 | uniform vec2 u_mouse; // mouse position in screen pixels
13 | uniform float u_time; // Time in seconds since load
14 |
15 | float nSeed = 0.34999999999999998;
16 | bool lineMode = false;
17 | float tSize = 0.10000000000000001;
18 |
19 | vec2 hash2( vec2 p) {
20 | vec2 o = (p+0.5)/256.0;
21 | return o;
22 | }
23 |
24 | float goldNoise( vec2 coord, float seed){
25 | float phi = 1.61803398874989484820459 * 00000.1;
26 | float pi2 = PI * 00000.1;
27 | float sq2 = 1.41421356237309504880169 * 10000.0;
28 | float temp = fract(
29 | sin(
30 | dot(
31 | coord*(seed+phi), vec2(phi, pi2)
32 | )
33 | ) * sq2
34 | );
35 | return temp;
36 | }
37 |
38 | vec3 pattern( vec2 uv) {
39 | vec2 grid = floor(uv);
40 | vec2 subuv = fract(uv);
41 | float mult = 0.5;
42 | float dnoise = goldNoise(grid, nSeed);
43 | vec2 rand = hash2(grid);
44 | float shade = 0.;
45 | float df;
46 | float check = dnoise;
47 | if( check <= .25 ) {
48 | df = subuv.x - subuv.y; // tl
49 | } else if( check <= .5 ) {
50 | df = 1. - subuv.y - subuv.x;
51 | } else if( check <= .75 ) {
52 | df = subuv.y - subuv.x;
53 | } else if( check <= 1. ) {
54 | df = subuv.y - 1. + subuv.x;
55 | }
56 | shade = smoothstep(.0, -.02, df);
57 | if (lineMode)
58 | shade += smoothstep(.02, .04, df);
59 | return vec3( shade );
60 | }
61 |
62 | void main() {
63 | float fScale = (tSize == 0.0) ? max( u_resolution.x, u_resolution.y) : 1.0 / tSize;
64 | vec2 uv = (gl_FragCoord.xy - 0.5 * u_resolution.xy) / min( u_resolution.y, u_resolution.x);
65 | uv *= fScale;
66 | vec3 colour = pattern(uv);
67 | gl_FragColor = vec4( colour,colour.r);
68 | }
--------------------------------------------------------------------------------
/workshops/shaders-primer/shadertoy-step1.glsl:
--------------------------------------------------------------------------------
1 | // Title: Standard code template of Shadertoy
2 | // Author: Shadertoy
3 |
4 | void mainImage( out vec4 fragColor, in vec2 fragCoord) {
5 | // Normalized pixel coordinates (from 0 to 1)
6 | vec2 uv = fragCoord / iResolution.xy;
7 |
8 | // Time varying pixel color
9 | vec3 col = 0.5 + 0.5 * cos( iTime * 10.0 + uv.xyx + vec3( 0,2,4));
10 |
11 | // Output to screen
12 | fragColor = vec4(col,1.0);
13 | }
14 |
15 | // How-to run: copy & past into https://www.shadertoy.com/new
--------------------------------------------------------------------------------
/workshops/shaders-primer/shadertoy-step10.glsl:
--------------------------------------------------------------------------------
1 | // Title: Standard code template of Shadertoy
2 | // Author: Nicola Papale & Olivier Lange
3 |
4 | void mainImage( out vec4 fragColor, in vec2 fragCoord) {
5 | // Normalized pixel coordinates (from 0 to 1)
6 | vec2 uv = fragCoord / iResolution.xy;
7 |
8 | // Position varying pixel color, taken from textures
9 | vec3 img1 = texture( iChannel0, uv).rgb;
10 | vec3 img2 = texture( iChannel1, uv).rgb;
11 | vec3 m = mix( img1, img2, uv.x );
12 |
13 | float t = log2(iTime / 3.0) ;
14 | //if( uv.x > 0.5) { t *= -1.0; }
15 | float ydemo = sin( t * uv.y * 100.0 + t * 200.0);
16 | float xdemo = cos( uv.x * 230.0 + t * 500.0);
17 | float demo = ydemo * xdemo * 2.0;
18 | if( uv.x > iMouse.x / 1000.0) { demo *= 2.0; }
19 |
20 | // Output to screen
21 | fragColor = vec4( m * demo, 1.0);
22 | }
23 |
24 | // How-to run: copy & past into https://www.shadertoy.com/new
25 |
--------------------------------------------------------------------------------
/workshops/shaders-primer/shadertoy-step11.glsl:
--------------------------------------------------------------------------------
1 | // Title: Standard code template of Shadertoy
2 | // Author: Nicola Papale & Olivier Lange
3 |
4 | void mainImage( out vec4 fragColor, in vec2 fragCoord) {
5 | // Normalized pixel coordinates (from 0 to 1)
6 | vec2 uv = fragCoord / iResolution.xy;
7 |
8 | // Position varying pixel color, taken from textures
9 | vec3 img1 = texture( iChannel0, uv).rgb;
10 | vec3 img2 = texture( iChannel1, uv).rgb;
11 | vec3 m = mix( img1, img2, uv.x );
12 |
13 | float t = log2((mod(iTime, 10.0) + 3.0) / 5.0) ;
14 | //if( uv.x > 0.5) { t *= -1.0; }
15 | float ydemo = sin( t * uv.y * 100.0 + t * 200.0);
16 | float xdemo = cos( uv.x * 230.0 + t * 500.0);
17 | float demo = ydemo * xdemo * 2.0;
18 | if( uv.x > iMouse.x / 1000.0) { demo *= 2.0; }
19 |
20 | // Output to screen
21 | fragColor = vec4( m * demo, 1.0);
22 | }
23 |
24 | // How-to run: copy & past into https://www.shadertoy.com/new
25 |
--------------------------------------------------------------------------------
/workshops/shaders-primer/shadertoy-step2.glsl:
--------------------------------------------------------------------------------
1 | // Title: Standard code template of Shadertoy
2 | // Author: Olivier Lange & Leander Herzog
3 |
4 | void mainImage( out vec4 fragColor, in vec2 fragCoord) {
5 | // Normalized pixel coordinates (from 0 to 1)
6 | vec2 uv = fragCoord / iResolution.xy;
7 |
8 | // Time and position varying pixel color
9 | float t = iTime * 30.0;
10 | if( uv.x > 0.5) {
11 | t *= -1.0;
12 | }
13 |
14 | float demo = sin( t + uv.y * 200.0);
15 | if( uv.x > iMouse.x / 1000.0) {
16 | demo *= 20.0;
17 | }
18 |
19 | // Output to screen
20 | fragColor = vec4( demo);
21 | }
22 |
23 | // How-to run: copy & past into https://www.shadertoy.com/new
--------------------------------------------------------------------------------
/workshops/shaders-primer/shadertoy-step3.glsl:
--------------------------------------------------------------------------------
1 | // Title: Standard code template of Shadertoy
2 | // Author: Olivier Lange & Leander Herzog
3 |
4 | void mainImage( out vec4 fragColor, in vec2 fragCoord) {
5 | // Normalized pixel coordinates (from 0 to 1)
6 | vec2 uv = fragCoord / iResolution.xy;
7 |
8 | // Position varying pixel color, taken from textures
9 | vec3 img1 = texture( iChannel0, uv).rgb;
10 | vec3 img2 = texture( iChannel1, uv).rgb;
11 | vec3 m = mix( img1, img2, uv.x);
12 |
13 | // Output to screen
14 | fragColor = vec4( m, 1.0);
15 | }
16 |
17 | // How-to run: copy & past into https://www.shadertoy.com/new
--------------------------------------------------------------------------------
/workshops/shaders-primer/shadertoy-step4.glsl:
--------------------------------------------------------------------------------
1 | // Title: Mixing an image with camera
2 | // Author: Olivier Lange
3 | //
4 | // How-to run: copy & past into https://www.shadertoy.com/new
5 | //
6 | // iChannel0: pick any texture
7 | // iChannel1: pick the Webcam
8 |
9 | void mainImage( out vec4 fragColor, in vec2 fragCoord) {
10 | // Normalized pixel coordinates (from 0 to 1)
11 | vec2 uv = fragCoord / iResolution.xy;
12 |
13 | // Position varying pixel color, taken from textures
14 | vec3 img1 = texture( iChannel0, uv).rgb;
15 | vec3 img2 = texture( iChannel1, uv).rgb;
16 | vec3 m = mix( img1, img2, uv.x);
17 |
18 | float t = iTime * 30.0;
19 | if( uv.x > 0.5) { t *= -1.0; }
20 |
21 | float demo = sin( t + uv.y * 100.0);
22 | if( uv.x > iMouse.x / 1000.0) { demo *= 2.0; }
23 |
24 | // Output to screen
25 | fragColor = vec4( m * demo, 1.0);
26 | }
27 |
--------------------------------------------------------------------------------
/workshops/shaders-primer/shadertoy-step5.glsl:
--------------------------------------------------------------------------------
1 | // Title: Mixing an image with camera
2 | // Author: Olivier Lange
3 | //
4 | // How-to run: copy & past into https://www.shadertoy.com/new
5 | //
6 | // iChannel0: pick any texture
7 | // iChannel1: pick any texture
8 |
9 | void mainImage( out vec4 fragColor, in vec2 fragCoord )
10 | {
11 | vec2 uv = fragCoord/iResolution.xy;
12 |
13 | float t = iTime;
14 | float k = floor( fract(t+uv.y*10.0)*2.0);
15 | vec3 img = texture(iChannel0,uv).rgg;
16 | vec3 col = vec3(k);
17 |
18 | col -= img;
19 |
20 | float cut = fract(t * 0.5);
21 | cut = (sin( t) + 1.0) * 0.5;
22 | if(uv.x > cut) {
23 | col = img;
24 | }
25 |
26 | fragColor = vec4(col,1.0);
27 | }
28 |
29 | // Tip: « Shadertoy Custom Textures » Chrome extension allows to drag & drop an image from Finder to the Shadertoy channels
30 | // https://chrome.google.com/webstore/detail/shadertoy-custom-texures/jgeibpcndpjboeebilehgbpkopkgkjda?hl=en
--------------------------------------------------------------------------------
/workshops/shaders-primer/shadertoy-step6.glsl:
--------------------------------------------------------------------------------
1 | // Title: Mixing images with each other
2 | // Author: Olivier Lange
3 | //
4 | // How-to run: copy & past into https://www.shadertoy.com/new
5 | //
6 | // iChannel0: pick any texture
7 | // iChannel1: pick any texture
8 |
9 | void mainImage( out vec4 fragColor, in vec2 fragCoord) {
10 | // Normalized pixel coordinates (from 0 to 1)
11 | vec2 uv = fragCoord / iResolution.xy;
12 |
13 | vec2 e = vec2( uv.x * fract( iTime + uv.x * 7.0) * 0.3, uv.y);
14 |
15 | vec3 img1 = texture( iChannel0, e).rgb;
16 | vec3 img2 = texture( iChannel1, uv).rgb;
17 |
18 | // Output to screen
19 | fragColor = vec4( img2*0.5 + img1, 1.0);
20 | }
21 |
22 | // Tip: « Shadertoy Custom Textures » Chrome extension allows to drag & drop an image from Finder to the Shadertoy channels
23 | // https://chrome.google.com/webstore/detail/shadertoy-custom-texures/jgeibpcndpjboeebilehgbpkopkgkjda?hl=en
--------------------------------------------------------------------------------
/workshops/shaders-primer/shadertoy-step7.glsl:
--------------------------------------------------------------------------------
1 | // Title: Transforming images with sound
2 | // Author: Leander Herzog & Olivier Lange
3 | //
4 | // How-to run: copy & past into https://www.shadertoy.com/new
5 | //
6 | // iChannel0: pick any texture
7 | // iChannel1: pick any texture
8 | // iChannel2: pick a SoundCloud track
9 |
10 | void mainImage( out vec4 fragColor, in vec2 fragCoord) {
11 | vec2 uv = fragCoord / iResolution.xy;
12 |
13 | vec3 img1 = texture( iChannel0, uv).rgb;
14 | vec2 e = uv;
15 |
16 | e.x *= img1.r * 0.3;
17 | float sound = texture( iChannel2, e).r;
18 |
19 | e.y -= sound * 0.4;
20 | vec3 img2 = texture( iChannel1, e).rgb;
21 |
22 | //vec3 d = vec3( uv.x, uv.y, 0.0);
23 | fragColor = vec4( img2, 1.0);
24 | }
25 |
26 | // Tip: « Shadertoy Custom Textures » Chrome extension allows to drag & drop an image from Finder to the Shadertoy channels
27 | // https://chrome.google.com/webstore/detail/shadertoy-custom-texures/jgeibpcndpjboeebilehgbpkopkgkjda?hl=en
--------------------------------------------------------------------------------
/workshops/shaders-primer/shadertoy-step8.glsl:
--------------------------------------------------------------------------------
1 | // Title: A Truchet Tile pattern
2 | // Author: pjkarlik
3 | // Adapted from https://github.com/pjkarlik/TruchetTiles/blob/master/src/shader/truchet/fragmentShader.js
4 |
5 | #ifdef GL_ES
6 | precision mediump float;
7 | #endif
8 |
9 | #define PI 3.14159265358979323846264
10 |
11 | float nSeed = 0.34999999999999998;
12 | bool lineMode = false;
13 | float tSize = 0.10000000000000001;
14 |
15 | vec2 hash2( vec2 p) {
16 | vec2 o = (p+0.5)/256.0;
17 | return o;
18 | }
19 |
20 | float goldNoise( vec2 coord, float seed){
21 | float phi = 1.61803398874989484820459 * 00000.1;
22 | float pi2 = PI * 00000.1;
23 | float sq2 = 1.41421356237309504880169 * 10000.0;
24 | float temp = fract(
25 | sin(
26 | dot(
27 | coord*(seed+phi), vec2(phi, pi2)
28 | )
29 | ) * sq2
30 | );
31 | return temp;
32 | }
33 |
34 | vec3 pattern( vec2 uv) {
35 | vec2 grid = floor(uv);
36 | vec2 subuv = fract(uv);
37 | float mult = 0.5;
38 | float dnoise = goldNoise(grid, nSeed);
39 | vec2 rand = hash2(grid);
40 | float shade = 0.;
41 | float df;
42 | float check = dnoise;
43 | if( check <= .25 ) {
44 | df = subuv.x - subuv.y; // tl
45 | } else if( check <= .5 ) {
46 | df = 1. - subuv.y - subuv.x;
47 | } else if( check <= .75 ) {
48 | df = subuv.y - subuv.x;
49 | } else if( check <= 1. ) {
50 | df = subuv.y - 1. + subuv.x;
51 | }
52 | shade = smoothstep(.0, -.02, df);
53 | if (lineMode)
54 | shade += smoothstep(.02, .04, df);
55 | return vec3( shade );
56 | }
57 |
58 | void mainImage( out vec4 fragColor, in vec2 fragCoord) {
59 | float fScale = (tSize == 0.0) ? max( iResolution.x, iResolution.y) : 1.0 / tSize;
60 | vec2 uv = ( fragCoord.xy - 0.5 * iResolution.xy) / min( iResolution.y, iResolution.x);
61 | uv *= fScale;
62 | vec3 colour = pattern( uv);
63 | fragColor = vec4( colour, colour.r);
64 | }
--------------------------------------------------------------------------------
/workshops/shaders-primer/shadertoy-step9.glsl:
--------------------------------------------------------------------------------
1 | // Title: Standard code template of Shadertoy
2 | // Author: Nicola Papale
3 |
4 | void mainImage( out vec4 fragColor, in vec2 fragCoord) {
5 | // Normalized pixel coordinates (from 0 to 1)
6 | vec2 uv = fragCoord / iResolution.xy;
7 |
8 | // Position varying pixel color, taken from textures
9 | vec3 img1 = texture( iChannel0, uv).rgb;
10 | vec3 img2 = texture( iChannel1, uv).rgb;
11 | vec3 m = mix( img1, img2, uv.x);
12 |
13 | float t = iTime / 1.0 ;
14 | if( uv.x > 0.5) { t *= -1.0; }
15 | float ydemo =sin( t * uv.y * 100.0);
16 | float xdemo = cos( uv.x * 230.0);
17 | float demo = ydemo * xdemo;
18 | if( uv.x > iMouse.x / 1000.0) { demo *= 2.0; }
19 |
20 | // Output to screen
21 | fragColor = vec4( m * demo, 1.0);
22 | }
23 |
24 | // How-to run: copy & past into https://www.shadertoy.com/new
25 |
--------------------------------------------------------------------------------