├── LICENSE
├── server
├── .gitignore
├── .dockerignore
├── index.html
├── package.json
├── fly.toml
├── Dockerfile
├── main.js
└── package-lock.json
├── assets
├── models
│ ├── rocks.fbx
│ ├── scene.bin
│ ├── scene.glb
│ ├── terr4.glb
│ ├── paintbg.png
│ ├── terrain.glb
│ ├── explosion.png
│ ├── heightmap.png
│ ├── explosionold.png
│ ├── rocktexture.jpg
│ ├── terrain-draco-1.glb
│ ├── terrain-draco-2.glb
│ ├── GrassRockyAlbedo.jpg
│ ├── textures
│ │ ├── DL2X2_1_baseColor.png
│ │ ├── Trank_bark_baseColor.jpeg
│ │ ├── DL2X2_1_metallicRoughness.png
│ │ └── Trank_bark_metallicRoughness.png
│ └── tree.gltf
├── skybox
│ ├── Up_Tex.webp
│ ├── Back_Tex.webp
│ ├── Down_Tex.webp
│ ├── Front_Tex.webp
│ ├── Left_Tex.webp
│ └── Right_Tex.webp
├── sounds
│ ├── bamboo.mp3
│ ├── asiastana.ogg
│ ├── slownomotion.ogg
│ ├── rocket-explode.ogg
│ └── rocket-flying.ogg
├── images
│ └── crosshair.png
└── draco
│ ├── draco_decoder.wasm
│ ├── draco_decoder_gltf.wasm
│ └── draco_wasm_wrapper_gltf.js
├── .prettierrc.json
├── .gitignore
├── .vscode
├── extensions.json
└── settings.json
├── .vsls.json
├── bundler
├── webpack.prod.js
├── webpack.dev.js
└── webpack.common.js
├── src
├── shader
│ ├── Explosion.frag
│ └── Explosion.vert
├── main.js
├── index.html
├── style.css
└── core
│ └── Game.js
├── package.json
└── README.md
/LICENSE:
--------------------------------------------------------------------------------
1 | ADD LICENSE
--------------------------------------------------------------------------------
/server/.gitignore:
--------------------------------------------------------------------------------
1 | /node_modules
--------------------------------------------------------------------------------
/server/.dockerignore:
--------------------------------------------------------------------------------
1 | fly.toml
2 | Dockerfile
3 | .dockerignore
4 | node_modules
5 | .git
6 |
--------------------------------------------------------------------------------
/assets/models/rocks.fbx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/felixgren/three-arena/HEAD/assets/models/rocks.fbx
--------------------------------------------------------------------------------
/assets/models/scene.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/felixgren/three-arena/HEAD/assets/models/scene.bin
--------------------------------------------------------------------------------
/assets/models/scene.glb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/felixgren/three-arena/HEAD/assets/models/scene.glb
--------------------------------------------------------------------------------
/assets/models/terr4.glb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/felixgren/three-arena/HEAD/assets/models/terr4.glb
--------------------------------------------------------------------------------
/.prettierrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "singleQuote": true,
3 | "tabWidth": 4,
4 | "printWidth": 80
5 | }
6 |
--------------------------------------------------------------------------------
/assets/models/paintbg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/felixgren/three-arena/HEAD/assets/models/paintbg.png
--------------------------------------------------------------------------------
/assets/models/terrain.glb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/felixgren/three-arena/HEAD/assets/models/terrain.glb
--------------------------------------------------------------------------------
/assets/skybox/Up_Tex.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/felixgren/three-arena/HEAD/assets/skybox/Up_Tex.webp
--------------------------------------------------------------------------------
/assets/sounds/bamboo.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/felixgren/three-arena/HEAD/assets/sounds/bamboo.mp3
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /node_modules
2 | /dist
3 | .vercel
4 |
5 | /src/entities
6 | /src/temp
7 | /assets/sounds/wip/
8 |
--------------------------------------------------------------------------------
/.vscode/extensions.json:
--------------------------------------------------------------------------------
1 | {
2 | "recommendations": ["slevesque.shader", "esbenp.prettier-vscode"]
3 | }
4 |
--------------------------------------------------------------------------------
/assets/images/crosshair.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/felixgren/three-arena/HEAD/assets/images/crosshair.png
--------------------------------------------------------------------------------
/assets/models/explosion.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/felixgren/three-arena/HEAD/assets/models/explosion.png
--------------------------------------------------------------------------------
/assets/models/heightmap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/felixgren/three-arena/HEAD/assets/models/heightmap.png
--------------------------------------------------------------------------------
/assets/skybox/Back_Tex.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/felixgren/three-arena/HEAD/assets/skybox/Back_Tex.webp
--------------------------------------------------------------------------------
/assets/skybox/Down_Tex.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/felixgren/three-arena/HEAD/assets/skybox/Down_Tex.webp
--------------------------------------------------------------------------------
/assets/skybox/Front_Tex.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/felixgren/three-arena/HEAD/assets/skybox/Front_Tex.webp
--------------------------------------------------------------------------------
/assets/skybox/Left_Tex.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/felixgren/three-arena/HEAD/assets/skybox/Left_Tex.webp
--------------------------------------------------------------------------------
/assets/skybox/Right_Tex.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/felixgren/three-arena/HEAD/assets/skybox/Right_Tex.webp
--------------------------------------------------------------------------------
/assets/sounds/asiastana.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/felixgren/three-arena/HEAD/assets/sounds/asiastana.ogg
--------------------------------------------------------------------------------
/assets/models/explosionold.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/felixgren/three-arena/HEAD/assets/models/explosionold.png
--------------------------------------------------------------------------------
/assets/models/rocktexture.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/felixgren/three-arena/HEAD/assets/models/rocktexture.jpg
--------------------------------------------------------------------------------
/assets/sounds/slownomotion.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/felixgren/three-arena/HEAD/assets/sounds/slownomotion.ogg
--------------------------------------------------------------------------------
/assets/draco/draco_decoder.wasm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/felixgren/three-arena/HEAD/assets/draco/draco_decoder.wasm
--------------------------------------------------------------------------------
/assets/models/terrain-draco-1.glb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/felixgren/three-arena/HEAD/assets/models/terrain-draco-1.glb
--------------------------------------------------------------------------------
/assets/models/terrain-draco-2.glb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/felixgren/three-arena/HEAD/assets/models/terrain-draco-2.glb
--------------------------------------------------------------------------------
/assets/sounds/rocket-explode.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/felixgren/three-arena/HEAD/assets/sounds/rocket-explode.ogg
--------------------------------------------------------------------------------
/assets/sounds/rocket-flying.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/felixgren/three-arena/HEAD/assets/sounds/rocket-flying.ogg
--------------------------------------------------------------------------------
/assets/models/GrassRockyAlbedo.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/felixgren/three-arena/HEAD/assets/models/GrassRockyAlbedo.jpg
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "editor.defaultFormatter": "esbenp.prettier-vscode",
3 | "editor.formatOnSave": true
4 | }
5 |
--------------------------------------------------------------------------------
/assets/draco/draco_decoder_gltf.wasm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/felixgren/three-arena/HEAD/assets/draco/draco_decoder_gltf.wasm
--------------------------------------------------------------------------------
/assets/models/textures/DL2X2_1_baseColor.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/felixgren/three-arena/HEAD/assets/models/textures/DL2X2_1_baseColor.png
--------------------------------------------------------------------------------
/assets/models/textures/Trank_bark_baseColor.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/felixgren/three-arena/HEAD/assets/models/textures/Trank_bark_baseColor.jpeg
--------------------------------------------------------------------------------
/assets/models/textures/DL2X2_1_metallicRoughness.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/felixgren/three-arena/HEAD/assets/models/textures/DL2X2_1_metallicRoughness.png
--------------------------------------------------------------------------------
/.vsls.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "http://json.schemastore.org/vsls",
3 | "gitignore": "none",
4 | "excludeFiles": ["!.env"],
5 | "hideFiles": []
6 | }
7 |
--------------------------------------------------------------------------------
/assets/models/textures/Trank_bark_metallicRoughness.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/felixgren/three-arena/HEAD/assets/models/textures/Trank_bark_metallicRoughness.png
--------------------------------------------------------------------------------
/server/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Socket
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/bundler/webpack.prod.js:
--------------------------------------------------------------------------------
1 | const { merge } = require('webpack-merge');
2 | const commonConfiguration = require('./webpack.common.js');
3 | const { CleanWebpackPlugin } = require('clean-webpack-plugin');
4 |
5 | module.exports = merge(commonConfiguration, {
6 | mode: 'production',
7 | plugins: [new CleanWebpackPlugin()],
8 | });
9 |
--------------------------------------------------------------------------------
/server/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "server",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "main.js",
6 | "scripts": {
7 | "start": "node main.js",
8 | "test": "echo \"Error: no test specified\" && exit 1"
9 | },
10 | "keywords": [],
11 | "author": "",
12 | "license": "ISC",
13 | "dependencies": {
14 | "express": "^4.17.1",
15 | "socket.io": "^4.1.1"
16 | },
17 | "engines": {
18 | "node": "15.14.0"
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/shader/Explosion.frag:
--------------------------------------------------------------------------------
1 | export default `
2 | varying vec2 vUv;
3 | varying float noise;
4 | uniform sampler2D tExplosion;
5 |
6 | float random( vec3 scale, float seed ){
7 | return fract( sin( dot( gl_FragCoord.xyz + seed, scale ) ) * 43758.5453 + seed ) ;
8 | }
9 |
10 | void main() {
11 |
12 | float r = .01 * random( vec3( 12.9898, 78.233, 151.7182 ), 0.0 );
13 | vec2 tPos = vec2( 0, 1.3 * noise + r );
14 | vec4 color = texture2D( tExplosion, tPos );
15 | gl_FragColor = vec4( color.rgb, 1.0 );
16 |
17 | }
18 | `;
19 |
--------------------------------------------------------------------------------
/src/main.js:
--------------------------------------------------------------------------------
1 | import Game from './core/Game';
2 |
3 | const startGameButton = document.querySelector('.start-button-wrapper');
4 | const respawnGameButton = document.querySelector('.respawn-button-wrapper');
5 |
6 | Game.load();
7 |
8 | startGameButton.addEventListener('click', () => {
9 | Game.startGame();
10 | startGameButton.style.display = 'none';
11 | });
12 |
13 | respawnGameButton.addEventListener('click', () => {
14 | Game.triggerRespawn();
15 | Game.activatePointerLock();
16 | respawnGameButton.style.display = 'none';
17 | });
18 |
--------------------------------------------------------------------------------
/server/fly.toml:
--------------------------------------------------------------------------------
1 | # fly.toml file generated for three-arena on 2023-01-29T16:30:46+01:00
2 |
3 | app = "three-arena"
4 | kill_signal = "SIGINT"
5 | kill_timeout = 5
6 | processes = []
7 |
8 | [env]
9 | PORT = "8080"
10 |
11 | [experimental]
12 | auto_rollback = true
13 |
14 | [[services]]
15 | http_checks = []
16 | internal_port = 8080
17 | processes = ["app"]
18 | protocol = "tcp"
19 | script_checks = []
20 | [services.concurrency]
21 | hard_limit = 25
22 | soft_limit = 20
23 | type = "connections"
24 |
25 | [[services.ports]]
26 | force_https = true
27 | handlers = ["http"]
28 | port = 80
29 |
30 | [[services.ports]]
31 | handlers = ["tls", "http"]
32 | port = 443
33 |
34 | [[services.tcp_checks]]
35 | grace_period = "1s"
36 | interval = "15s"
37 | restart_limit = 0
38 | timeout = "2s"
39 |
--------------------------------------------------------------------------------
/server/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM debian:bullseye as builder
2 |
3 | ARG NODE_VERSION=16.19.0
4 |
5 | RUN apt-get update; apt install -y curl python-is-python3 pkg-config build-essential
6 | RUN curl https://get.volta.sh | bash
7 | ENV VOLTA_HOME /root/.volta
8 | ENV PATH /root/.volta/bin:$PATH
9 | RUN volta install node@${NODE_VERSION}
10 |
11 | #######################################################################
12 |
13 | RUN mkdir /app
14 | WORKDIR /app
15 |
16 | # NPM will not install any package listed in "devDependencies" when NODE_ENV is set to "production",
17 | # to install all modules: "npm install --production=false".
18 | # Ref: https://docs.npmjs.com/cli/v9/commands/npm-install#description
19 |
20 | ENV NODE_ENV production
21 |
22 | COPY . .
23 |
24 | RUN npm install
25 | FROM debian:bullseye
26 |
27 | LABEL fly_launch_runtime="nodejs"
28 |
29 | COPY --from=builder /root/.volta /root/.volta
30 | COPY --from=builder /app /app
31 |
32 | WORKDIR /app
33 | ENV NODE_ENV production
34 | ENV PATH /root/.volta/bin:$PATH
35 |
36 | CMD [ "npm", "run", "start" ]
37 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "level-up",
3 | "version": "1.0.0",
4 | "description": "",
5 | "private": true,
6 | "scripts": {
7 | "build": "webpack --config ./bundler/webpack.prod.js",
8 | "dev": "webpack serve --config ./bundler/webpack.dev.js",
9 | "start": "npm run dev",
10 | "server": "npm start --prefix server"
11 | },
12 | "devDependencies": {
13 | "@babel/core": "^7.13.16",
14 | "@babel/preset-env": "^7.13.15",
15 | "babel-loader": "^8.2.2",
16 | "clean-webpack-plugin": "*",
17 | "copy-webpack-plugin": "^8.1.1",
18 | "css-loader": "^5.2.4",
19 | "file-loader": "^6.2.0",
20 | "html-loader": "^2.1.2",
21 | "html-webpack-plugin": "^5.3.1",
22 | "mini-css-extract-plugin": "^1.5.1",
23 | "portfinder-sync": "^0.0.2",
24 | "prettier": "^2.2.1",
25 | "raw-loader": "^4.0.2",
26 | "style-loader": "^2.0.0",
27 | "webpack": "^5.36.1",
28 | "webpack-cli": "^4.6.0",
29 | "webpack-dev-server": "^3.11.2",
30 | "webpack-merge": "^5.7.3"
31 | },
32 | "dependencies": {
33 | "dat.gui": "^0.7.7",
34 | "socket.io-client": "^4.1.1",
35 | "three": "^0.128.0"
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/bundler/webpack.dev.js:
--------------------------------------------------------------------------------
1 | const { merge } = require('webpack-merge');
2 | const commonConfiguration = require('./webpack.common.js');
3 | const ip = require('internal-ip');
4 | const portFinderSync = require('portfinder-sync');
5 |
6 | const infoColor = (_message) => {
7 | return `\u001b[1m\u001b[34m${_message}\u001b[39m\u001b[22m`;
8 | };
9 |
10 | module.exports = merge(commonConfiguration, {
11 | mode: 'development',
12 | devServer: {
13 | host: '0.0.0.0',
14 | port: portFinderSync.getPort(5000),
15 | contentBase: './dist',
16 | watchContentBase: true,
17 | open: true,
18 | https: false,
19 | useLocalIp: true,
20 | disableHostCheck: true,
21 | overlay: true,
22 | noInfo: true,
23 | after: function (app, server, compiler) {
24 | const port = server.options.port;
25 | const https = server.options.https ? 's' : '';
26 | const localIp = ip.v4.sync();
27 | const domain1 = `http${https}://localhost:${port}`;
28 | const domain2 = `http${https}://${localIp}:${port}`;
29 |
30 | console.log(
31 | `Project running at:\n - ${infoColor(
32 | domain1
33 | )}\n - ${infoColor(domain2)}`
34 | );
35 | },
36 | },
37 | });
38 |
--------------------------------------------------------------------------------
/bundler/webpack.common.js:
--------------------------------------------------------------------------------
1 | const CopyWebpackPlugin = require('copy-webpack-plugin');
2 | const HtmlWebpackPlugin = require('html-webpack-plugin');
3 | const MiniCSSExtractPlugin = require('mini-css-extract-plugin');
4 | const path = require('path');
5 |
6 | module.exports = {
7 | entry: path.resolve(__dirname, '../src/main.js'),
8 | output: {
9 | filename: 'bundle.[contenthash].js',
10 | path: path.resolve(__dirname, '../dist'),
11 | },
12 | devtool: 'source-map',
13 | plugins: [
14 | new CopyWebpackPlugin({
15 | patterns: [{ from: path.resolve(__dirname, '../assets') }],
16 | }),
17 | new HtmlWebpackPlugin({
18 | template: path.resolve(__dirname, '../src/index.html'),
19 | minify: true,
20 | }),
21 | new MiniCSSExtractPlugin(),
22 | ],
23 | module: {
24 | rules: [
25 | // HTML
26 | {
27 | test: /\.(html)$/,
28 | use: ['html-loader'],
29 | },
30 |
31 | // JS
32 | {
33 | test: /\.js$/,
34 | exclude: /node_modules/,
35 | use: ['babel-loader'],
36 | },
37 |
38 | // CSS
39 | {
40 | test: /\.css$/,
41 | use: [MiniCSSExtractPlugin.loader, 'css-loader'],
42 | },
43 |
44 | // Images
45 | {
46 | test: /\.(jpg|png|gif|svg)$/,
47 | use: [
48 | {
49 | loader: 'file-loader',
50 | options: {
51 | outputPath: 'assets/images/',
52 | },
53 | },
54 | ],
55 | },
56 |
57 | // Fonts
58 | {
59 | test: /\.(ttf|eot|woff|woff2)$/,
60 | use: [
61 | {
62 | loader: 'file-loader',
63 | options: {
64 | outputPath: 'assets/fonts/',
65 | },
66 | },
67 | ],
68 | },
69 | ],
70 | },
71 | };
72 |
--------------------------------------------------------------------------------
/src/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Three.js arena
7 |
8 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
Velocity:
19 |
Initial
20 |
Position:
21 |
Initial
22 |
23 |
24 |
25 |
28 |
29 |
30 |
35 |
36 |
37 |
41 |
42 |
43 |
48 |
49 |
50 |
51 |
52 |
60 |
61 |
62 |
63 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | 
2 |
3 | ## Three Arena
4 | Join now on *[three-arena.vercel.app](https://three-arena.vercel.app/)*
5 |
6 | An arena shooter created in three.js. Shoot your friends in this socket.io multiplayer game. You can open chat by pressing t.
7 |
8 | It features a vanilla built movement system, collisions (with the help of octrees), chat & shooting. Backend is an express socket.io server which gathers and sends out all player data (movement, directions, chat, rocket fire events) to the clients. The clients then react by generating and updating the players & events, the client is completely trusted. Best part is that it's all in one file... but would be very easy to break out & expand upon if you have some time.
9 |
10 | If you've found this repo valuable, do give it a star.
11 |
12 | This game was created using the following technologies:
13 |
14 | - [three.js](https://threejs.org/)
15 | - [Socket.IO](https://socket.io/)
16 | - [webpack](https://webpack.js.org/)
17 |
18 | ## Installation
19 |
20 | **Prerequisites**
21 |
22 | - [UNIX based OS (Mac, Linux or WSL2 for Windows)](https://docs.microsoft.com/en-us/windows/wsl/install-win10)
23 | - node
24 | - npm
25 |
26 | ### Setting up project
27 |
28 | ```
29 | git clone https://github.com/felixgren/three-arena.git
30 | cd three-arena
31 | npm install
32 | cd server
33 | npm install
34 | ```
35 |
36 | ### Run project
37 |
38 | ```js
39 | // Start client
40 | npm run dev
41 |
42 | // Start server
43 | npm run server
44 | ```
45 |
46 | > In case of errors, verify that socket.io client in `game.js` is targeted at matching localhost port inside `/server/main.js`.
47 |
48 | # Changelog
49 |
50 | - [#1 - Initial setup](https://github.com/felixgren/level-up/pull/1)
51 | - [#2 - Shadows ](https://github.com/felixgren/level-up/pull/2)
52 | - [#3 - Basic skybox & model, FPS counter](https://github.com/felixgren/level-up/pull/3)
53 | - [#4 - Drawcalls to debug GUI](https://github.com/felixgren/level-up/pull/4/)
54 | - [#5 - Movement and collisions.](https://github.com/felixgren/level-up/pull/5/)
55 | - [#6 - Rockets.](https://github.com/felixgren/level-up/pull/6/)
56 | - [#7 - World terrain, heightmap, model, skybox](https://github.com/felixgren/level-up/pull/7/)
57 | - [#8 - Refactored entire project](https://github.com/felixgren/level-up/pull/8/)
58 | - [#9 - Code Review](https://github.com/felixgren/three-arena/pull/9)
59 | - [#10 - Core Features 1 (Multiplayer, Chat, Explosions, etc)](https://github.com/felixgren/three-arena/pull/10/)
60 | - [#11 - Environment 2 (New Map)](https://github.com/felixgren/three-arena/pull/11/)
61 | - [#12 - Core Features 2 (Respawn, UI, Chat types)](https://github.com/felixgren/three-arena/pull/12/)
62 | - [#13 - Core Features 3 (General improvements)](https://github.com/felixgren/three-arena/pull/13/)
63 | - [#14 - Update node server host](https://github.com/felixgren/three-arena/pull/14/)
64 |
--------------------------------------------------------------------------------
/server/main.js:
--------------------------------------------------------------------------------
1 | const express = require('express');
2 | const app = express();
3 | const http = require('http').Server(app);
4 |
5 | const io = require('socket.io')(http, {
6 | cors: {
7 | origin: '*',
8 | methods: ['GET', 'POST'],
9 | },
10 | });
11 |
12 | app.use(express.static('../dist/'));
13 |
14 | app.get('/', function (req, res) {
15 | res.sendFile(__dirname + '../../dist/index.html');
16 | });
17 |
18 | let players = {};
19 |
20 | (() => {
21 | setup();
22 |
23 | // Update player position, roughly matches 120 refresh
24 | setInterval(function () {
25 | io.sockets.emit('playerPositions', players);
26 | }, 8);
27 | })();
28 |
29 | function setup() {
30 | io.on('connection', function (socket) {
31 | // Client connect...
32 | console.log(`User ${socket.id} connected`);
33 |
34 | // Add to server players object
35 | players[socket.id] = {
36 | position: [0, 0, 0],
37 | direction: [0, 0, 0],
38 | };
39 |
40 | // We give all clients notice of new player and their ID..
41 | socket.broadcast.emit(
42 | 'player connect',
43 | socket.id,
44 | io.engine.clientsCount
45 | );
46 |
47 | // We give client their ID, playerCount and playerIDs
48 | socket.emit(
49 | 'initPlayer',
50 | { id: socket.id },
51 | io.engine.clientsCount,
52 | Object.keys(players)
53 | );
54 |
55 | // We give clients notice of disconnection and the their ID
56 | socket.on('disconnect', function () {
57 | console.log(`User ${socket.id} disconnected`);
58 | socket.broadcast.emit(
59 | 'player disconnect',
60 | socket.id,
61 | io.engine.clientsCount
62 | );
63 | // Delete from players object
64 | delete players[socket.id];
65 | });
66 |
67 | // On chat message emit it to everyone
68 | socket.on('chat message', function (username, message) {
69 | io.emit('chat message', username, message);
70 | });
71 |
72 | socket.on('kill message', function (shooter, killed) {
73 | io.emit('kill message', shooter, killed);
74 | });
75 |
76 | // Data every client uploads
77 | socket.on('updateClientPos', (position, direction) => {
78 | if (players[socket.id]) {
79 | players[socket.id].position = position;
80 | players[socket.id].direction = direction;
81 | }
82 | });
83 |
84 | socket.on('triggerRemoteRocket', () => {
85 | socket.broadcast.emit(
86 | 'shootSyncRocket',
87 | players[socket.id],
88 | socket.id
89 | );
90 | });
91 | });
92 |
93 | let port = process.env.PORT;
94 | if (port == null || port == '') {
95 | port = 3000;
96 | }
97 |
98 | http.listen(port, function () {
99 | console.log(`Listening on port ${port}`);
100 | });
101 | }
102 |
--------------------------------------------------------------------------------
/src/style.css:
--------------------------------------------------------------------------------
1 | * {
2 | margin: 0;
3 | padding: 0;
4 | font-family: 'Montserrat', sans-serif;
5 | }
6 |
7 | html,
8 | body {
9 | height: 100vh;
10 | background: black;
11 | }
12 |
13 | .webgl {
14 | position: fixed;
15 | top: 0;
16 | left: 0;
17 | outline: none;
18 | }
19 |
20 | .custom-stats {
21 | bottom: 0;
22 | right: 0;
23 | color: rgb(255, 102, 0);
24 | background-color: rgba(53, 53, 53, 0.5);
25 | position: absolute;
26 | padding: 5px;
27 | /* font-family: Arial, Helvetica, sans-serif; */
28 | font-weight: 400;
29 | z-index: 100;
30 | }
31 |
32 | .custom-stats h4 {
33 | font-weight: 500;
34 | }
35 |
36 | .pause-button {
37 | bottom: 0;
38 | right: 10vh;
39 | position: absolute;
40 | z-index: 100;
41 | display: inline-block;
42 | padding: 0.35em 1.2em;
43 | border: 0.1em solid #ffffff;
44 | margin: 0 0.3em 0.3em 0;
45 | border-radius: 0.12em;
46 | box-sizing: border-box;
47 | text-decoration: none;
48 | font-family: 'Arial', sans-serif;
49 | font-weight: 300;
50 | color: #ffffff;
51 | text-align: center;
52 | transition: all 0.2s;
53 | /* display: none; */
54 | }
55 |
56 | .pause-button:hover {
57 | color: #000000;
58 | background-color: #ffffff;
59 | }
60 |
61 | .respawn-button-wrapper {
62 | position: absolute;
63 | display: none;
64 | z-index: 10;
65 | width: 100vw;
66 | height: 100vh;
67 | background-color: black;
68 | }
69 |
70 | .respawn-text {
71 | position: absolute;
72 | top: 200px;
73 | left: calc(50% - 75px);
74 | color: white;
75 | font-size: 30px;
76 | /* font-weight: 500; */
77 | letter-spacing: 0.15em;
78 | transition: 150ms;
79 | }
80 |
81 | .button {
82 | position: absolute;
83 | top: 250px;
84 | left: calc(50% - 150px);
85 | font-size: 40px;
86 | cursor: pointer;
87 | background-color: #1b1b1b;
88 | color: white;
89 | font-weight: 300;
90 | letter-spacing: 0.15em;
91 | transition: 150ms;
92 | border: 3px solid black;
93 | border-radius: 8px;
94 | margin: 8px 6px;
95 | transform: translate(8px, 8px);
96 | width: 300px;
97 | height: 60px;
98 | }
99 |
100 | .button:hover {
101 | transform: translate(0px, 0px) !important;
102 | }
103 |
104 | .button-background {
105 | position: absolute;
106 | top: 250px;
107 | left: calc(50% - 150px);
108 | background-color: #ee0000;
109 | border: 3px solid black;
110 | border-radius: 8px;
111 | margin: 8px 6px;
112 | width: 300px;
113 | height: 60px;
114 | box-sizing: border-box;
115 | }
116 |
117 | #chatSection {
118 | left: 4%;
119 | bottom: 4%;
120 | z-index: 10;
121 | position: absolute;
122 | border-radius: 3px;
123 | }
124 |
125 | .chatList {
126 | list-style-type: none;
127 | font-size: 16px;
128 | text-align: left;
129 | font-family: 'Roboto Mono', monospace;
130 | }
131 |
132 | .chatContainer {
133 | background-color: #4e4e4eaf;
134 | font-size: 28px;
135 | color: #ffffff;
136 | text-align: center;
137 | line-height: 20px;
138 | }
139 |
140 | .chatContainer > div {
141 | padding: 4px;
142 | }
143 |
144 | .chatContainer > div > span {
145 | display: inline-block;
146 | }
147 |
148 | .chatContainer > div > ul > li:not(:first-child) {
149 | border-top: 1px solid #6b6b6b60;
150 | }
151 |
152 | .chatContainer > div > ul > li {
153 | padding: 4px;
154 | }
155 |
156 | .hidden {
157 | display: none;
158 | }
159 |
160 | #inputForm {
161 | z-index: 10;
162 | display: none;
163 | position: absolute;
164 | bottom: 2%;
165 | left: 4%;
166 | z-index: 50;
167 | padding: 2px;
168 | }
169 |
170 | #inputForm input {
171 | line-height: 20px;
172 | color: white;
173 | border: none;
174 | background-color: transparent;
175 | outline: none;
176 | }
177 |
--------------------------------------------------------------------------------
/src/shader/Explosion.vert:
--------------------------------------------------------------------------------
1 | export default `
2 | //
3 | // GLSL textureless classic 3D noise "cnoise",
4 | // with an RSL-style periodic variant "pnoise".
5 | // Author: Stefan Gustavson (stefan.gustavson@liu.se)
6 | // Version: 2011-10-11
7 | //
8 | // Many thanks to Ian McEwan of Ashima Arts for the
9 | // ideas for permutation and gradient selection.
10 | //
11 | // Copyright (c) 2011 Stefan Gustavson. All rights reserved.
12 | // Distributed under the MIT license. See LICENSE file.
13 | // https://github.com/ashima/webgl-noise
14 | //
15 |
16 | vec3 mod289(vec3 x)
17 | {
18 | return x - floor(x * (1.0 / 289.0)) * 289.0;
19 | }
20 |
21 | vec4 mod289(vec4 x)
22 | {
23 | return x - floor(x * (1.0 / 289.0)) * 289.0;
24 | }
25 |
26 | vec4 permute(vec4 x)
27 | {
28 | return mod289(((x*34.0)+1.0)*x);
29 | }
30 |
31 | vec4 taylorInvSqrt(vec4 r)
32 | {
33 | return 1.79284291400159 - 0.85373472095314 * r;
34 | }
35 |
36 | vec3 fade(vec3 t) {
37 | return t*t*t*(t*(t*6.0-15.0)+10.0);
38 | }
39 |
40 | // Classic Perlin noise
41 | float cnoise(vec3 P)
42 | {
43 | vec3 Pi0 = floor(P); // Integer part for indexing
44 | vec3 Pi1 = Pi0 + vec3(1.0); // Integer part + 1
45 | Pi0 = mod289(Pi0);
46 | Pi1 = mod289(Pi1);
47 | vec3 Pf0 = fract(P); // Fractional part for interpolation
48 | vec3 Pf1 = Pf0 - vec3(1.0); // Fractional part - 1.0
49 | vec4 ix = vec4(Pi0.x, Pi1.x, Pi0.x, Pi1.x);
50 | vec4 iy = vec4(Pi0.yy, Pi1.yy);
51 | vec4 iz0 = Pi0.zzzz;
52 | vec4 iz1 = Pi1.zzzz;
53 |
54 | vec4 ixy = permute(permute(ix) + iy);
55 | vec4 ixy0 = permute(ixy + iz0);
56 | vec4 ixy1 = permute(ixy + iz1);
57 |
58 | vec4 gx0 = ixy0 * (1.0 / 7.0);
59 | vec4 gy0 = fract(floor(gx0) * (1.0 / 7.0)) - 0.5;
60 | gx0 = fract(gx0);
61 | vec4 gz0 = vec4(0.5) - abs(gx0) - abs(gy0);
62 | vec4 sz0 = step(gz0, vec4(0.0));
63 | gx0 -= sz0 * (step(0.0, gx0) - 0.5);
64 | gy0 -= sz0 * (step(0.0, gy0) - 0.5);
65 |
66 | vec4 gx1 = ixy1 * (1.0 / 7.0);
67 | vec4 gy1 = fract(floor(gx1) * (1.0 / 7.0)) - 0.5;
68 | gx1 = fract(gx1);
69 | vec4 gz1 = vec4(0.5) - abs(gx1) - abs(gy1);
70 | vec4 sz1 = step(gz1, vec4(0.0));
71 | gx1 -= sz1 * (step(0.0, gx1) - 0.5);
72 | gy1 -= sz1 * (step(0.0, gy1) - 0.5);
73 |
74 | vec3 g000 = vec3(gx0.x,gy0.x,gz0.x);
75 | vec3 g100 = vec3(gx0.y,gy0.y,gz0.y);
76 | vec3 g010 = vec3(gx0.z,gy0.z,gz0.z);
77 | vec3 g110 = vec3(gx0.w,gy0.w,gz0.w);
78 | vec3 g001 = vec3(gx1.x,gy1.x,gz1.x);
79 | vec3 g101 = vec3(gx1.y,gy1.y,gz1.y);
80 | vec3 g011 = vec3(gx1.z,gy1.z,gz1.z);
81 | vec3 g111 = vec3(gx1.w,gy1.w,gz1.w);
82 |
83 | vec4 norm0 = taylorInvSqrt(vec4(dot(g000, g000), dot(g010, g010), dot(g100, g100), dot(g110, g110)));
84 | g000 *= norm0.x;
85 | g010 *= norm0.y;
86 | g100 *= norm0.z;
87 | g110 *= norm0.w;
88 | vec4 norm1 = taylorInvSqrt(vec4(dot(g001, g001), dot(g011, g011), dot(g101, g101), dot(g111, g111)));
89 | g001 *= norm1.x;
90 | g011 *= norm1.y;
91 | g101 *= norm1.z;
92 | g111 *= norm1.w;
93 |
94 | float n000 = dot(g000, Pf0);
95 | float n100 = dot(g100, vec3(Pf1.x, Pf0.yz));
96 | float n010 = dot(g010, vec3(Pf0.x, Pf1.y, Pf0.z));
97 | float n110 = dot(g110, vec3(Pf1.xy, Pf0.z));
98 | float n001 = dot(g001, vec3(Pf0.xy, Pf1.z));
99 | float n101 = dot(g101, vec3(Pf1.x, Pf0.y, Pf1.z));
100 | float n011 = dot(g011, vec3(Pf0.x, Pf1.yz));
101 | float n111 = dot(g111, Pf1);
102 |
103 | vec3 fade_xyz = fade(Pf0);
104 | vec4 n_z = mix(vec4(n000, n100, n010, n110), vec4(n001, n101, n011, n111), fade_xyz.z);
105 | vec2 n_yz = mix(n_z.xy, n_z.zw, fade_xyz.y);
106 | float n_xyz = mix(n_yz.x, n_yz.y, fade_xyz.x);
107 | return 2.2 * n_xyz;
108 | }
109 |
110 | // Classic Perlin noise, periodic variant
111 | float pnoise(vec3 P, vec3 rep)
112 | {
113 | vec3 Pi0 = mod(floor(P), rep); // Integer part, modulo period
114 | vec3 Pi1 = mod(Pi0 + vec3(1.0), rep); // Integer part + 1, mod period
115 | Pi0 = mod289(Pi0);
116 | Pi1 = mod289(Pi1);
117 | vec3 Pf0 = fract(P); // Fractional part for interpolation
118 | vec3 Pf1 = Pf0 - vec3(1.0); // Fractional part - 1.0
119 | vec4 ix = vec4(Pi0.x, Pi1.x, Pi0.x, Pi1.x);
120 | vec4 iy = vec4(Pi0.yy, Pi1.yy);
121 | vec4 iz0 = Pi0.zzzz;
122 | vec4 iz1 = Pi1.zzzz;
123 |
124 | vec4 ixy = permute(permute(ix) + iy);
125 | vec4 ixy0 = permute(ixy + iz0);
126 | vec4 ixy1 = permute(ixy + iz1);
127 |
128 | vec4 gx0 = ixy0 * (1.0 / 7.0);
129 | vec4 gy0 = fract(floor(gx0) * (1.0 / 7.0)) - 0.5;
130 | gx0 = fract(gx0);
131 | vec4 gz0 = vec4(0.5) - abs(gx0) - abs(gy0);
132 | vec4 sz0 = step(gz0, vec4(0.0));
133 | gx0 -= sz0 * (step(0.0, gx0) - 0.5);
134 | gy0 -= sz0 * (step(0.0, gy0) - 0.5);
135 |
136 | vec4 gx1 = ixy1 * (1.0 / 7.0);
137 | vec4 gy1 = fract(floor(gx1) * (1.0 / 7.0)) - 0.5;
138 | gx1 = fract(gx1);
139 | vec4 gz1 = vec4(0.5) - abs(gx1) - abs(gy1);
140 | vec4 sz1 = step(gz1, vec4(0.0));
141 | gx1 -= sz1 * (step(0.0, gx1) - 0.5);
142 | gy1 -= sz1 * (step(0.0, gy1) - 0.5);
143 |
144 | vec3 g000 = vec3(gx0.x,gy0.x,gz0.x);
145 | vec3 g100 = vec3(gx0.y,gy0.y,gz0.y);
146 | vec3 g010 = vec3(gx0.z,gy0.z,gz0.z);
147 | vec3 g110 = vec3(gx0.w,gy0.w,gz0.w);
148 | vec3 g001 = vec3(gx1.x,gy1.x,gz1.x);
149 | vec3 g101 = vec3(gx1.y,gy1.y,gz1.y);
150 | vec3 g011 = vec3(gx1.z,gy1.z,gz1.z);
151 | vec3 g111 = vec3(gx1.w,gy1.w,gz1.w);
152 |
153 | vec4 norm0 = taylorInvSqrt(vec4(dot(g000, g000), dot(g010, g010), dot(g100, g100), dot(g110, g110)));
154 | g000 *= norm0.x;
155 | g010 *= norm0.y;
156 | g100 *= norm0.z;
157 | g110 *= norm0.w;
158 | vec4 norm1 = taylorInvSqrt(vec4(dot(g001, g001), dot(g011, g011), dot(g101, g101), dot(g111, g111)));
159 | g001 *= norm1.x;
160 | g011 *= norm1.y;
161 | g101 *= norm1.z;
162 | g111 *= norm1.w;
163 |
164 | float n000 = dot(g000, Pf0);
165 | float n100 = dot(g100, vec3(Pf1.x, Pf0.yz));
166 | float n010 = dot(g010, vec3(Pf0.x, Pf1.y, Pf0.z));
167 | float n110 = dot(g110, vec3(Pf1.xy, Pf0.z));
168 | float n001 = dot(g001, vec3(Pf0.xy, Pf1.z));
169 | float n101 = dot(g101, vec3(Pf1.x, Pf0.y, Pf1.z));
170 | float n011 = dot(g011, vec3(Pf0.x, Pf1.yz));
171 | float n111 = dot(g111, Pf1);
172 |
173 | vec3 fade_xyz = fade(Pf0);
174 | vec4 n_z = mix(vec4(n000, n100, n010, n110), vec4(n001, n101, n011, n111), fade_xyz.z);
175 | vec2 n_yz = mix(n_z.xy, n_z.zw, fade_xyz.y);
176 | float n_xyz = mix(n_yz.x, n_yz.y, fade_xyz.x);
177 | return 2.2 * n_xyz;
178 | }
179 |
180 | //
181 | // Created largely with the help of ClickToRelease!
182 | // https://www.clicktorelease.com/blog/vertex-displacement-noise-3d-webgl-glsl-three-js/
183 |
184 | varying vec2 vUv;
185 | varying float noise;
186 | uniform float time;
187 |
188 | float turbulence( vec3 p ) {
189 | float w = 100.0;
190 | float t = -.5;
191 | for (float f = 1.0 ; f <= 10.0 ; f++ ){
192 | float power = pow( 2.0, f );
193 | t += abs( pnoise( vec3( power * p ), vec3( 10.0, 10.0, 10.0 ) ) / power );
194 | }
195 | return t;
196 | }
197 |
198 | void main() {
199 |
200 | vUv = uv;
201 |
202 | noise = 10.0 * -.10 * turbulence( .5 * normal + time );
203 | float b = 5.0 * pnoise( 0.05 * position + vec3( 2.0 * time ), vec3( 100.0 ) );
204 | float displacement = - 10. * noise + b;
205 |
206 | vec3 newPosition = position + normal * displacement;
207 | gl_Position = projectionMatrix * modelViewMatrix * vec4( newPosition, 1.0 );
208 |
209 | }
210 | `;
211 |
--------------------------------------------------------------------------------
/assets/models/tree.gltf:
--------------------------------------------------------------------------------
1 | {
2 | "accessors": [
3 | {
4 | "bufferView": 2,
5 | "componentType": 5126,
6 | "count": 12020,
7 | "max": [
8 | 0.80282998085021973,
9 | 1.3153300285339355,
10 | 2.0525000095367432
11 | ],
12 | "min": [
13 | -1.3118699789047241,
14 | -1.439210057258606,
15 | 0.18327000737190247
16 | ],
17 | "type": "VEC3"
18 | },
19 | {
20 | "bufferView": 2,
21 | "byteOffset": 144240,
22 | "componentType": 5126,
23 | "count": 12020,
24 | "max": [
25 | 0.99983775615692139,
26 | 0.99993628263473511,
27 | 0.99950402975082397
28 | ],
29 | "min": [
30 | -0.99997878074645996,
31 | -0.99986916780471802,
32 | -0.99989950656890869
33 | ],
34 | "type": "VEC3"
35 | },
36 | {
37 | "bufferView": 1,
38 | "componentType": 5126,
39 | "count": 12020,
40 | "max": [
41 | 1.0006699562072754,
42 | 1.0001300573348999
43 | ],
44 | "min": [
45 | -0.0019499999471008778,
46 | 0
47 | ],
48 | "type": "VEC2"
49 | },
50 | {
51 | "bufferView": 0,
52 | "componentType": 5125,
53 | "count": 18030,
54 | "max": [
55 | 12019
56 | ],
57 | "min": [
58 | 0
59 | ],
60 | "type": "SCALAR"
61 | },
62 | {
63 | "bufferView": 2,
64 | "byteOffset": 288480,
65 | "componentType": 5126,
66 | "count": 18717,
67 | "max": [
68 | 0.6457899808883667,
69 | 1.1660900115966797,
70 | 1.9106500148773193
71 | ],
72 | "min": [
73 | -1.131909966468811,
74 | -1.2874499559402466,
75 | 0
76 | ],
77 | "type": "VEC3"
78 | },
79 | {
80 | "bufferView": 2,
81 | "byteOffset": 513084,
82 | "componentType": 5126,
83 | "count": 18717,
84 | "max": [
85 | 1,
86 | 0.99992716312408447,
87 | 0.99930250644683838
88 | ],
89 | "min": [
90 | -0.99997878074645996,
91 | -0.99992716312408447,
92 | -0.99930250644683838
93 | ],
94 | "type": "VEC3"
95 | },
96 | {
97 | "bufferView": 1,
98 | "byteOffset": 96160,
99 | "componentType": 5126,
100 | "count": 18717,
101 | "max": [
102 | 2,
103 | 112.55133056640625
104 | ],
105 | "min": [
106 | 0,
107 | 0
108 | ],
109 | "type": "VEC2"
110 | },
111 | {
112 | "bufferView": 0,
113 | "byteOffset": 72120,
114 | "componentType": 5125,
115 | "count": 96276,
116 | "max": [
117 | 18716
118 | ],
119 | "min": [
120 | 0
121 | ],
122 | "type": "SCALAR"
123 | }
124 | ],
125 | "asset": {
126 | "extras": {
127 | "author": "RosticOstafi (https://sketchfab.com/RosticOstafi)",
128 | "license": "CC-BY-4.0 (http://creativecommons.org/licenses/by/4.0/)",
129 | "source": "https://sketchfab.com/3d-models/tree-sakura-4a201fe7f1a548fa9a0b32388be75499",
130 | "title": "Tree Sakura"
131 | },
132 | "generator": "Sketchfab-8.20.0",
133 | "version": "2.0"
134 | },
135 | "bufferViews": [
136 | {
137 | "buffer": 0,
138 | "byteLength": 457224,
139 | "byteOffset": 0,
140 | "name": "floatBufferViews",
141 | "target": 34963
142 | },
143 | {
144 | "buffer": 0,
145 | "byteLength": 245896,
146 | "byteOffset": 457224,
147 | "byteStride": 8,
148 | "name": "floatBufferViews",
149 | "target": 34962
150 | },
151 | {
152 | "buffer": 0,
153 | "byteLength": 737688,
154 | "byteOffset": 703120,
155 | "byteStride": 12,
156 | "name": "floatBufferViews",
157 | "target": 34962
158 | }
159 | ],
160 | "buffers": [
161 | {
162 | "byteLength": 1440808,
163 | "uri": "scene.bin"
164 | }
165 | ],
166 | "images": [
167 | {
168 | "uri": "textures/DL2X2_1_baseColor.png"
169 | },
170 | {
171 | "uri": "textures/DL2X2_1_metallicRoughness.png"
172 | },
173 | {
174 | "uri": "textures/Trank_bark_baseColor.jpeg"
175 | },
176 | {
177 | "uri": "textures/Trank_bark_metallicRoughness.png"
178 | }
179 | ],
180 | "materials": [
181 | {
182 | "alphaMode": "BLEND",
183 | "doubleSided": true,
184 | "name": "DL2X2_1",
185 | "pbrMetallicRoughness": {
186 | "baseColorFactor": [
187 | 1,
188 | 1,
189 | 1,
190 | 1
191 | ],
192 | "baseColorTexture": {
193 | "index": 0,
194 | "texCoord": 0
195 | },
196 | "metallicFactor": 1,
197 | "metallicRoughnessTexture": {
198 | "index": 1,
199 | "texCoord": 0
200 | },
201 | "roughnessFactor": 0.59999999999999998
202 | }
203 | },
204 | {
205 | "doubleSided": true,
206 | "name": "Trank_bark",
207 | "pbrMetallicRoughness": {
208 | "baseColorFactor": [
209 | 0.32488567073170732,
210 | 0.32488567073170732,
211 | 0.32488567073170732,
212 | 1
213 | ],
214 | "baseColorTexture": {
215 | "index": 2,
216 | "texCoord": 0
217 | },
218 | "metallicFactor": 1,
219 | "metallicRoughnessTexture": {
220 | "index": 3,
221 | "texCoord": 0
222 | },
223 | "roughnessFactor": 1
224 | }
225 | }
226 | ],
227 | "meshes": [
228 | {
229 | "primitives": [
230 | {
231 | "attributes": {
232 | "NORMAL": 1,
233 | "POSITION": 0,
234 | "TEXCOORD_0": 2
235 | },
236 | "indices": 3,
237 | "material": 0,
238 | "mode": 4
239 | }
240 | ]
241 | },
242 | {
243 | "primitives": [
244 | {
245 | "attributes": {
246 | "NORMAL": 5,
247 | "POSITION": 4,
248 | "TEXCOORD_0": 6
249 | },
250 | "indices": 7,
251 | "material": 1,
252 | "mode": 4
253 | }
254 | ]
255 | }
256 | ],
257 | "nodes": [
258 | {
259 | "children": [
260 | 1
261 | ],
262 | "name": "RootNode (gltf orientation matrix)",
263 | "rotation": [
264 | -0.70710678118654746,
265 | -0,
266 | -0,
267 | 0.70710678118654757
268 | ]
269 | },
270 | {
271 | "children": [
272 | 2
273 | ],
274 | "name": "RootNode (model correction matrix)"
275 | },
276 | {
277 | "children": [
278 | 3,
279 | 4
280 | ],
281 | "name": "Tree.obj.cleaner.materialmerger.gles"
282 | },
283 | {
284 | "mesh": 0,
285 | "name": ""
286 | },
287 | {
288 | "mesh": 1,
289 | "name": ""
290 | }
291 | ],
292 | "samplers": [
293 | {
294 | "magFilter": 9729,
295 | "minFilter": 9987,
296 | "wrapS": 10497,
297 | "wrapT": 10497
298 | }
299 | ],
300 | "scene": 0,
301 | "scenes": [
302 | {
303 | "name": "OSG_Scene",
304 | "nodes": [
305 | 0
306 | ]
307 | }
308 | ],
309 | "textures": [
310 | {
311 | "sampler": 0,
312 | "source": 0
313 | },
314 | {
315 | "sampler": 0,
316 | "source": 1
317 | },
318 | {
319 | "sampler": 0,
320 | "source": 2
321 | },
322 | {
323 | "sampler": 0,
324 | "source": 3
325 | }
326 | ]
327 | }
328 |
329 |
--------------------------------------------------------------------------------
/src/core/Game.js:
--------------------------------------------------------------------------------
1 | import '../style.css';
2 | import * as THREE from 'three';
3 | import * as dat from 'dat.gui';
4 | import io from 'socket.io-client';
5 | import Stats from 'three/examples/jsm/libs/stats.module';
6 | import { Capsule } from 'three/examples/jsm/math/Capsule';
7 | import { Octree } from 'three/examples/jsm/math/Octree';
8 | import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader';
9 | import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader';
10 | import { Sprite, SpriteMaterial, OrthographicCamera, Scene } from 'three';
11 | import explosionFragment from '../shader/Explosion.frag';
12 | import explosionVertex from '../shader/Explosion.vert';
13 |
14 | class Game {
15 | constructor() {
16 | this.camera = null;
17 | this.scene = null;
18 | this.renderer = null;
19 |
20 | this.gui = null;
21 | this.clock = null;
22 |
23 | this.worldOctree = new Octree();
24 | this.world = new THREE.Group();
25 |
26 | this.lastTime = null;
27 | this.stats = null;
28 | this.drawCallPanel = null;
29 |
30 | this.player = null;
31 | this.players = null;
32 | this.playerCapsule = null;
33 | this.isPlayerGrounded = false;
34 | this.playerSpeed = 50;
35 | this.playerVelocity = null;
36 | this.teleportVec = new THREE.Vector3(0, 0, 0); // Better performance to reuse same vector
37 |
38 | this.Key = {};
39 | this.controls = null;
40 | this.maxJumps = 2;
41 | this.upVector = null;
42 | this.gravity = 70;
43 |
44 | this.toggle = false;
45 | this.collisionsEnabled = true;
46 | this.playerFocused = false;
47 | this.inputDisabled = false;
48 |
49 | this.rockets = [];
50 | this.rocketForce = 90;
51 | this.maxRockets = 100;
52 | this.rocketIdx = 0;
53 | this.deltaRocket = 0;
54 | this.frontRocketLight = null;
55 | this.backRocketLight = null;
56 |
57 | this.textureLoader = new THREE.TextureLoader();
58 | this.textureMap = new Map();
59 |
60 | this.elaspedTime = 0;
61 | this.chatMessages = new Array();
62 |
63 | this.loadingManager = new THREE.LoadingManager();
64 | this.audioLoader = new THREE.AudioLoader(this.loadingManager);
65 | this.listener = new THREE.AudioListener();
66 | this.audioMap = new Map();
67 |
68 | this.shaderLoader = new THREE.TextureLoader();
69 | this.explosionMaterial = null;
70 | this.explosionTime = Date.now();
71 |
72 | this.animRequest;
73 | this.requestAnimId = null;
74 | this.startAnimation = startAnimation.bind(this);
75 | this.stopAnimation = stopAnimation.bind(this);
76 |
77 | this.ui = {
78 | body: document.querySelector('body'),
79 | respawnButton: document.querySelector('.respawn-button-wrapper'),
80 | pauseButton: document.querySelector('.pause-button-wrapper'),
81 | velocityStats: document.querySelector('.velocity-stats'),
82 | positionStats: document.querySelector('.position-stats'),
83 | chatSection: document.getElementById('chatSection'),
84 | chatList: document.querySelector('.chatList'),
85 | crosshair: null,
86 | };
87 | }
88 |
89 | // Loading scene function before game is started
90 | load() {
91 | console.log('PRELOADING...');
92 |
93 | this.initAudio().then(() => {
94 | this.initScene();
95 | this.initSkybox();
96 | this.initMap();
97 | this.initPlayer();
98 | this.initCrosshair();
99 | this.initExplosion();
100 | this.initStats();
101 | this.initDevWIP();
102 | this.initSocket();
103 | });
104 | }
105 |
106 | // Init function when game starts
107 | startGame() {
108 | console.log('START GAME');
109 |
110 | this.activatePointerLock();
111 | this.activateMovement();
112 | this.activateRocketShooting();
113 | this.activateGamePause();
114 | this.startAnimation(); // Starts tick function
115 | this.addChatMessage('Admin', 'Welcome to three arena.');
116 | }
117 |
118 | // Main update game function
119 | tick() {
120 | const delta = this.clock.getDelta();
121 | this.elaspedTime += delta;
122 |
123 | this.updatePlayerControl(delta);
124 | this.updateCheckOnGround(delta);
125 | this.updatePlayerMovement(delta);
126 | this.updateRockets(delta);
127 | this.updateChatList();
128 | this.updateStats();
129 | this.updateCloneCube();
130 |
131 | this.stats.update();
132 | this.renderer.render(this.scene, this.camera);
133 | this.renderer.autoClear = false;
134 | this.renderer.render(this.hudScene, this.hudCamera);
135 | }
136 |
137 | createCloneCube() {
138 | const geometry = new THREE.BoxGeometry();
139 | const material = new THREE.MeshBasicMaterial({ color: 0x00ffff });
140 | this.cube = new THREE.Mesh(geometry, material);
141 | this.scene.add(this.cube);
142 | }
143 |
144 | createMannequin() {
145 | const headGeo = new THREE.BoxGeometry(1, 1, 1);
146 | const bodyGeo = new THREE.BoxGeometry(0.7, 1, 0.7);
147 | const gunGeo = new THREE.BoxGeometry(1.5, 0.2, 0.2);
148 |
149 | const playerMat = new THREE.MeshNormalMaterial();
150 | const gunMat = new THREE.MeshPhongMaterial();
151 | gunMat.color = new THREE.Color(0x000000);
152 |
153 | const playerHead = new THREE.Mesh(headGeo, playerMat);
154 | const playerBody = new THREE.Mesh(bodyGeo, playerMat);
155 | const playerGun = new THREE.Mesh(gunGeo, gunMat);
156 |
157 | playerBody.position.set(0, -1, 0);
158 | playerGun.position.set(0.3, -1, 0.5);
159 |
160 | const playerModel = new THREE.Group();
161 | playerModel.add(playerHead);
162 | playerModel.add(playerBody);
163 | playerModel.add(playerGun);
164 |
165 | this.scene.add(playerModel);
166 | playerModel.position.set(5, 0, 0);
167 | }
168 |
169 | updateCloneCube() {
170 | const position = this.playerCapsule.end;
171 | this.cube.position.set(position.x + 2, position.y + 2, position.z + 2);
172 | }
173 |
174 | // ------------------------------------------------
175 | // Main init functions during loading screen
176 |
177 | initAudio() {
178 | console.log('init audio');
179 | const loadingManager = this.loadingManager;
180 | const audioLoader = this.audioLoader;
181 | const audioMap = this.audioMap;
182 | const listener = this.listener;
183 |
184 | const rocketExplode = new THREE.PositionalAudio(listener);
185 | const rocketFly = new THREE.PositionalAudio(listener);
186 | const ambientSong = new THREE.Audio(listener);
187 |
188 | audioLoader.load('sounds/rocket-explode.ogg', (buffer) =>
189 | rocketExplode.setBuffer(buffer)
190 | );
191 |
192 | audioLoader.load('sounds/rocket-flying.ogg', (buffer) =>
193 | rocketFly.setBuffer(buffer)
194 | );
195 |
196 | audioLoader.load('sounds/slownomotion.ogg', (buffer) => {
197 | ambientSong.setBuffer(buffer);
198 | ambientSong.setLoop(true);
199 | ambientSong.setVolume(0.02);
200 | // ambientSong.play();
201 | });
202 |
203 | audioMap.set('rocketFly', rocketFly);
204 | audioMap.set('rocketExplode', rocketExplode);
205 | audioMap.set('ambientSong', ambientSong);
206 |
207 | loadingManager.onProgress = (url, itemsLoaded, itemsTotal) => {
208 | console.log(
209 | 'Loading file: ' +
210 | url +
211 | '.\nLoaded ' +
212 | itemsLoaded +
213 | ' of ' +
214 | itemsTotal +
215 | ' files.'
216 | );
217 | };
218 |
219 | loadingManager.onError = function (url) {
220 | console.log('There was an error loading ' + url);
221 | };
222 |
223 | return new Promise((resolve) => {
224 | loadingManager.onLoad = () => {
225 | resolve();
226 | console.log('All loading completed!');
227 | };
228 | });
229 | }
230 |
231 | initScene() {
232 | this.gui = new dat.GUI();
233 | this.clock = new THREE.Clock();
234 | this.scene = new THREE.Scene();
235 |
236 | this.camera = new THREE.PerspectiveCamera(
237 | 75,
238 | window.innerWidth / window.innerHeight,
239 | 0.1,
240 | 2000
241 | );
242 | this.camera.add(this.listener);
243 |
244 | this.renderer = new THREE.WebGLRenderer({
245 | powerPreference: 'high-performance',
246 | antialias: false,
247 | });
248 | this.renderer.setSize(window.innerWidth, window.innerHeight);
249 | this.renderer.setPixelRatio(Math.min(window.devicePixelRatio, 1));
250 | this.renderer.shadowMap.enabled = true;
251 | this.renderer.shadowMap.type = THREE.PCFSoftShadowMap;
252 | this.ui.body.appendChild(this.renderer.domElement);
253 |
254 | window.addEventListener('resize', () => {
255 | this.camera.aspect = window.innerWidth / window.innerHeight;
256 | this.camera.updateProjectionMatrix();
257 | this.renderer.setSize(window.innerWidth, window.innerHeight);
258 | this.hudSetSize(window.innerWidth, window.innerHeight);
259 | this.renderer.setPixelRatio(Math.min(window.devicePixelRatio, 1));
260 | });
261 |
262 | // Maybe other init functions here such as field, playermodel, map, objects, rockets etc in here
263 | console.log('init scene');
264 | }
265 |
266 | initSkybox() {
267 | this.scene.background = new THREE.CubeTextureLoader().load([
268 | 'skybox/Right_Tex.webp',
269 | 'skybox/Left_Tex.webp',
270 | 'skybox/Up_Tex.webp',
271 | 'skybox/Down_Tex.webp',
272 | 'skybox/Front_Tex.webp',
273 | 'skybox/Back_Tex.webp',
274 | ]);
275 |
276 | console.log('init skybox');
277 | }
278 |
279 | initMap() {
280 | const ambientLight = new THREE.AmbientLight(0xddbf96, 0.6); // Soft white light
281 | const dirLight = new THREE.DirectionalLight(0xfcd6a4, 1);
282 |
283 | dirLight.position.set(-25, 250, 120);
284 | dirLight.castShadow = true;
285 | dirLight.shadow.camera.near = 1;
286 | dirLight.shadow.camera.far = 2000;
287 | dirLight.shadow.camera.right = 250;
288 | dirLight.shadow.camera.left = -250;
289 | dirLight.shadow.camera.top = 250;
290 | dirLight.shadow.camera.bottom = -250;
291 | dirLight.shadow.mapSize.width = 4064;
292 | dirLight.shadow.mapSize.height = 4064;
293 | dirLight.shadow.radius = 0.6;
294 |
295 | this.scene.add(ambientLight);
296 | this.scene.add(dirLight);
297 |
298 | const gltfLoader = new GLTFLoader().setPath('models/');
299 | const dracoLoader = new DRACOLoader();
300 | dracoLoader.setDecoderPath('draco/');
301 | gltfLoader.setDRACOLoader(dracoLoader);
302 | gltfLoader.load('scene.glb', (gltf) => {
303 | gltf.scene.traverse((model) => {
304 | model.receiveShadow = true;
305 | model.castShadow = true;
306 | });
307 | gltf.scene.receiveShadow = true;
308 | gltf.scene.castShadow = true;
309 | this.world.add(gltf.scene);
310 | this.worldOctree.fromGraphNode(gltf.scene);
311 | });
312 | gltfLoader.load('tree.gltf', (gltf) => {
313 | gltf.scene.traverse((model) => {
314 | model.castShadow = true;
315 | });
316 | gltf.scene.scale.set(35, 35, 35);
317 | gltf.scene.position.set(-3, -10, -3);
318 | this.world.add(gltf.scene);
319 | });
320 |
321 | // TEST Objects
322 | const geometry = new THREE.IcosahedronGeometry(1);
323 | const bgGeometry = new THREE.PlaneBufferGeometry(1500, 1500, 128, 128);
324 |
325 | const textureRock = new THREE.TextureLoader().load(
326 | 'models/rocktexture.jpg'
327 | );
328 | textureRock.wrapS = THREE.RepeatWrapping;
329 | textureRock.wrapT = THREE.RepeatWrapping;
330 | textureRock.repeat.set(1, 1);
331 |
332 | const displacementMap = new THREE.TextureLoader().load(
333 | 'models/paintbg.png'
334 | );
335 | displacementMap.wrapS = THREE.RepeatWrapping;
336 | displacementMap.wrapT = THREE.RepeatWrapping;
337 | displacementMap.repeat.set(1, 1);
338 | const textMat = new THREE.MeshPhongMaterial({
339 | color: '#030303',
340 | map: textureRock,
341 | shininess: 0,
342 | displacementMap: displacementMap,
343 | displacementScale: 500,
344 | displacementBias: -0.428408,
345 | });
346 |
347 | const bgMaterial = new THREE.MeshBasicMaterial();
348 | bgMaterial.color = new THREE.Color(0xff111111);
349 | const material = new THREE.MeshPhongMaterial();
350 | material.color = new THREE.Color(0xff109000);
351 |
352 | const sphere = new THREE.Mesh(geometry, material);
353 | const bgfull = new THREE.Mesh(bgGeometry, textMat);
354 |
355 | bgfull.position.set(0, -210, 0);
356 | bgfull.rotation.x = -89.5;
357 | bgfull.rotation.z = 89.5;
358 |
359 | sphere.castShadow = true;
360 | sphere.position.set(0, 75, 0);
361 | sphere.scale.set(2, 2, 2);
362 |
363 | this.scene.add(bgfull);
364 | this.world.add(sphere);
365 | this.scene.add(this.world);
366 | this.worldOctree.fromGraphNode(this.world);
367 |
368 | console.log('init map');
369 | }
370 |
371 | initPlayer() {
372 | this.playerVelocity = new THREE.Vector3();
373 | this.playerDirection = new THREE.Vector3();
374 | this.upVector = new THREE.Vector3(0, 1, 0);
375 |
376 | // https://wickedengine.net/2020/04/26/capsule-collision-detection/
377 | this.playerCapsule = new Capsule(
378 | new THREE.Vector3(),
379 | new THREE.Vector3(0, 2, 0),
380 | 0.5
381 | );
382 |
383 | this.triggerRespawn();
384 | this.playerCapsule.translate(this.teleportVec.set(0, 100, 0));
385 |
386 | console.log('init player');
387 | }
388 |
389 | initCrosshair() {
390 | const textureLoader = this.textureLoader;
391 |
392 | let texture = textureLoader.load('images/crosshair.png');
393 | texture.matrixAutoUpdate = false;
394 | this.textureMap.set('crosshair', texture);
395 |
396 | const crosshairTexture = this.textureMap.get('crosshair');
397 | const crosshairMat = new SpriteMaterial({
398 | map: crosshairTexture,
399 | opacity: 1,
400 | });
401 |
402 | const crosshair = new Sprite(crosshairMat);
403 | crosshair.matrixAutoUpdate = false;
404 | crosshair.visible = true;
405 | crosshair.position.set(0, 0, 2);
406 | crosshair.scale.set(70, 70, 1);
407 | crosshair.updateMatrix();
408 |
409 | this.ui.crosshair = crosshair;
410 |
411 | this.hudCamera = new OrthographicCamera(
412 | -window.innerWidth / 2,
413 | window.innerWidth / 2,
414 | window.innerHeight / 2,
415 | -window.innerHeight / 2,
416 | 1,
417 | 10
418 | );
419 | this.hudCamera.position.z = 10;
420 | this.hudScene = new Scene();
421 | this.hudScene.add(crosshair);
422 |
423 | console.log('init crosshair');
424 | return this;
425 | }
426 |
427 | initExplosion() {
428 | this.shaderLoader.load(
429 | 'models/explosion.png',
430 | (texture) => {
431 | this.explosionMaterial = new THREE.ShaderMaterial({
432 | uniforms: {
433 | tExplosion: {
434 | type: 't',
435 | value: texture,
436 | },
437 | time: {
438 | type: 'f',
439 | value: 0.0,
440 | },
441 | },
442 | vertexShader: explosionVertex,
443 | fragmentShader: explosionFragment,
444 | });
445 |
446 | this.rocketExplosion = new THREE.Mesh(
447 | new THREE.IcosahedronGeometry(10, 10),
448 | this.explosionMaterial
449 | );
450 | this.scene.add(this.rocketExplosion);
451 | this.rocketExplosion.position.set(0, 10, -50);
452 | console.log('init explosions');
453 |
454 | this.initRockets();
455 | },
456 | undefined,
457 | function (err) {
458 | console.error(
459 | 'An error happened whilst loading initExplosions'
460 | );
461 | }
462 | );
463 | }
464 |
465 | initRockets() {
466 | const rocketGeometry = new THREE.CylinderGeometry(0.05, 0.15, 2, 12);
467 | const rocketMaterial = new THREE.MeshPhongMaterial();
468 | rocketMaterial.color = new THREE.Color(0x000000);
469 |
470 | this.frontRocketLight = new THREE.PointLight(0xffaa00, 0.1);
471 | this.backRocketLight = new THREE.PointLight(0xff0000, 0.1);
472 |
473 | this.scene.add(this.frontRocketLight, this.backRocketLight);
474 |
475 | this.frontRocketLight.castShadow = true;
476 | this.backRocketLight.castShadow = true;
477 |
478 | for (let i = 0; i < this.maxRockets; i++) {
479 | const coolRocket = new THREE.Mesh(rocketGeometry, rocketMaterial);
480 | const coolExplosion = this.rocketExplosion.clone();
481 | coolRocket.castShadow = true;
482 | coolRocket.receiveShadow = true;
483 | coolRocket.userData.isExploded = false;
484 |
485 | const audioFly = this.createAudioInstance(
486 | this.audioMap.get('rocketFly')
487 | );
488 | const audioExplode = this.createAudioInstance(
489 | this.audioMap.get('rocketExplode')
490 | );
491 | coolRocket.add(audioFly);
492 | coolRocket.add(audioExplode);
493 |
494 | coolExplosion.position.set(0, 0, 0);
495 | coolExplosion.visible = false;
496 | coolExplosion.name = 'explosion';
497 | this.scene.add(coolRocket);
498 | coolRocket.add(coolExplosion);
499 |
500 | this.rockets.push({
501 | mesh: coolRocket,
502 | collider: new THREE.Sphere(new THREE.Vector3(0, -50, 0), 0.5),
503 | velocity: new THREE.Vector3(),
504 | timer: new THREE.Clock(),
505 | });
506 | }
507 | console.log('init rockets');
508 | }
509 |
510 | initStats() {
511 | this.stats = new Stats();
512 | this.drawCallPanel = this.stats.addPanel(
513 | new Stats.Panel('drawcalls', '#ff8', '#221')
514 | );
515 | this.stats.showPanel(0, 1, 3);
516 | this.ui.body.appendChild(this.stats.domElement);
517 | this.ui.body.appendChild(this.stats.domElement);
518 |
519 | this.lastTime = performance.now();
520 | }
521 |
522 | initDevWIP() {
523 | this.createCloneCube();
524 | this.createMannequin();
525 | }
526 |
527 | initSocket() {
528 | console.log('init socket');
529 | this.socket = io('https://three-arena.fly.dev/');
530 |
531 | this.player = {};
532 | this.players = {};
533 |
534 | this.socket.on('connect', () => {
535 | this.socket.on('initPlayer', (data, playerCount, playerIDs) => {
536 | this.player.id = data.id;
537 | console.log(
538 | `I am ${this.socket.id}, the ${playerCount}${
539 | playerCount <= 1
540 | ? 'st'
541 | : playerCount == 2
542 | ? 'nd'
543 | : playerCount == 3
544 | ? 'rd'
545 | : 'th'
546 | } player`
547 | );
548 |
549 | // Check all that isn't local player
550 | for (let i = 0; i < playerCount; i++) {
551 | if (playerIDs[i] !== this.player.id) {
552 | console.log(
553 | `${playerIDs[i]} needs to be added to the world...`
554 | );
555 | this.initRemotePlayer(playerIDs[i]);
556 | }
557 | }
558 | });
559 | });
560 |
561 | this.socket.on('playerPositions', (players) => {
562 | this.updateRemotePlayers(players);
563 | });
564 |
565 | this.socket.on('player connect', (playerId, playerCount) => {
566 | console.log(`${playerId} joined the session!`);
567 | console.log(`There are now ${playerCount} players`);
568 | if (playerId !== this.player.id) {
569 | console.log(`${playerId} needs to be added to the world...`);
570 | this.initRemotePlayer(playerId);
571 | }
572 | this.addStatusMessage(playerId, 'join');
573 | });
574 |
575 | this.socket.on('player disconnect', (playerId, playerCount) => {
576 | this.deleteRemotePlayer(playerId);
577 | console.log(`${playerId} has left us...`);
578 | console.log(`There are now ${playerCount} players`);
579 | this.addStatusMessage(playerId, 'leave');
580 | });
581 |
582 | this.socket.on('connect', () => {
583 | this.socket.on('chat message', (username, message) => {
584 | this.addChatMessage(username, message);
585 | });
586 | });
587 |
588 | this.socket.on('shootSyncRocket', (playerData, playerID) => {
589 | this.shootRemoteRocket(playerData, playerID);
590 | });
591 |
592 | this.socket.on('kill message', (shooter, killed) => {
593 | if (shooter) {
594 | this.addKillMessage(shooter, killed);
595 | } else {
596 | this.addKillMessage(killed);
597 | }
598 | });
599 | }
600 |
601 | initRemotePlayer(playerID) {
602 | const geometry = new THREE.BoxGeometry(1, 1, 1);
603 | const material = new THREE.MeshNormalMaterial();
604 | material.color = new THREE.Color(0x000000);
605 |
606 | const remotePlayer = new THREE.Mesh(geometry, material);
607 | remotePlayer.position.set(0, 0, 0);
608 |
609 | this.scene.add(remotePlayer);
610 |
611 | this.players[playerID] = {};
612 | this.players[playerID].mesh = remotePlayer;
613 | this.players[playerID].positionSync = new THREE.Vector3();
614 | this.players[playerID].lookDirection = new THREE.Vector3();
615 |
616 | console.log(`${playerID} added to the scene!`);
617 | console.log(this.players);
618 | }
619 |
620 | deleteRemotePlayer(playerID) {
621 | this.scene.remove(this.players[playerID].mesh);
622 | delete this.players[playerID];
623 | console.log(this.players);
624 | }
625 |
626 | updateRemotePlayers(remotePlayers) {
627 | for (let id in remotePlayers) {
628 | if (id != this.player.id) {
629 | // Should not forget to reuse vectors
630 | this.players[id].positionSync = new THREE.Vector3().fromArray(
631 | remotePlayers[id].position
632 | );
633 | this.players[id].lookDirection = new THREE.Vector3().fromArray(
634 | remotePlayers[id].direction
635 | );
636 |
637 | // Set player position
638 | this.players[id].mesh.position.set(
639 | this.players[id].positionSync.x,
640 | this.players[id].positionSync.y,
641 | this.players[id].positionSync.z
642 | );
643 |
644 | // Set head rotation
645 | this.players[id].mesh.rotation.y =
646 | this.players[id].lookDirection.x;
647 | this.players[id].mesh.rotation.x =
648 | this.players[id].lookDirection.y;
649 | }
650 | }
651 | }
652 |
653 | uploadMovementData() {
654 | this.socket.emit(
655 | 'updateClientPos',
656 | [
657 | this.playerCapsule.end.x,
658 | this.playerCapsule.end.y,
659 | this.playerCapsule.end.z,
660 | ],
661 | this.lookVector().toArray()
662 | );
663 | }
664 |
665 | // ------------------------------------------------
666 | // Activate functions when game starts
667 |
668 | activatePointerLock() {
669 | this.ui.body.requestPointerLock();
670 |
671 | document.querySelector('canvas').addEventListener('mousedown', () => {
672 | !this.inputDisabled && this.ui.body.requestPointerLock();
673 | });
674 |
675 | this.camera.rotation.order = 'YXZ';
676 |
677 | document.addEventListener('mousemove', (event) => {
678 | if (document.pointerLockElement === this.ui.body) {
679 | // add check looking for 360 rotation
680 | this.camera.rotation.x -= event.movementY / 700;
681 | this.camera.rotation.y -= event.movementX / 700;
682 | }
683 | });
684 |
685 | document.addEventListener('pointerlockchange', () => {
686 | this.playerFocused = document.pointerLockElement === this.ui.body;
687 | console.log(`Player Focus is ${this.playerFocused}`);
688 | });
689 |
690 | document.addEventListener(
691 | 'click',
692 | (event) => {
693 | if (this.inputDisabled) {
694 | event.stopPropagation();
695 | event.preventDefault();
696 | }
697 | },
698 | true
699 | );
700 |
701 | console.log('Activate pointerlock');
702 | }
703 |
704 | activateGamePause() {
705 | this.ui.pauseButton.addEventListener('click', () => {
706 | this.toggle = !this.toggle;
707 | this.toggle ? this.stopAnimation() : this.startAnimation();
708 | });
709 | }
710 |
711 | activateMovement() {
712 | document.addEventListener('keydown', (event) => {
713 | !this.inputDisabled && (this.Key[event.key] = true);
714 | if (event.key == 'Enter') {
715 | event.preventDefault();
716 | }
717 | });
718 | document.addEventListener('keyup', (event) => {
719 | this.Key[event.key] = false;
720 | });
721 |
722 | console.log('Activate movement controls');
723 | }
724 |
725 | activateRocketShooting() {
726 | let canShoot = true;
727 |
728 | document.addEventListener('click', () => {
729 | if (canShoot) {
730 | // Currently bug causes rocket to misalign after reaching maxRocket count, AKA when rocketIdx is reset.
731 | const rocket = this.rockets[this.rocketIdx];
732 |
733 | // Align rocket to look direction
734 | rocket.mesh.lookAt(this.lookVector().negate());
735 |
736 | rocket.mesh.add(this.frontRocketLight, this.backRocketLight);
737 | this.frontRocketLight.position.set(0, -1.1, 0);
738 | this.backRocketLight.position.set(0, -1.2, 0);
739 | this.frontRocketLight.power = 120;
740 | this.backRocketLight.power = 100;
741 | this.frontRocketLight.distance = 10;
742 | this.backRocketLight.distance = 10; // use for animation
743 |
744 | // Copy player head pos to projectile center
745 | rocket.collider.center.copy(this.playerCapsule.end);
746 |
747 | // Apply force in look direction
748 | rocket.velocity
749 | .copy(this.lookVector())
750 | .multiplyScalar(this.rocketForce);
751 |
752 | // Reset explode state
753 | rocket.mesh.userData.isExploded = false;
754 |
755 | // Set rocket visible
756 | rocket.mesh.visible = true;
757 |
758 | // Emit to other players
759 | this.socket.emit('triggerRemoteRocket');
760 |
761 | this.rocketIdx = (this.rocketIdx + 1) % this.rockets.length;
762 |
763 | canShoot = false;
764 | console.log('Rocket fired');
765 |
766 | setTimeout(() => {
767 | canShoot = true;
768 | }, 500);
769 | }
770 | });
771 | }
772 |
773 | shootRemoteRocket(playerData, playerID) {
774 | const rocket = this.rockets[this.rocketIdx];
775 | const playerPosition = new THREE.Vector3().fromArray(
776 | playerData.position
777 | );
778 | const playerDirection = new THREE.Vector3().fromArray(
779 | playerData.direction
780 | );
781 |
782 | // Model direction
783 | rocket.mesh.lookAt(playerDirection.negate());
784 |
785 | rocket.mesh.add(this.frontRocketLight, this.backRocketLight);
786 | this.frontRocketLight.position.set(0, -1.1, 0);
787 | this.backRocketLight.position.set(0, -1.2, 0);
788 | this.frontRocketLight.power = 120;
789 | this.backRocketLight.power = 100;
790 | this.frontRocketLight.distance = 10;
791 | this.backRocketLight.distance = 10; // Could be used for explosion animation
792 |
793 | // Spawn Position
794 | rocket.collider.center.copy(playerPosition);
795 |
796 | // Spawn shoot direction
797 | rocket.velocity
798 | .copy(playerDirection.negate())
799 | .multiplyScalar(this.rocketForce);
800 |
801 | // Reset explode state
802 | rocket.mesh.userData.isExploded = false;
803 |
804 | // Set rocket owner
805 | rocket.mesh.userData.shooter = playerID;
806 |
807 | // Set visible
808 | rocket.mesh.visible = true;
809 |
810 | this.rocketIdx = (this.rocketIdx + 1) % this.rockets.length;
811 |
812 | console.log('Remote rocket fired');
813 | }
814 |
815 | // ------------------------------------------------
816 | // Functions to update game in animation function (tick)
817 |
818 | updatePlayerControl(delta) {
819 | if (this.Key['w']) {
820 | this.playerVelocity.add(
821 | this.lookVector().multiplyScalar(this.playerSpeed * delta)
822 | );
823 | }
824 | if (this.Key['a']) {
825 | this.playerVelocity.add(
826 | this.playerDirection.crossVectors(
827 | this.upVector,
828 | this.lookVector().multiplyScalar(this.playerSpeed * delta)
829 | )
830 | );
831 | }
832 | if (this.Key['s']) {
833 | this.playerVelocity.add(
834 | this.lookVector()
835 | .negate()
836 | .multiplyScalar(this.playerSpeed * delta)
837 | );
838 | }
839 | if (this.Key['d']) {
840 | this.playerVelocity.add(
841 | this.playerDirection.crossVectors(
842 | this.upVector,
843 | this.lookVector()
844 | .negate()
845 | .multiplyScalar(this.playerSpeed * delta)
846 | )
847 | );
848 | }
849 | if (this.isPlayerGrounded) {
850 | if (this.Key[' ']) {
851 | this.playerVelocity.y = 50;
852 | }
853 | }
854 | if (this.Key['Control']) {
855 | this.playerVelocity.y -= this.playerSpeed * delta;
856 | }
857 | if (this.Key['e']) {
858 | this.playerVelocity.set(0, 0, 0);
859 | }
860 | if (this.Key['t']) {
861 | openForm();
862 | }
863 | if (this.Key['Enter']) {
864 | closeForm();
865 | let inputText = document.getElementById('inputText');
866 | if (inputText.value !== '') {
867 | this.socket.emit(
868 | 'chat message',
869 | this.socket.id,
870 | inputText.value
871 | );
872 | inputText.value = '';
873 | }
874 | }
875 | }
876 |
877 | updateCheckOnGround(delta) {
878 | if (this.isPlayerGrounded) {
879 | this.playerVelocity.addScaledVector(
880 | this.playerVelocity,
881 | -5 * delta
882 | );
883 | } else if (this.playerFocused) {
884 | this.playerVelocity.y -= this.gravity * delta;
885 | }
886 | }
887 |
888 | updatePlayerMovement(delta) {
889 | // if (this.collisionsEnabled) {
890 | this.playerCollision();
891 | // }
892 |
893 | if (this.playerFocused) {
894 | const deltaPosition = this.playerVelocity
895 | .clone()
896 | .multiplyScalar(delta);
897 | this.playerCapsule.translate(deltaPosition);
898 | this.camera.position.copy(this.playerCapsule.end);
899 |
900 | this.uploadMovementData();
901 | }
902 |
903 | if (
904 | this.camera.position.y < -10 &&
905 | Math.abs(this.camera.position.x) <= 125 &&
906 | Math.abs(this.camera.position.z) <= 125
907 | ) {
908 | console.log('Player glitched through floor, correction applied');
909 | this.teleportToGround();
910 | this.playerVelocity.setY(0);
911 | // this.collisionsEnabled = true;
912 | }
913 |
914 | if (this.camera.position.y < -200) {
915 | console.log('Player fell off the map, up they go');
916 | let pushForce = 200;
917 | this.camera.position.y < -500 && (pushForce = 500);
918 | this.playerVelocity.set(0, 0, 0);
919 | this.playerVelocity.y = pushForce;
920 | // this.collisionsEnabled = false;
921 |
922 | if (this.camera.position.y < -1000) {
923 | console.log('Player way off, teleported back up');
924 | this.teleportToGround(50);
925 | this.playerVelocity.set(0, 0, 0);
926 | }
927 |
928 | setTimeout(() => {
929 | this.camera.position.y > -200 &&
930 | console.log('World collisions re-enabled');
931 | // this.collisionsEnabled = true;
932 | }, 2500);
933 | }
934 | }
935 |
936 | updateRockets(delta) {
937 | if (this.explosionMaterial) {
938 | this.explosionMaterial.uniforms['time'].value =
939 | 0.00025 * (Date.now() - this.explosionTime);
940 | }
941 |
942 | this.rockets.forEach((rocket) => {
943 | rocket.collider.center.addScaledVector(rocket.velocity, delta);
944 |
945 | // Check collision
946 | const result = this.worldOctree.sphereIntersect(rocket.collider);
947 |
948 | let airRocketIdx;
949 | if (this.rocketIdx > 0) {
950 | airRocketIdx = this.rocketIdx - 1;
951 | } else {
952 | airRocketIdx = this.rocketIdx;
953 | }
954 |
955 | const flySound = this.rockets[airRocketIdx].mesh.children[0];
956 | const explodeSound = this.rockets[airRocketIdx].mesh.children[1];
957 |
958 | if (this.rocketIdx !== this.deltaRocket) {
959 | this.deltaRocket = this.rocketIdx;
960 |
961 | flySound.offset = 1;
962 | flySound.play();
963 | }
964 |
965 | // On rocket impact
966 | if (result) {
967 | rocket.velocity.set(0, 0, 0);
968 | const explodeMesh = rocket.mesh.getObjectByName('explosion');
969 |
970 | if (!rocket.mesh.userData.isExploded) {
971 | rocket.mesh.userData.isExploded = true;
972 | console.log('Rocket hit');
973 |
974 | const playerDistance =
975 | this.playerCapsule.end.distanceToSquared(
976 | rocket.collider.center
977 | );
978 |
979 | // On Player hit
980 | if (playerDistance < 170) {
981 | this.socket.emit(
982 | 'kill message',
983 | rocket.mesh.userData.shooter,
984 | this.player.id
985 | );
986 |
987 | this.triggerDeath();
988 | }
989 |
990 | explodeSound.offset = 0.05;
991 | explodeSound.play();
992 | flySound.stop();
993 |
994 | explodeMesh.visible = true;
995 | rocket.timer.start();
996 | }
997 |
998 | if (rocket.timer.getElapsedTime() >= 0.2) {
999 | {
1000 | // Plays once
1001 | rocket.timer.stop();
1002 | explodeMesh.scale.set(0, 0, 0);
1003 | explodeMesh.position.set(0, 0, 0);
1004 | rocket.mesh.visible = false;
1005 |
1006 | // For looping animation, both do same thing, start() would seem most efficient
1007 | // this.explodeClock = new THREE.Clock();
1008 | // rocket.timer.start()
1009 | }
1010 | } else {
1011 | let size = 0 + rocket.timer.getElapsedTime() * 8;
1012 | explodeMesh.scale.set(size, size, size);
1013 | }
1014 | } else {
1015 | // Whilst in air
1016 | rocket.velocity.y -= (this.gravity / 15) * delta;
1017 | }
1018 |
1019 | // Accelerate with time
1020 | const acceleration = Math.exp(3 * delta) - 1;
1021 | rocket.velocity.addScaledVector(rocket.velocity, acceleration);
1022 |
1023 | rocket.mesh.position.copy(rocket.collider.center);
1024 | });
1025 | }
1026 |
1027 | updateChatList() {
1028 | const chatMessages = this.chatMessages;
1029 |
1030 | for (let i = chatMessages.length - 1; i >= 0; i--) {
1031 | const message = chatMessages[i];
1032 |
1033 | if (this.elaspedTime >= message.endTime) {
1034 | chatMessages.splice(i, 1);
1035 |
1036 | const chatList = this.ui.chatList;
1037 | chatList.removeChild(message.ui);
1038 | }
1039 | }
1040 |
1041 | if (chatMessages.length === 0) {
1042 | this.ui.chatSection.classList.add('hidden');
1043 | }
1044 |
1045 | return this;
1046 | }
1047 |
1048 | updateStats() {
1049 | this.ui.velocityStats.innerHTML = `
1050 | X: ${this.roundStat(this.playerVelocity.x)}
1051 | Y: ${this.roundStat(this.playerVelocity.y)}
1052 | Z: ${this.roundStat(this.playerVelocity.z)}`;
1053 |
1054 | this.ui.positionStats.innerHTML = `
1055 | X: ${this.roundStat(this.camera.position.x)}
1056 | Y: ${this.roundStat(this.camera.position.y)}
1057 | Z: ${this.roundStat(this.camera.position.z)}`;
1058 |
1059 | if (performance.now() - this.lastTime < 1000 / 1) return;
1060 | this.lastTime = performance.now();
1061 | this.drawCallPanel.update(this.renderer.info.render.calls);
1062 | }
1063 |
1064 | // ------------------------------------------------
1065 | // General functions
1066 |
1067 | triggerDeath() {
1068 | console.log('You died');
1069 | document.exitPointerLock();
1070 | this.respawnWaitingRoom();
1071 | this.inputDisabled = true;
1072 | this.ui.respawnButton.style.pointerEvents = 'none';
1073 | this.ui.respawnButton.style.userSelect = 'none';
1074 | this.ui.respawnButton.style.display = 'block';
1075 | this.ui.respawnButton.lastChild.style.fontSize = '30px';
1076 | this.ui.respawnButton.lastChild.style.transform = 'translate(0px, 0px)';
1077 | this.ui.respawnButton.lastChild.textContent = `Respawn in 5`;
1078 |
1079 | let countdown = 5;
1080 | const timer = setInterval(() => {
1081 | countdown--;
1082 | countdown <= 0 && clearInterval(timer);
1083 | this.ui.respawnButton.lastChild.textContent = `Respawn in ${countdown}`;
1084 | }, 1000);
1085 |
1086 | setTimeout(() => {
1087 | console.log('You can now respawn');
1088 | this.inputDisabled = false;
1089 | this.ui.respawnButton.style.userSelect = 'unset';
1090 | this.ui.respawnButton.style.pointerEvents = 'unset';
1091 | this.ui.respawnButton.lastChild.textContent = `RESPAWN`;
1092 | this.ui.respawnButton.lastChild.style.fontSize = '40px';
1093 | this.ui.respawnButton.lastChild.style.transform =
1094 | 'translate(8px, 8px)';
1095 | }, 5000);
1096 | }
1097 |
1098 | triggerRespawn() {
1099 | console.log('Respawn triggered');
1100 | const distFromX = -this.playerCapsule.end.x;
1101 | const distToGround = Math.abs(this.playerCapsule.end.y);
1102 | const distFromZ = -this.playerCapsule.end.z;
1103 | this.playerCapsule.translate(
1104 | this.teleportVec.set(
1105 | distFromX + this.getRandomBetween(10, 120),
1106 | distToGround + 50,
1107 | distFromZ + this.getRandomBetween(10, 120)
1108 | )
1109 | );
1110 | this.playerVelocity.set(0, 0, 0);
1111 | this.gravity = 70;
1112 | }
1113 |
1114 | addChatMessage(username, message) {
1115 | const usernameSpan = document.createElement('span');
1116 | usernameSpan.style.color = '#0fff00';
1117 | usernameSpan.textContent = username;
1118 |
1119 | const middleSpan = document.createElement('span');
1120 | middleSpan.textContent = ': ';
1121 |
1122 | const messageSpan = document.createElement('span');
1123 | messageSpan.style.color = '#ffffff';
1124 | messageSpan.textContent = message;
1125 |
1126 | const content = document.createElement('li');
1127 | content.appendChild(usernameSpan);
1128 | content.appendChild(middleSpan);
1129 | content.appendChild(messageSpan);
1130 |
1131 | this.createMessage(content);
1132 | }
1133 |
1134 | addKillMessage(shooter, killed) {
1135 | const shooterSpan = document.createElement('span');
1136 | shooterSpan.textContent = `${shooter}`;
1137 | shooterSpan.style.color = '#00ff00';
1138 |
1139 | const middleSpan = document.createElement('span');
1140 | middleSpan.textContent = ' ︻┳═一 ';
1141 |
1142 | const killedSpan = document.createElement('span');
1143 | killedSpan.textContent = killed;
1144 | killedSpan.style.color = '#ff0000';
1145 |
1146 | const content = document.createElement('li');
1147 | content.style.color = '#ffff00';
1148 | content.style.fontWeight = '500';
1149 | content.appendChild(shooterSpan);
1150 | content.appendChild(middleSpan);
1151 | content.appendChild(killedSpan);
1152 |
1153 | this.createMessage(content);
1154 | }
1155 |
1156 | addStatusMessage(username, status) {
1157 | const usernameSpan = document.createElement('span');
1158 | usernameSpan.textContent = username;
1159 |
1160 | const statusSpan = document.createElement('span');
1161 | statusSpan.textContent = status;
1162 |
1163 | const content = document.createElement('li');
1164 | switch (status) {
1165 | case 'join':
1166 | content.style.color = '#00ff00';
1167 | statusSpan.textContent = ' has joined the game';
1168 | break;
1169 | case 'leave':
1170 | content.style.color = '#ff0000';
1171 | statusSpan.textContent = ' has left the game ';
1172 | break;
1173 | default:
1174 | statusSpan.textContent = ' unknown status event ';
1175 | break;
1176 | }
1177 | content.appendChild(usernameSpan);
1178 | content.appendChild(statusSpan);
1179 |
1180 | this.createMessage(content);
1181 | }
1182 |
1183 | createMessage(content) {
1184 | this.ui.chatSection.classList.remove('hidden');
1185 |
1186 | const chatMessage = {
1187 | endTime: this.elaspedTime + 10,
1188 | ui: content,
1189 | };
1190 |
1191 | this.chatMessages.push(chatMessage);
1192 | const chatList = this.ui.chatList;
1193 | chatList.appendChild(content);
1194 |
1195 | return this;
1196 | }
1197 |
1198 | roundStat(data) {
1199 | return Math.round(data * 100) / 100;
1200 | }
1201 |
1202 | lookVector() {
1203 | this.camera.getWorldDirection(this.playerDirection);
1204 | this.playerDirection.normalize();
1205 | return this.playerDirection;
1206 | }
1207 |
1208 | playerCollision() {
1209 | const collide = this.worldOctree.capsuleIntersect(this.playerCapsule);
1210 | this.isPlayerGrounded = false;
1211 | if (collide) {
1212 | this.isPlayerGrounded = collide.normal.y > 0;
1213 |
1214 | this.playerCapsule.translate(
1215 | collide.normal.multiplyScalar(collide.depth)
1216 | );
1217 | }
1218 | }
1219 |
1220 | createAudioInstance(source) {
1221 | const audio = new source.constructor(source.listener);
1222 | audio.buffer = source.buffer;
1223 |
1224 | return audio;
1225 | }
1226 |
1227 | hudSetSize(width, height) {
1228 | this.hudCamera.left = -width / 2;
1229 | this.hudCamera.right = width / 2;
1230 | this.hudCamera.top = height / 2;
1231 | this.hudCamera.bottom = -height / 2;
1232 | this.hudCamera.updateProjectionMatrix();
1233 |
1234 | return this;
1235 | }
1236 |
1237 | getRandomBetween(min, max) {
1238 | return Math.random() * (max - min) + min;
1239 | }
1240 |
1241 | teleportToGround(extraDistance = 0) {
1242 | const distToGround = Math.abs(this.playerCapsule.end.y);
1243 | this.playerCapsule.translate(
1244 | this.teleportVec.set(0, distToGround + extraDistance, 0)
1245 | );
1246 | }
1247 |
1248 | toggleInputs() {
1249 | this.inputDisabled = !this.inputDisabled;
1250 | this.inputDisabled ? console.log('enabled') : console.log('disabled');
1251 | }
1252 |
1253 | respawnWaitingRoom() {
1254 | this.gravity = 0;
1255 | const distFromX = -this.playerCapsule.end.x;
1256 | const distToGround = Math.abs(this.playerCapsule.end.y);
1257 | const distFromZ = -this.playerCapsule.end.z;
1258 | this.playerCapsule.translate(
1259 | this.teleportVec.set(
1260 | distFromX + 0,
1261 | distToGround - 50,
1262 | distFromZ + 0
1263 | )
1264 | );
1265 | this.playerVelocity.set(0, 0, 0);
1266 | }
1267 |
1268 | // ------------------------------------------------
1269 | // In development functions
1270 |
1271 | createCloneCube() {
1272 | const geometry = new THREE.BoxGeometry();
1273 | const material = new THREE.MeshBasicMaterial({ color: 0x00ffff });
1274 | this.cube = new THREE.Mesh(geometry, material);
1275 | this.scene.add(this.cube);
1276 | }
1277 |
1278 | updateCloneCube() {
1279 | const position = this.playerCapsule.end;
1280 | this.cube.position.set(position.x + 2, position.y + 2, position.z + 2);
1281 | }
1282 |
1283 | createMannequin() {
1284 | const headGeo = new THREE.BoxGeometry(1, 1, 1);
1285 | const bodyGeo = new THREE.BoxGeometry(0.7, 1, 0.7);
1286 | const gunGeo = new THREE.BoxGeometry(1.5, 0.2, 0.2);
1287 |
1288 | const playerMat = new THREE.MeshNormalMaterial();
1289 | const gunMat = new THREE.MeshPhongMaterial();
1290 | gunMat.color = new THREE.Color(0x000000);
1291 |
1292 | const playerHead = new THREE.Mesh(headGeo, playerMat);
1293 | const playerBody = new THREE.Mesh(bodyGeo, playerMat);
1294 | const playerGun = new THREE.Mesh(gunGeo, gunMat);
1295 |
1296 | playerBody.position.set(0, -1, 0);
1297 | playerGun.position.set(0.3, -1, 0.5);
1298 |
1299 | const playerModel = new THREE.Group();
1300 | playerModel.add(playerHead);
1301 | playerModel.add(playerBody);
1302 | playerModel.add(playerGun);
1303 |
1304 | this.scene.add(playerModel);
1305 | playerModel.position.set(5, 0, 0);
1306 | }
1307 |
1308 | checkPlayerData() {
1309 | const playerVelocity = this.playerVelocity.clone();
1310 | const position = this.playerCapsule.end;
1311 | const look = this.lookVector();
1312 | console.log('Velocity is');
1313 | console.log(playerVelocity);
1314 | console.log('Position is');
1315 | console.log(position);
1316 | console.log('Look direction is');
1317 | console.log(look);
1318 | }
1319 | }
1320 |
1321 | function startAnimation() {
1322 | this.requestAnimId = requestAnimationFrame(this.startAnimation);
1323 | this.tick();
1324 | }
1325 |
1326 | function stopAnimation() {
1327 | cancelAnimationFrame(this.requestAnimId);
1328 | }
1329 |
1330 | function openForm() {
1331 | document.getElementById('inputForm').style.display = 'block';
1332 | document.getElementById('inputText').focus();
1333 | }
1334 |
1335 | function closeForm() {
1336 | document.getElementById('inputForm').style.display = 'none';
1337 | }
1338 |
1339 | export default new Game();
1340 |
--------------------------------------------------------------------------------
/server/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "server",
3 | "version": "1.0.0",
4 | "lockfileVersion": 2,
5 | "requires": true,
6 | "packages": {
7 | "": {
8 | "name": "server",
9 | "version": "1.0.0",
10 | "license": "ISC",
11 | "dependencies": {
12 | "express": "^4.17.1",
13 | "socket.io": "^4.1.1"
14 | },
15 | "engines": {
16 | "node": "15.14.0"
17 | }
18 | },
19 | "node_modules/@types/component-emitter": {
20 | "version": "1.2.10",
21 | "resolved": "https://registry.npmjs.org/@types/component-emitter/-/component-emitter-1.2.10.tgz",
22 | "integrity": "sha512-bsjleuRKWmGqajMerkzox19aGbscQX5rmmvvXl3wlIp5gMG1HgkiwPxsN5p070fBDKTNSPgojVbuY1+HWMbFhg=="
23 | },
24 | "node_modules/@types/cookie": {
25 | "version": "0.4.0",
26 | "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.0.tgz",
27 | "integrity": "sha512-y7mImlc/rNkvCRmg8gC3/lj87S7pTUIJ6QGjwHR9WQJcFs+ZMTOaoPrkdFA/YdbuqVEmEbb5RdhVxMkAcgOnpg=="
28 | },
29 | "node_modules/@types/cors": {
30 | "version": "2.8.10",
31 | "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.10.tgz",
32 | "integrity": "sha512-C7srjHiVG3Ey1nR6d511dtDkCEjxuN9W1HWAEjGq8kpcwmNM6JJkpC0xvabM7BXTG2wDq8Eu33iH9aQKa7IvLQ=="
33 | },
34 | "node_modules/@types/node": {
35 | "version": "15.12.2",
36 | "resolved": "https://registry.npmjs.org/@types/node/-/node-15.12.2.tgz",
37 | "integrity": "sha512-zjQ69G564OCIWIOHSXyQEEDpdpGl+G348RAKY0XXy9Z5kU9Vzv1GMNnkar/ZJ8dzXB3COzD9Mo9NtRZ4xfgUww=="
38 | },
39 | "node_modules/accepts": {
40 | "version": "1.3.7",
41 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz",
42 | "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==",
43 | "dependencies": {
44 | "mime-types": "~2.1.24",
45 | "negotiator": "0.6.2"
46 | },
47 | "engines": {
48 | "node": ">= 0.6"
49 | }
50 | },
51 | "node_modules/array-flatten": {
52 | "version": "1.1.1",
53 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
54 | "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI="
55 | },
56 | "node_modules/base64-arraybuffer": {
57 | "version": "0.1.4",
58 | "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.4.tgz",
59 | "integrity": "sha1-mBjHngWbE1X5fgQooBfIOOkLqBI=",
60 | "engines": {
61 | "node": ">= 0.6.0"
62 | }
63 | },
64 | "node_modules/base64id": {
65 | "version": "2.0.0",
66 | "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz",
67 | "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==",
68 | "engines": {
69 | "node": "^4.5.0 || >= 5.9"
70 | }
71 | },
72 | "node_modules/body-parser": {
73 | "version": "1.19.0",
74 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz",
75 | "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==",
76 | "dependencies": {
77 | "bytes": "3.1.0",
78 | "content-type": "~1.0.4",
79 | "debug": "2.6.9",
80 | "depd": "~1.1.2",
81 | "http-errors": "1.7.2",
82 | "iconv-lite": "0.4.24",
83 | "on-finished": "~2.3.0",
84 | "qs": "6.7.0",
85 | "raw-body": "2.4.0",
86 | "type-is": "~1.6.17"
87 | },
88 | "engines": {
89 | "node": ">= 0.8"
90 | }
91 | },
92 | "node_modules/bytes": {
93 | "version": "3.1.0",
94 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz",
95 | "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==",
96 | "engines": {
97 | "node": ">= 0.8"
98 | }
99 | },
100 | "node_modules/component-emitter": {
101 | "version": "1.3.0",
102 | "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz",
103 | "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg=="
104 | },
105 | "node_modules/content-disposition": {
106 | "version": "0.5.3",
107 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz",
108 | "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==",
109 | "dependencies": {
110 | "safe-buffer": "5.1.2"
111 | },
112 | "engines": {
113 | "node": ">= 0.6"
114 | }
115 | },
116 | "node_modules/content-type": {
117 | "version": "1.0.4",
118 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
119 | "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==",
120 | "engines": {
121 | "node": ">= 0.6"
122 | }
123 | },
124 | "node_modules/cookie": {
125 | "version": "0.4.0",
126 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz",
127 | "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==",
128 | "engines": {
129 | "node": ">= 0.6"
130 | }
131 | },
132 | "node_modules/cookie-signature": {
133 | "version": "1.0.6",
134 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
135 | "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw="
136 | },
137 | "node_modules/cors": {
138 | "version": "2.8.5",
139 | "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
140 | "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
141 | "dependencies": {
142 | "object-assign": "^4",
143 | "vary": "^1"
144 | },
145 | "engines": {
146 | "node": ">= 0.10"
147 | }
148 | },
149 | "node_modules/debug": {
150 | "version": "2.6.9",
151 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
152 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
153 | "dependencies": {
154 | "ms": "2.0.0"
155 | }
156 | },
157 | "node_modules/depd": {
158 | "version": "1.1.2",
159 | "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
160 | "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=",
161 | "engines": {
162 | "node": ">= 0.6"
163 | }
164 | },
165 | "node_modules/destroy": {
166 | "version": "1.0.4",
167 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
168 | "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA="
169 | },
170 | "node_modules/ee-first": {
171 | "version": "1.1.1",
172 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
173 | "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
174 | },
175 | "node_modules/encodeurl": {
176 | "version": "1.0.2",
177 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
178 | "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=",
179 | "engines": {
180 | "node": ">= 0.8"
181 | }
182 | },
183 | "node_modules/engine.io": {
184 | "version": "5.1.1",
185 | "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-5.1.1.tgz",
186 | "integrity": "sha512-aMWot7H5aC8L4/T8qMYbLdvKlZOdJTH54FxfdFunTGvhMx1BHkJOntWArsVfgAZVwAO9LC2sryPWRcEeUzCe5w==",
187 | "dependencies": {
188 | "accepts": "~1.3.4",
189 | "base64id": "2.0.0",
190 | "cookie": "~0.4.1",
191 | "cors": "~2.8.5",
192 | "debug": "~4.3.1",
193 | "engine.io-parser": "~4.0.0",
194 | "ws": "~7.4.2"
195 | },
196 | "engines": {
197 | "node": ">=10.0.0"
198 | }
199 | },
200 | "node_modules/engine.io-parser": {
201 | "version": "4.0.2",
202 | "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-4.0.2.tgz",
203 | "integrity": "sha512-sHfEQv6nmtJrq6TKuIz5kyEKH/qSdK56H/A+7DnAuUPWosnIZAS2NHNcPLmyjtY3cGS/MqJdZbUjW97JU72iYg==",
204 | "dependencies": {
205 | "base64-arraybuffer": "0.1.4"
206 | },
207 | "engines": {
208 | "node": ">=8.0.0"
209 | }
210 | },
211 | "node_modules/engine.io/node_modules/cookie": {
212 | "version": "0.4.1",
213 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz",
214 | "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==",
215 | "engines": {
216 | "node": ">= 0.6"
217 | }
218 | },
219 | "node_modules/engine.io/node_modules/debug": {
220 | "version": "4.3.1",
221 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
222 | "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
223 | "dependencies": {
224 | "ms": "2.1.2"
225 | },
226 | "engines": {
227 | "node": ">=6.0"
228 | },
229 | "peerDependenciesMeta": {
230 | "supports-color": {
231 | "optional": true
232 | }
233 | }
234 | },
235 | "node_modules/engine.io/node_modules/ms": {
236 | "version": "2.1.2",
237 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
238 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
239 | },
240 | "node_modules/escape-html": {
241 | "version": "1.0.3",
242 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
243 | "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg="
244 | },
245 | "node_modules/etag": {
246 | "version": "1.8.1",
247 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
248 | "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=",
249 | "engines": {
250 | "node": ">= 0.6"
251 | }
252 | },
253 | "node_modules/express": {
254 | "version": "4.17.1",
255 | "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz",
256 | "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==",
257 | "dependencies": {
258 | "accepts": "~1.3.7",
259 | "array-flatten": "1.1.1",
260 | "body-parser": "1.19.0",
261 | "content-disposition": "0.5.3",
262 | "content-type": "~1.0.4",
263 | "cookie": "0.4.0",
264 | "cookie-signature": "1.0.6",
265 | "debug": "2.6.9",
266 | "depd": "~1.1.2",
267 | "encodeurl": "~1.0.2",
268 | "escape-html": "~1.0.3",
269 | "etag": "~1.8.1",
270 | "finalhandler": "~1.1.2",
271 | "fresh": "0.5.2",
272 | "merge-descriptors": "1.0.1",
273 | "methods": "~1.1.2",
274 | "on-finished": "~2.3.0",
275 | "parseurl": "~1.3.3",
276 | "path-to-regexp": "0.1.7",
277 | "proxy-addr": "~2.0.5",
278 | "qs": "6.7.0",
279 | "range-parser": "~1.2.1",
280 | "safe-buffer": "5.1.2",
281 | "send": "0.17.1",
282 | "serve-static": "1.14.1",
283 | "setprototypeof": "1.1.1",
284 | "statuses": "~1.5.0",
285 | "type-is": "~1.6.18",
286 | "utils-merge": "1.0.1",
287 | "vary": "~1.1.2"
288 | },
289 | "engines": {
290 | "node": ">= 0.10.0"
291 | }
292 | },
293 | "node_modules/finalhandler": {
294 | "version": "1.1.2",
295 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz",
296 | "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==",
297 | "dependencies": {
298 | "debug": "2.6.9",
299 | "encodeurl": "~1.0.2",
300 | "escape-html": "~1.0.3",
301 | "on-finished": "~2.3.0",
302 | "parseurl": "~1.3.3",
303 | "statuses": "~1.5.0",
304 | "unpipe": "~1.0.0"
305 | },
306 | "engines": {
307 | "node": ">= 0.8"
308 | }
309 | },
310 | "node_modules/forwarded": {
311 | "version": "0.2.0",
312 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
313 | "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==",
314 | "engines": {
315 | "node": ">= 0.6"
316 | }
317 | },
318 | "node_modules/fresh": {
319 | "version": "0.5.2",
320 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
321 | "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=",
322 | "engines": {
323 | "node": ">= 0.6"
324 | }
325 | },
326 | "node_modules/http-errors": {
327 | "version": "1.7.2",
328 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz",
329 | "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==",
330 | "dependencies": {
331 | "depd": "~1.1.2",
332 | "inherits": "2.0.3",
333 | "setprototypeof": "1.1.1",
334 | "statuses": ">= 1.5.0 < 2",
335 | "toidentifier": "1.0.0"
336 | },
337 | "engines": {
338 | "node": ">= 0.6"
339 | }
340 | },
341 | "node_modules/iconv-lite": {
342 | "version": "0.4.24",
343 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
344 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
345 | "dependencies": {
346 | "safer-buffer": ">= 2.1.2 < 3"
347 | },
348 | "engines": {
349 | "node": ">=0.10.0"
350 | }
351 | },
352 | "node_modules/inherits": {
353 | "version": "2.0.3",
354 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
355 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
356 | },
357 | "node_modules/ipaddr.js": {
358 | "version": "1.9.1",
359 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
360 | "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
361 | "engines": {
362 | "node": ">= 0.10"
363 | }
364 | },
365 | "node_modules/media-typer": {
366 | "version": "0.3.0",
367 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
368 | "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=",
369 | "engines": {
370 | "node": ">= 0.6"
371 | }
372 | },
373 | "node_modules/merge-descriptors": {
374 | "version": "1.0.1",
375 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
376 | "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E="
377 | },
378 | "node_modules/methods": {
379 | "version": "1.1.2",
380 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
381 | "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=",
382 | "engines": {
383 | "node": ">= 0.6"
384 | }
385 | },
386 | "node_modules/mime": {
387 | "version": "1.6.0",
388 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
389 | "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
390 | "bin": {
391 | "mime": "cli.js"
392 | },
393 | "engines": {
394 | "node": ">=4"
395 | }
396 | },
397 | "node_modules/mime-db": {
398 | "version": "1.48.0",
399 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.48.0.tgz",
400 | "integrity": "sha512-FM3QwxV+TnZYQ2aRqhlKBMHxk10lTbMt3bBkMAp54ddrNeVSfcQYOOKuGuy3Ddrm38I04If834fOUSq1yzslJQ==",
401 | "engines": {
402 | "node": ">= 0.6"
403 | }
404 | },
405 | "node_modules/mime-types": {
406 | "version": "2.1.31",
407 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.31.tgz",
408 | "integrity": "sha512-XGZnNzm3QvgKxa8dpzyhFTHmpP3l5YNusmne07VUOXxou9CqUqYa/HBy124RqtVh/O2pECas/MOcsDgpilPOPg==",
409 | "dependencies": {
410 | "mime-db": "1.48.0"
411 | },
412 | "engines": {
413 | "node": ">= 0.6"
414 | }
415 | },
416 | "node_modules/ms": {
417 | "version": "2.0.0",
418 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
419 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
420 | },
421 | "node_modules/negotiator": {
422 | "version": "0.6.2",
423 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz",
424 | "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==",
425 | "engines": {
426 | "node": ">= 0.6"
427 | }
428 | },
429 | "node_modules/object-assign": {
430 | "version": "4.1.1",
431 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
432 | "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
433 | "engines": {
434 | "node": ">=0.10.0"
435 | }
436 | },
437 | "node_modules/on-finished": {
438 | "version": "2.3.0",
439 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
440 | "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
441 | "dependencies": {
442 | "ee-first": "1.1.1"
443 | },
444 | "engines": {
445 | "node": ">= 0.8"
446 | }
447 | },
448 | "node_modules/parseurl": {
449 | "version": "1.3.3",
450 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
451 | "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
452 | "engines": {
453 | "node": ">= 0.8"
454 | }
455 | },
456 | "node_modules/path-to-regexp": {
457 | "version": "0.1.7",
458 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
459 | "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w="
460 | },
461 | "node_modules/proxy-addr": {
462 | "version": "2.0.7",
463 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
464 | "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
465 | "dependencies": {
466 | "forwarded": "0.2.0",
467 | "ipaddr.js": "1.9.1"
468 | },
469 | "engines": {
470 | "node": ">= 0.10"
471 | }
472 | },
473 | "node_modules/qs": {
474 | "version": "6.7.0",
475 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
476 | "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==",
477 | "engines": {
478 | "node": ">=0.6"
479 | }
480 | },
481 | "node_modules/range-parser": {
482 | "version": "1.2.1",
483 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
484 | "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
485 | "engines": {
486 | "node": ">= 0.6"
487 | }
488 | },
489 | "node_modules/raw-body": {
490 | "version": "2.4.0",
491 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz",
492 | "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==",
493 | "dependencies": {
494 | "bytes": "3.1.0",
495 | "http-errors": "1.7.2",
496 | "iconv-lite": "0.4.24",
497 | "unpipe": "1.0.0"
498 | },
499 | "engines": {
500 | "node": ">= 0.8"
501 | }
502 | },
503 | "node_modules/safe-buffer": {
504 | "version": "5.1.2",
505 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
506 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
507 | },
508 | "node_modules/safer-buffer": {
509 | "version": "2.1.2",
510 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
511 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
512 | },
513 | "node_modules/send": {
514 | "version": "0.17.1",
515 | "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz",
516 | "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==",
517 | "dependencies": {
518 | "debug": "2.6.9",
519 | "depd": "~1.1.2",
520 | "destroy": "~1.0.4",
521 | "encodeurl": "~1.0.2",
522 | "escape-html": "~1.0.3",
523 | "etag": "~1.8.1",
524 | "fresh": "0.5.2",
525 | "http-errors": "~1.7.2",
526 | "mime": "1.6.0",
527 | "ms": "2.1.1",
528 | "on-finished": "~2.3.0",
529 | "range-parser": "~1.2.1",
530 | "statuses": "~1.5.0"
531 | },
532 | "engines": {
533 | "node": ">= 0.8.0"
534 | }
535 | },
536 | "node_modules/send/node_modules/ms": {
537 | "version": "2.1.1",
538 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
539 | "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg=="
540 | },
541 | "node_modules/serve-static": {
542 | "version": "1.14.1",
543 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz",
544 | "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==",
545 | "dependencies": {
546 | "encodeurl": "~1.0.2",
547 | "escape-html": "~1.0.3",
548 | "parseurl": "~1.3.3",
549 | "send": "0.17.1"
550 | },
551 | "engines": {
552 | "node": ">= 0.8.0"
553 | }
554 | },
555 | "node_modules/setprototypeof": {
556 | "version": "1.1.1",
557 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz",
558 | "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw=="
559 | },
560 | "node_modules/socket.io": {
561 | "version": "4.1.2",
562 | "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.1.2.tgz",
563 | "integrity": "sha512-xK0SD1C7hFrh9+bYoYCdVt+ncixkSLKtNLCax5aEy1o3r5PaO5yQhVb97exIe67cE7lAK+EpyMytXWTWmyZY8w==",
564 | "dependencies": {
565 | "@types/cookie": "^0.4.0",
566 | "@types/cors": "^2.8.8",
567 | "@types/node": ">=10.0.0",
568 | "accepts": "~1.3.4",
569 | "base64id": "~2.0.0",
570 | "debug": "~4.3.1",
571 | "engine.io": "~5.1.0",
572 | "socket.io-adapter": "~2.3.0",
573 | "socket.io-parser": "~4.0.3"
574 | },
575 | "engines": {
576 | "node": ">=10.0.0"
577 | }
578 | },
579 | "node_modules/socket.io-adapter": {
580 | "version": "2.3.1",
581 | "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.3.1.tgz",
582 | "integrity": "sha512-8cVkRxI8Nt2wadkY6u60Y4rpW3ejA1rxgcK2JuyIhmF+RMNpTy1QRtkHIDUOf3B4HlQwakMsWbKftMv/71VMmw=="
583 | },
584 | "node_modules/socket.io-parser": {
585 | "version": "4.0.4",
586 | "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.0.4.tgz",
587 | "integrity": "sha512-t+b0SS+IxG7Rxzda2EVvyBZbvFPBCjJoyHuE0P//7OAsN23GItzDRdWa6ALxZI/8R5ygK7jAR6t028/z+7295g==",
588 | "dependencies": {
589 | "@types/component-emitter": "^1.2.10",
590 | "component-emitter": "~1.3.0",
591 | "debug": "~4.3.1"
592 | },
593 | "engines": {
594 | "node": ">=10.0.0"
595 | }
596 | },
597 | "node_modules/socket.io-parser/node_modules/debug": {
598 | "version": "4.3.1",
599 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
600 | "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
601 | "dependencies": {
602 | "ms": "2.1.2"
603 | },
604 | "engines": {
605 | "node": ">=6.0"
606 | },
607 | "peerDependenciesMeta": {
608 | "supports-color": {
609 | "optional": true
610 | }
611 | }
612 | },
613 | "node_modules/socket.io-parser/node_modules/ms": {
614 | "version": "2.1.2",
615 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
616 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
617 | },
618 | "node_modules/socket.io/node_modules/debug": {
619 | "version": "4.3.1",
620 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
621 | "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
622 | "dependencies": {
623 | "ms": "2.1.2"
624 | },
625 | "engines": {
626 | "node": ">=6.0"
627 | },
628 | "peerDependenciesMeta": {
629 | "supports-color": {
630 | "optional": true
631 | }
632 | }
633 | },
634 | "node_modules/socket.io/node_modules/ms": {
635 | "version": "2.1.2",
636 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
637 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
638 | },
639 | "node_modules/statuses": {
640 | "version": "1.5.0",
641 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
642 | "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=",
643 | "engines": {
644 | "node": ">= 0.6"
645 | }
646 | },
647 | "node_modules/toidentifier": {
648 | "version": "1.0.0",
649 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz",
650 | "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==",
651 | "engines": {
652 | "node": ">=0.6"
653 | }
654 | },
655 | "node_modules/type-is": {
656 | "version": "1.6.18",
657 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
658 | "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
659 | "dependencies": {
660 | "media-typer": "0.3.0",
661 | "mime-types": "~2.1.24"
662 | },
663 | "engines": {
664 | "node": ">= 0.6"
665 | }
666 | },
667 | "node_modules/unpipe": {
668 | "version": "1.0.0",
669 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
670 | "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=",
671 | "engines": {
672 | "node": ">= 0.8"
673 | }
674 | },
675 | "node_modules/utils-merge": {
676 | "version": "1.0.1",
677 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
678 | "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=",
679 | "engines": {
680 | "node": ">= 0.4.0"
681 | }
682 | },
683 | "node_modules/vary": {
684 | "version": "1.1.2",
685 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
686 | "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=",
687 | "engines": {
688 | "node": ">= 0.8"
689 | }
690 | },
691 | "node_modules/ws": {
692 | "version": "7.4.6",
693 | "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz",
694 | "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==",
695 | "engines": {
696 | "node": ">=8.3.0"
697 | },
698 | "peerDependencies": {
699 | "bufferutil": "^4.0.1",
700 | "utf-8-validate": "^5.0.2"
701 | },
702 | "peerDependenciesMeta": {
703 | "bufferutil": {
704 | "optional": true
705 | },
706 | "utf-8-validate": {
707 | "optional": true
708 | }
709 | }
710 | }
711 | },
712 | "dependencies": {
713 | "@types/component-emitter": {
714 | "version": "1.2.10",
715 | "resolved": "https://registry.npmjs.org/@types/component-emitter/-/component-emitter-1.2.10.tgz",
716 | "integrity": "sha512-bsjleuRKWmGqajMerkzox19aGbscQX5rmmvvXl3wlIp5gMG1HgkiwPxsN5p070fBDKTNSPgojVbuY1+HWMbFhg=="
717 | },
718 | "@types/cookie": {
719 | "version": "0.4.0",
720 | "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.0.tgz",
721 | "integrity": "sha512-y7mImlc/rNkvCRmg8gC3/lj87S7pTUIJ6QGjwHR9WQJcFs+ZMTOaoPrkdFA/YdbuqVEmEbb5RdhVxMkAcgOnpg=="
722 | },
723 | "@types/cors": {
724 | "version": "2.8.10",
725 | "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.10.tgz",
726 | "integrity": "sha512-C7srjHiVG3Ey1nR6d511dtDkCEjxuN9W1HWAEjGq8kpcwmNM6JJkpC0xvabM7BXTG2wDq8Eu33iH9aQKa7IvLQ=="
727 | },
728 | "@types/node": {
729 | "version": "15.12.2",
730 | "resolved": "https://registry.npmjs.org/@types/node/-/node-15.12.2.tgz",
731 | "integrity": "sha512-zjQ69G564OCIWIOHSXyQEEDpdpGl+G348RAKY0XXy9Z5kU9Vzv1GMNnkar/ZJ8dzXB3COzD9Mo9NtRZ4xfgUww=="
732 | },
733 | "accepts": {
734 | "version": "1.3.7",
735 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz",
736 | "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==",
737 | "requires": {
738 | "mime-types": "~2.1.24",
739 | "negotiator": "0.6.2"
740 | }
741 | },
742 | "array-flatten": {
743 | "version": "1.1.1",
744 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
745 | "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI="
746 | },
747 | "base64-arraybuffer": {
748 | "version": "0.1.4",
749 | "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.4.tgz",
750 | "integrity": "sha1-mBjHngWbE1X5fgQooBfIOOkLqBI="
751 | },
752 | "base64id": {
753 | "version": "2.0.0",
754 | "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz",
755 | "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog=="
756 | },
757 | "body-parser": {
758 | "version": "1.19.0",
759 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz",
760 | "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==",
761 | "requires": {
762 | "bytes": "3.1.0",
763 | "content-type": "~1.0.4",
764 | "debug": "2.6.9",
765 | "depd": "~1.1.2",
766 | "http-errors": "1.7.2",
767 | "iconv-lite": "0.4.24",
768 | "on-finished": "~2.3.0",
769 | "qs": "6.7.0",
770 | "raw-body": "2.4.0",
771 | "type-is": "~1.6.17"
772 | }
773 | },
774 | "bytes": {
775 | "version": "3.1.0",
776 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz",
777 | "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg=="
778 | },
779 | "component-emitter": {
780 | "version": "1.3.0",
781 | "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz",
782 | "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg=="
783 | },
784 | "content-disposition": {
785 | "version": "0.5.3",
786 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz",
787 | "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==",
788 | "requires": {
789 | "safe-buffer": "5.1.2"
790 | }
791 | },
792 | "content-type": {
793 | "version": "1.0.4",
794 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
795 | "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA=="
796 | },
797 | "cookie": {
798 | "version": "0.4.0",
799 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz",
800 | "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg=="
801 | },
802 | "cookie-signature": {
803 | "version": "1.0.6",
804 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
805 | "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw="
806 | },
807 | "cors": {
808 | "version": "2.8.5",
809 | "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
810 | "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
811 | "requires": {
812 | "object-assign": "^4",
813 | "vary": "^1"
814 | }
815 | },
816 | "debug": {
817 | "version": "2.6.9",
818 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
819 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
820 | "requires": {
821 | "ms": "2.0.0"
822 | }
823 | },
824 | "depd": {
825 | "version": "1.1.2",
826 | "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
827 | "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak="
828 | },
829 | "destroy": {
830 | "version": "1.0.4",
831 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
832 | "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA="
833 | },
834 | "ee-first": {
835 | "version": "1.1.1",
836 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
837 | "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
838 | },
839 | "encodeurl": {
840 | "version": "1.0.2",
841 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
842 | "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k="
843 | },
844 | "engine.io": {
845 | "version": "5.1.1",
846 | "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-5.1.1.tgz",
847 | "integrity": "sha512-aMWot7H5aC8L4/T8qMYbLdvKlZOdJTH54FxfdFunTGvhMx1BHkJOntWArsVfgAZVwAO9LC2sryPWRcEeUzCe5w==",
848 | "requires": {
849 | "accepts": "~1.3.4",
850 | "base64id": "2.0.0",
851 | "cookie": "~0.4.1",
852 | "cors": "~2.8.5",
853 | "debug": "~4.3.1",
854 | "engine.io-parser": "~4.0.0",
855 | "ws": "~7.4.2"
856 | },
857 | "dependencies": {
858 | "cookie": {
859 | "version": "0.4.1",
860 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz",
861 | "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA=="
862 | },
863 | "debug": {
864 | "version": "4.3.1",
865 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
866 | "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
867 | "requires": {
868 | "ms": "2.1.2"
869 | }
870 | },
871 | "ms": {
872 | "version": "2.1.2",
873 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
874 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
875 | }
876 | }
877 | },
878 | "engine.io-parser": {
879 | "version": "4.0.2",
880 | "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-4.0.2.tgz",
881 | "integrity": "sha512-sHfEQv6nmtJrq6TKuIz5kyEKH/qSdK56H/A+7DnAuUPWosnIZAS2NHNcPLmyjtY3cGS/MqJdZbUjW97JU72iYg==",
882 | "requires": {
883 | "base64-arraybuffer": "0.1.4"
884 | }
885 | },
886 | "escape-html": {
887 | "version": "1.0.3",
888 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
889 | "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg="
890 | },
891 | "etag": {
892 | "version": "1.8.1",
893 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
894 | "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc="
895 | },
896 | "express": {
897 | "version": "4.17.1",
898 | "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz",
899 | "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==",
900 | "requires": {
901 | "accepts": "~1.3.7",
902 | "array-flatten": "1.1.1",
903 | "body-parser": "1.19.0",
904 | "content-disposition": "0.5.3",
905 | "content-type": "~1.0.4",
906 | "cookie": "0.4.0",
907 | "cookie-signature": "1.0.6",
908 | "debug": "2.6.9",
909 | "depd": "~1.1.2",
910 | "encodeurl": "~1.0.2",
911 | "escape-html": "~1.0.3",
912 | "etag": "~1.8.1",
913 | "finalhandler": "~1.1.2",
914 | "fresh": "0.5.2",
915 | "merge-descriptors": "1.0.1",
916 | "methods": "~1.1.2",
917 | "on-finished": "~2.3.0",
918 | "parseurl": "~1.3.3",
919 | "path-to-regexp": "0.1.7",
920 | "proxy-addr": "~2.0.5",
921 | "qs": "6.7.0",
922 | "range-parser": "~1.2.1",
923 | "safe-buffer": "5.1.2",
924 | "send": "0.17.1",
925 | "serve-static": "1.14.1",
926 | "setprototypeof": "1.1.1",
927 | "statuses": "~1.5.0",
928 | "type-is": "~1.6.18",
929 | "utils-merge": "1.0.1",
930 | "vary": "~1.1.2"
931 | }
932 | },
933 | "finalhandler": {
934 | "version": "1.1.2",
935 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz",
936 | "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==",
937 | "requires": {
938 | "debug": "2.6.9",
939 | "encodeurl": "~1.0.2",
940 | "escape-html": "~1.0.3",
941 | "on-finished": "~2.3.0",
942 | "parseurl": "~1.3.3",
943 | "statuses": "~1.5.0",
944 | "unpipe": "~1.0.0"
945 | }
946 | },
947 | "forwarded": {
948 | "version": "0.2.0",
949 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
950 | "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow=="
951 | },
952 | "fresh": {
953 | "version": "0.5.2",
954 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
955 | "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac="
956 | },
957 | "http-errors": {
958 | "version": "1.7.2",
959 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz",
960 | "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==",
961 | "requires": {
962 | "depd": "~1.1.2",
963 | "inherits": "2.0.3",
964 | "setprototypeof": "1.1.1",
965 | "statuses": ">= 1.5.0 < 2",
966 | "toidentifier": "1.0.0"
967 | }
968 | },
969 | "iconv-lite": {
970 | "version": "0.4.24",
971 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
972 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
973 | "requires": {
974 | "safer-buffer": ">= 2.1.2 < 3"
975 | }
976 | },
977 | "inherits": {
978 | "version": "2.0.3",
979 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
980 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
981 | },
982 | "ipaddr.js": {
983 | "version": "1.9.1",
984 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
985 | "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g=="
986 | },
987 | "media-typer": {
988 | "version": "0.3.0",
989 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
990 | "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g="
991 | },
992 | "merge-descriptors": {
993 | "version": "1.0.1",
994 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
995 | "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E="
996 | },
997 | "methods": {
998 | "version": "1.1.2",
999 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
1000 | "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4="
1001 | },
1002 | "mime": {
1003 | "version": "1.6.0",
1004 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
1005 | "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg=="
1006 | },
1007 | "mime-db": {
1008 | "version": "1.48.0",
1009 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.48.0.tgz",
1010 | "integrity": "sha512-FM3QwxV+TnZYQ2aRqhlKBMHxk10lTbMt3bBkMAp54ddrNeVSfcQYOOKuGuy3Ddrm38I04If834fOUSq1yzslJQ=="
1011 | },
1012 | "mime-types": {
1013 | "version": "2.1.31",
1014 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.31.tgz",
1015 | "integrity": "sha512-XGZnNzm3QvgKxa8dpzyhFTHmpP3l5YNusmne07VUOXxou9CqUqYa/HBy124RqtVh/O2pECas/MOcsDgpilPOPg==",
1016 | "requires": {
1017 | "mime-db": "1.48.0"
1018 | }
1019 | },
1020 | "ms": {
1021 | "version": "2.0.0",
1022 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
1023 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
1024 | },
1025 | "negotiator": {
1026 | "version": "0.6.2",
1027 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz",
1028 | "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw=="
1029 | },
1030 | "object-assign": {
1031 | "version": "4.1.1",
1032 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
1033 | "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
1034 | },
1035 | "on-finished": {
1036 | "version": "2.3.0",
1037 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
1038 | "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
1039 | "requires": {
1040 | "ee-first": "1.1.1"
1041 | }
1042 | },
1043 | "parseurl": {
1044 | "version": "1.3.3",
1045 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
1046 | "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ=="
1047 | },
1048 | "path-to-regexp": {
1049 | "version": "0.1.7",
1050 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
1051 | "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w="
1052 | },
1053 | "proxy-addr": {
1054 | "version": "2.0.7",
1055 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
1056 | "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
1057 | "requires": {
1058 | "forwarded": "0.2.0",
1059 | "ipaddr.js": "1.9.1"
1060 | }
1061 | },
1062 | "qs": {
1063 | "version": "6.7.0",
1064 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
1065 | "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ=="
1066 | },
1067 | "range-parser": {
1068 | "version": "1.2.1",
1069 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
1070 | "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg=="
1071 | },
1072 | "raw-body": {
1073 | "version": "2.4.0",
1074 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz",
1075 | "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==",
1076 | "requires": {
1077 | "bytes": "3.1.0",
1078 | "http-errors": "1.7.2",
1079 | "iconv-lite": "0.4.24",
1080 | "unpipe": "1.0.0"
1081 | }
1082 | },
1083 | "safe-buffer": {
1084 | "version": "5.1.2",
1085 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
1086 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
1087 | },
1088 | "safer-buffer": {
1089 | "version": "2.1.2",
1090 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
1091 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
1092 | },
1093 | "send": {
1094 | "version": "0.17.1",
1095 | "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz",
1096 | "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==",
1097 | "requires": {
1098 | "debug": "2.6.9",
1099 | "depd": "~1.1.2",
1100 | "destroy": "~1.0.4",
1101 | "encodeurl": "~1.0.2",
1102 | "escape-html": "~1.0.3",
1103 | "etag": "~1.8.1",
1104 | "fresh": "0.5.2",
1105 | "http-errors": "~1.7.2",
1106 | "mime": "1.6.0",
1107 | "ms": "2.1.1",
1108 | "on-finished": "~2.3.0",
1109 | "range-parser": "~1.2.1",
1110 | "statuses": "~1.5.0"
1111 | },
1112 | "dependencies": {
1113 | "ms": {
1114 | "version": "2.1.1",
1115 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
1116 | "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg=="
1117 | }
1118 | }
1119 | },
1120 | "serve-static": {
1121 | "version": "1.14.1",
1122 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz",
1123 | "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==",
1124 | "requires": {
1125 | "encodeurl": "~1.0.2",
1126 | "escape-html": "~1.0.3",
1127 | "parseurl": "~1.3.3",
1128 | "send": "0.17.1"
1129 | }
1130 | },
1131 | "setprototypeof": {
1132 | "version": "1.1.1",
1133 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz",
1134 | "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw=="
1135 | },
1136 | "socket.io": {
1137 | "version": "4.1.2",
1138 | "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.1.2.tgz",
1139 | "integrity": "sha512-xK0SD1C7hFrh9+bYoYCdVt+ncixkSLKtNLCax5aEy1o3r5PaO5yQhVb97exIe67cE7lAK+EpyMytXWTWmyZY8w==",
1140 | "requires": {
1141 | "@types/cookie": "^0.4.0",
1142 | "@types/cors": "^2.8.8",
1143 | "@types/node": ">=10.0.0",
1144 | "accepts": "~1.3.4",
1145 | "base64id": "~2.0.0",
1146 | "debug": "~4.3.1",
1147 | "engine.io": "~5.1.0",
1148 | "socket.io-adapter": "~2.3.0",
1149 | "socket.io-parser": "~4.0.3"
1150 | },
1151 | "dependencies": {
1152 | "debug": {
1153 | "version": "4.3.1",
1154 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
1155 | "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
1156 | "requires": {
1157 | "ms": "2.1.2"
1158 | }
1159 | },
1160 | "ms": {
1161 | "version": "2.1.2",
1162 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
1163 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
1164 | }
1165 | }
1166 | },
1167 | "socket.io-adapter": {
1168 | "version": "2.3.1",
1169 | "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.3.1.tgz",
1170 | "integrity": "sha512-8cVkRxI8Nt2wadkY6u60Y4rpW3ejA1rxgcK2JuyIhmF+RMNpTy1QRtkHIDUOf3B4HlQwakMsWbKftMv/71VMmw=="
1171 | },
1172 | "socket.io-parser": {
1173 | "version": "4.0.4",
1174 | "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.0.4.tgz",
1175 | "integrity": "sha512-t+b0SS+IxG7Rxzda2EVvyBZbvFPBCjJoyHuE0P//7OAsN23GItzDRdWa6ALxZI/8R5ygK7jAR6t028/z+7295g==",
1176 | "requires": {
1177 | "@types/component-emitter": "^1.2.10",
1178 | "component-emitter": "~1.3.0",
1179 | "debug": "~4.3.1"
1180 | },
1181 | "dependencies": {
1182 | "debug": {
1183 | "version": "4.3.1",
1184 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
1185 | "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
1186 | "requires": {
1187 | "ms": "2.1.2"
1188 | }
1189 | },
1190 | "ms": {
1191 | "version": "2.1.2",
1192 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
1193 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
1194 | }
1195 | }
1196 | },
1197 | "statuses": {
1198 | "version": "1.5.0",
1199 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
1200 | "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow="
1201 | },
1202 | "toidentifier": {
1203 | "version": "1.0.0",
1204 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz",
1205 | "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw=="
1206 | },
1207 | "type-is": {
1208 | "version": "1.6.18",
1209 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
1210 | "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
1211 | "requires": {
1212 | "media-typer": "0.3.0",
1213 | "mime-types": "~2.1.24"
1214 | }
1215 | },
1216 | "unpipe": {
1217 | "version": "1.0.0",
1218 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
1219 | "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw="
1220 | },
1221 | "utils-merge": {
1222 | "version": "1.0.1",
1223 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
1224 | "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM="
1225 | },
1226 | "vary": {
1227 | "version": "1.1.2",
1228 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
1229 | "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw="
1230 | },
1231 | "ws": {
1232 | "version": "7.4.6",
1233 | "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz",
1234 | "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==",
1235 | "requires": {}
1236 | }
1237 | }
1238 | }
1239 |
--------------------------------------------------------------------------------
/assets/draco/draco_wasm_wrapper_gltf.js:
--------------------------------------------------------------------------------
1 | var $jscomp=$jscomp||{};$jscomp.scope={};$jscomp.arrayIteratorImpl=function(l){var n=0;return function(){return nm?Math.max(C+m,0):Math.min(m,C);q=0>q?Math.max(C+q,0):Math.min(q,C);h=0>h?Math.max(C+h,0):Math.min(h,C);if(mq;)--h in this?this[--m]=this[h]:delete this[--m];return this}},"es6","es3");
19 | $jscomp.typedArrayCopyWithin=function(l){return l?l:Array.prototype.copyWithin};$jscomp.polyfill("Int8Array.prototype.copyWithin",$jscomp.typedArrayCopyWithin,"es6","es5");$jscomp.polyfill("Uint8Array.prototype.copyWithin",$jscomp.typedArrayCopyWithin,"es6","es5");$jscomp.polyfill("Uint8ClampedArray.prototype.copyWithin",$jscomp.typedArrayCopyWithin,"es6","es5");$jscomp.polyfill("Int16Array.prototype.copyWithin",$jscomp.typedArrayCopyWithin,"es6","es5");
20 | $jscomp.polyfill("Uint16Array.prototype.copyWithin",$jscomp.typedArrayCopyWithin,"es6","es5");$jscomp.polyfill("Int32Array.prototype.copyWithin",$jscomp.typedArrayCopyWithin,"es6","es5");$jscomp.polyfill("Uint32Array.prototype.copyWithin",$jscomp.typedArrayCopyWithin,"es6","es5");$jscomp.polyfill("Float32Array.prototype.copyWithin",$jscomp.typedArrayCopyWithin,"es6","es5");$jscomp.polyfill("Float64Array.prototype.copyWithin",$jscomp.typedArrayCopyWithin,"es6","es5");
21 | var DracoDecoderModule=function(){var l="undefined"!==typeof document&&document.currentScript?document.currentScript.src:void 0;"undefined"!==typeof __filename&&(l=l||__filename);return function(n){function m(e){return a.locateFile?a.locateFile(e,V):V+e}function q(e,b){e||p("Assertion failed: "+b)}function h(e,b){if(e){var c=oa;var d=e+b;for(b=e;c[b]&&!(b>=d);)++b;if(16g?d+=String.fromCharCode(g):(g-=65536,d+=String.fromCharCode(55296|g>>10,56320|g&1023))}}else d+=String.fromCharCode(g)}c=d}}else c="";return c}function C(e,b){0>2]=b};this.get_type=function(){return W[this.ptr+
25 | D.TYPE_OFFSET>>2]};this.set_destructor=function(b){W[this.ptr+D.DESTRUCTOR_OFFSET>>2]=b};this.get_destructor=function(){return W[this.ptr+D.DESTRUCTOR_OFFSET>>2]};this.set_refcount=function(b){W[this.ptr+D.REFCOUNT_OFFSET>>2]=b};this.set_caught=function(b){Z[this.ptr+D.CAUGHT_OFFSET>>0]=b?1:0};this.get_caught=function(){return 0!=Z[this.ptr+D.CAUGHT_OFFSET>>0]};this.set_rethrown=function(b){Z[this.ptr+D.RETHROWN_OFFSET>>0]=b?1:0};this.get_rethrown=function(){return 0!=Z[this.ptr+D.RETHROWN_OFFSET>>
26 | 0]};this.init=function(b,c){this.set_type(b);this.set_destructor(c);this.set_refcount(0);this.set_caught(!1);this.set_rethrown(!1)};this.add_ref=function(){W[this.ptr+D.REFCOUNT_OFFSET>>2]+=1};this.release_ref=function(){var b=W[this.ptr+D.REFCOUNT_OFFSET>>2];W[this.ptr+D.REFCOUNT_OFFSET>>2]=b-1;return 1===b}}function Q(){return 0=d&&(d=65536+((d&1023)<<10)|e.charCodeAt(++c)&1023);127>=d?++b:b=2047>=d?b+2:65535>=d?b+3:b+4}b=Array(b+1);c=0;d=b.length;if(0=v){var ia=e.charCodeAt(++g);v=65536+((v&1023)<<10)|ia&1023}if(127>=v){if(c>=d)break;b[c++]=v}else{if(2047>=v){if(c+1>=d)break;b[c++]=192|v>>6}else{if(65535>=v){if(c+2>=d)break;b[c++]=
29 | 224|v>>12}else{if(c+3>=d)break;b[c++]=240|v>>18;b[c++]=128|v>>12&63}b[c++]=128|v>>6&63}b[c++]=128|v&63}}b[c]=0}e=r.alloc(b,Z);r.copy(b,Z,e);return e}return e}function va(e){if("object"===typeof e){var b=r.alloc(e,Z);r.copy(e,Z,b);return b}return e}function aa(){throw"cannot construct a VoidPtr, no constructor in IDL";}function S(){this.ptr=Ja();z(S)[this.ptr]=this}function P(){this.ptr=Ka();z(P)[this.ptr]=this}function Y(){this.ptr=La();z(Y)[this.ptr]=this}function w(){this.ptr=Ma();z(w)[this.ptr]=
30 | this}function B(){this.ptr=Na();z(B)[this.ptr]=this}function F(){this.ptr=Oa();z(F)[this.ptr]=this}function G(){this.ptr=Pa();z(G)[this.ptr]=this}function E(){this.ptr=Qa();z(E)[this.ptr]=this}function T(){this.ptr=Ra();z(T)[this.ptr]=this}function A(){throw"cannot construct a Status, no constructor in IDL";}function H(){this.ptr=Sa();z(H)[this.ptr]=this}function I(){this.ptr=Ta();z(I)[this.ptr]=this}function J(){this.ptr=Ua();z(J)[this.ptr]=this}function K(){this.ptr=Va();z(K)[this.ptr]=this}function L(){this.ptr=
31 | Wa();z(L)[this.ptr]=this}function M(){this.ptr=Xa();z(M)[this.ptr]=this}function N(){this.ptr=Ya();z(N)[this.ptr]=this}function x(){this.ptr=Za();z(x)[this.ptr]=this}function k(){this.ptr=$a();z(k)[this.ptr]=this}n=n||{};var a="undefined"!==typeof n?n:{},Ga,ta;a.ready=new Promise(function(e,b){Ga=e;ta=b});var ab=!1,bb=!1;a.onRuntimeInitialized=function(){ab=!0;if(bb&&"function"===typeof a.onModuleLoaded)a.onModuleLoaded(a)};a.onModuleParsed=function(){bb=!0;if(ab&&"function"===typeof a.onModuleLoaded)a.onModuleLoaded(a)};
32 | a.isVersionSupported=function(e){if("string"!==typeof e)return!1;e=e.split(".");return 2>e.length||3=e[1]?!0:0!=e[0]||10>>=0;var b=oa.length;if(2147483648=c;c*=2){var d=b*(1+.2/c);
38 | d=Math.min(d,e+100663296);d=Math.min(2147483648,C(Math.max(16777216,e,d),65536));a:{try{ma.grow(d-pa.byteLength+65535>>>16);f(ma.buffer);var g=1;break a}catch(v){}g=void 0}if(g)return!0}return!1},memory:ma};(function(){function e(g,v){a.asm=g.exports;ua=a.asm.__indirect_function_table;ha--;a.monitorRunDependencies&&a.monitorRunDependencies(ha);0==ha&&(null!==Aa&&(clearInterval(Aa),Aa=null),na&&(g=na,na=null,g()))}function b(g){e(g.instance)}function c(g){return O().then(function(v){return WebAssembly.instantiate(v,
39 | d)}).then(g,function(v){ja("failed to asynchronously prepare wasm: "+v);p(v)})}var d={env:gb,wasi_snapshot_preview1:gb};ha++;a.monitorRunDependencies&&a.monitorRunDependencies(ha);if(a.instantiateWasm)try{return a.instantiateWasm(d,e)}catch(g){return ja("Module.instantiateWasm callback failed with error: "+g),!1}(function(){return ka||"function"!==typeof WebAssembly.instantiateStreaming||t(X,"data:application/octet-stream;base64,")||t(X,"file://")||"function"!==typeof fetch?c(b):fetch(X,{credentials:"same-origin"}).then(function(g){return WebAssembly.instantiateStreaming(g,
40 | d).then(b,function(v){ja("wasm streaming compile failed: "+v);ja("falling back to ArrayBuffer instantiation");return c(b)})})})().catch(ta);return{}})();var eb=a.___wasm_call_ctors=function(){return(eb=a.___wasm_call_ctors=a.asm.__wasm_call_ctors).apply(null,arguments)};a.___em_js__array_bounds_check_error=function(){return(a.___em_js__array_bounds_check_error=a.asm.__em_js__array_bounds_check_error).apply(null,arguments)};var hb=a._emscripten_bind_VoidPtr___destroy___0=function(){return(hb=a._emscripten_bind_VoidPtr___destroy___0=
41 | a.asm.emscripten_bind_VoidPtr___destroy___0).apply(null,arguments)},Ja=a._emscripten_bind_DecoderBuffer_DecoderBuffer_0=function(){return(Ja=a._emscripten_bind_DecoderBuffer_DecoderBuffer_0=a.asm.emscripten_bind_DecoderBuffer_DecoderBuffer_0).apply(null,arguments)},ib=a._emscripten_bind_DecoderBuffer_Init_2=function(){return(ib=a._emscripten_bind_DecoderBuffer_Init_2=a.asm.emscripten_bind_DecoderBuffer_Init_2).apply(null,arguments)},jb=a._emscripten_bind_DecoderBuffer___destroy___0=function(){return(jb=
42 | a._emscripten_bind_DecoderBuffer___destroy___0=a.asm.emscripten_bind_DecoderBuffer___destroy___0).apply(null,arguments)},Ka=a._emscripten_bind_AttributeTransformData_AttributeTransformData_0=function(){return(Ka=a._emscripten_bind_AttributeTransformData_AttributeTransformData_0=a.asm.emscripten_bind_AttributeTransformData_AttributeTransformData_0).apply(null,arguments)},kb=a._emscripten_bind_AttributeTransformData_transform_type_0=function(){return(kb=a._emscripten_bind_AttributeTransformData_transform_type_0=
43 | a.asm.emscripten_bind_AttributeTransformData_transform_type_0).apply(null,arguments)},lb=a._emscripten_bind_AttributeTransformData___destroy___0=function(){return(lb=a._emscripten_bind_AttributeTransformData___destroy___0=a.asm.emscripten_bind_AttributeTransformData___destroy___0).apply(null,arguments)},La=a._emscripten_bind_GeometryAttribute_GeometryAttribute_0=function(){return(La=a._emscripten_bind_GeometryAttribute_GeometryAttribute_0=a.asm.emscripten_bind_GeometryAttribute_GeometryAttribute_0).apply(null,
44 | arguments)},mb=a._emscripten_bind_GeometryAttribute___destroy___0=function(){return(mb=a._emscripten_bind_GeometryAttribute___destroy___0=a.asm.emscripten_bind_GeometryAttribute___destroy___0).apply(null,arguments)},Ma=a._emscripten_bind_PointAttribute_PointAttribute_0=function(){return(Ma=a._emscripten_bind_PointAttribute_PointAttribute_0=a.asm.emscripten_bind_PointAttribute_PointAttribute_0).apply(null,arguments)},nb=a._emscripten_bind_PointAttribute_size_0=function(){return(nb=a._emscripten_bind_PointAttribute_size_0=
45 | a.asm.emscripten_bind_PointAttribute_size_0).apply(null,arguments)},ob=a._emscripten_bind_PointAttribute_GetAttributeTransformData_0=function(){return(ob=a._emscripten_bind_PointAttribute_GetAttributeTransformData_0=a.asm.emscripten_bind_PointAttribute_GetAttributeTransformData_0).apply(null,arguments)},pb=a._emscripten_bind_PointAttribute_attribute_type_0=function(){return(pb=a._emscripten_bind_PointAttribute_attribute_type_0=a.asm.emscripten_bind_PointAttribute_attribute_type_0).apply(null,arguments)},
46 | qb=a._emscripten_bind_PointAttribute_data_type_0=function(){return(qb=a._emscripten_bind_PointAttribute_data_type_0=a.asm.emscripten_bind_PointAttribute_data_type_0).apply(null,arguments)},rb=a._emscripten_bind_PointAttribute_num_components_0=function(){return(rb=a._emscripten_bind_PointAttribute_num_components_0=a.asm.emscripten_bind_PointAttribute_num_components_0).apply(null,arguments)},sb=a._emscripten_bind_PointAttribute_normalized_0=function(){return(sb=a._emscripten_bind_PointAttribute_normalized_0=
47 | a.asm.emscripten_bind_PointAttribute_normalized_0).apply(null,arguments)},tb=a._emscripten_bind_PointAttribute_byte_stride_0=function(){return(tb=a._emscripten_bind_PointAttribute_byte_stride_0=a.asm.emscripten_bind_PointAttribute_byte_stride_0).apply(null,arguments)},ub=a._emscripten_bind_PointAttribute_byte_offset_0=function(){return(ub=a._emscripten_bind_PointAttribute_byte_offset_0=a.asm.emscripten_bind_PointAttribute_byte_offset_0).apply(null,arguments)},vb=a._emscripten_bind_PointAttribute_unique_id_0=
48 | function(){return(vb=a._emscripten_bind_PointAttribute_unique_id_0=a.asm.emscripten_bind_PointAttribute_unique_id_0).apply(null,arguments)},wb=a._emscripten_bind_PointAttribute___destroy___0=function(){return(wb=a._emscripten_bind_PointAttribute___destroy___0=a.asm.emscripten_bind_PointAttribute___destroy___0).apply(null,arguments)},Na=a._emscripten_bind_AttributeQuantizationTransform_AttributeQuantizationTransform_0=function(){return(Na=a._emscripten_bind_AttributeQuantizationTransform_AttributeQuantizationTransform_0=
49 | a.asm.emscripten_bind_AttributeQuantizationTransform_AttributeQuantizationTransform_0).apply(null,arguments)},xb=a._emscripten_bind_AttributeQuantizationTransform_InitFromAttribute_1=function(){return(xb=a._emscripten_bind_AttributeQuantizationTransform_InitFromAttribute_1=a.asm.emscripten_bind_AttributeQuantizationTransform_InitFromAttribute_1).apply(null,arguments)},yb=a._emscripten_bind_AttributeQuantizationTransform_quantization_bits_0=function(){return(yb=a._emscripten_bind_AttributeQuantizationTransform_quantization_bits_0=
50 | a.asm.emscripten_bind_AttributeQuantizationTransform_quantization_bits_0).apply(null,arguments)},zb=a._emscripten_bind_AttributeQuantizationTransform_min_value_1=function(){return(zb=a._emscripten_bind_AttributeQuantizationTransform_min_value_1=a.asm.emscripten_bind_AttributeQuantizationTransform_min_value_1).apply(null,arguments)},Ab=a._emscripten_bind_AttributeQuantizationTransform_range_0=function(){return(Ab=a._emscripten_bind_AttributeQuantizationTransform_range_0=a.asm.emscripten_bind_AttributeQuantizationTransform_range_0).apply(null,
51 | arguments)},Bb=a._emscripten_bind_AttributeQuantizationTransform___destroy___0=function(){return(Bb=a._emscripten_bind_AttributeQuantizationTransform___destroy___0=a.asm.emscripten_bind_AttributeQuantizationTransform___destroy___0).apply(null,arguments)},Oa=a._emscripten_bind_AttributeOctahedronTransform_AttributeOctahedronTransform_0=function(){return(Oa=a._emscripten_bind_AttributeOctahedronTransform_AttributeOctahedronTransform_0=a.asm.emscripten_bind_AttributeOctahedronTransform_AttributeOctahedronTransform_0).apply(null,
52 | arguments)},Cb=a._emscripten_bind_AttributeOctahedronTransform_InitFromAttribute_1=function(){return(Cb=a._emscripten_bind_AttributeOctahedronTransform_InitFromAttribute_1=a.asm.emscripten_bind_AttributeOctahedronTransform_InitFromAttribute_1).apply(null,arguments)},Db=a._emscripten_bind_AttributeOctahedronTransform_quantization_bits_0=function(){return(Db=a._emscripten_bind_AttributeOctahedronTransform_quantization_bits_0=a.asm.emscripten_bind_AttributeOctahedronTransform_quantization_bits_0).apply(null,
53 | arguments)},Eb=a._emscripten_bind_AttributeOctahedronTransform___destroy___0=function(){return(Eb=a._emscripten_bind_AttributeOctahedronTransform___destroy___0=a.asm.emscripten_bind_AttributeOctahedronTransform___destroy___0).apply(null,arguments)},Pa=a._emscripten_bind_PointCloud_PointCloud_0=function(){return(Pa=a._emscripten_bind_PointCloud_PointCloud_0=a.asm.emscripten_bind_PointCloud_PointCloud_0).apply(null,arguments)},Fb=a._emscripten_bind_PointCloud_num_attributes_0=function(){return(Fb=a._emscripten_bind_PointCloud_num_attributes_0=
54 | a.asm.emscripten_bind_PointCloud_num_attributes_0).apply(null,arguments)},Gb=a._emscripten_bind_PointCloud_num_points_0=function(){return(Gb=a._emscripten_bind_PointCloud_num_points_0=a.asm.emscripten_bind_PointCloud_num_points_0).apply(null,arguments)},Hb=a._emscripten_bind_PointCloud___destroy___0=function(){return(Hb=a._emscripten_bind_PointCloud___destroy___0=a.asm.emscripten_bind_PointCloud___destroy___0).apply(null,arguments)},Qa=a._emscripten_bind_Mesh_Mesh_0=function(){return(Qa=a._emscripten_bind_Mesh_Mesh_0=
55 | a.asm.emscripten_bind_Mesh_Mesh_0).apply(null,arguments)},Ib=a._emscripten_bind_Mesh_num_faces_0=function(){return(Ib=a._emscripten_bind_Mesh_num_faces_0=a.asm.emscripten_bind_Mesh_num_faces_0).apply(null,arguments)},Jb=a._emscripten_bind_Mesh_num_attributes_0=function(){return(Jb=a._emscripten_bind_Mesh_num_attributes_0=a.asm.emscripten_bind_Mesh_num_attributes_0).apply(null,arguments)},Kb=a._emscripten_bind_Mesh_num_points_0=function(){return(Kb=a._emscripten_bind_Mesh_num_points_0=a.asm.emscripten_bind_Mesh_num_points_0).apply(null,
56 | arguments)},Lb=a._emscripten_bind_Mesh___destroy___0=function(){return(Lb=a._emscripten_bind_Mesh___destroy___0=a.asm.emscripten_bind_Mesh___destroy___0).apply(null,arguments)},Ra=a._emscripten_bind_Metadata_Metadata_0=function(){return(Ra=a._emscripten_bind_Metadata_Metadata_0=a.asm.emscripten_bind_Metadata_Metadata_0).apply(null,arguments)},Mb=a._emscripten_bind_Metadata___destroy___0=function(){return(Mb=a._emscripten_bind_Metadata___destroy___0=a.asm.emscripten_bind_Metadata___destroy___0).apply(null,
57 | arguments)},Nb=a._emscripten_bind_Status_code_0=function(){return(Nb=a._emscripten_bind_Status_code_0=a.asm.emscripten_bind_Status_code_0).apply(null,arguments)},Ob=a._emscripten_bind_Status_ok_0=function(){return(Ob=a._emscripten_bind_Status_ok_0=a.asm.emscripten_bind_Status_ok_0).apply(null,arguments)},Pb=a._emscripten_bind_Status_error_msg_0=function(){return(Pb=a._emscripten_bind_Status_error_msg_0=a.asm.emscripten_bind_Status_error_msg_0).apply(null,arguments)},Qb=a._emscripten_bind_Status___destroy___0=
58 | function(){return(Qb=a._emscripten_bind_Status___destroy___0=a.asm.emscripten_bind_Status___destroy___0).apply(null,arguments)},Sa=a._emscripten_bind_DracoFloat32Array_DracoFloat32Array_0=function(){return(Sa=a._emscripten_bind_DracoFloat32Array_DracoFloat32Array_0=a.asm.emscripten_bind_DracoFloat32Array_DracoFloat32Array_0).apply(null,arguments)},Rb=a._emscripten_bind_DracoFloat32Array_GetValue_1=function(){return(Rb=a._emscripten_bind_DracoFloat32Array_GetValue_1=a.asm.emscripten_bind_DracoFloat32Array_GetValue_1).apply(null,
59 | arguments)},Sb=a._emscripten_bind_DracoFloat32Array_size_0=function(){return(Sb=a._emscripten_bind_DracoFloat32Array_size_0=a.asm.emscripten_bind_DracoFloat32Array_size_0).apply(null,arguments)},Tb=a._emscripten_bind_DracoFloat32Array___destroy___0=function(){return(Tb=a._emscripten_bind_DracoFloat32Array___destroy___0=a.asm.emscripten_bind_DracoFloat32Array___destroy___0).apply(null,arguments)},Ta=a._emscripten_bind_DracoInt8Array_DracoInt8Array_0=function(){return(Ta=a._emscripten_bind_DracoInt8Array_DracoInt8Array_0=
60 | a.asm.emscripten_bind_DracoInt8Array_DracoInt8Array_0).apply(null,arguments)},Ub=a._emscripten_bind_DracoInt8Array_GetValue_1=function(){return(Ub=a._emscripten_bind_DracoInt8Array_GetValue_1=a.asm.emscripten_bind_DracoInt8Array_GetValue_1).apply(null,arguments)},Vb=a._emscripten_bind_DracoInt8Array_size_0=function(){return(Vb=a._emscripten_bind_DracoInt8Array_size_0=a.asm.emscripten_bind_DracoInt8Array_size_0).apply(null,arguments)},Wb=a._emscripten_bind_DracoInt8Array___destroy___0=function(){return(Wb=
61 | a._emscripten_bind_DracoInt8Array___destroy___0=a.asm.emscripten_bind_DracoInt8Array___destroy___0).apply(null,arguments)},Ua=a._emscripten_bind_DracoUInt8Array_DracoUInt8Array_0=function(){return(Ua=a._emscripten_bind_DracoUInt8Array_DracoUInt8Array_0=a.asm.emscripten_bind_DracoUInt8Array_DracoUInt8Array_0).apply(null,arguments)},Xb=a._emscripten_bind_DracoUInt8Array_GetValue_1=function(){return(Xb=a._emscripten_bind_DracoUInt8Array_GetValue_1=a.asm.emscripten_bind_DracoUInt8Array_GetValue_1).apply(null,
62 | arguments)},Yb=a._emscripten_bind_DracoUInt8Array_size_0=function(){return(Yb=a._emscripten_bind_DracoUInt8Array_size_0=a.asm.emscripten_bind_DracoUInt8Array_size_0).apply(null,arguments)},Zb=a._emscripten_bind_DracoUInt8Array___destroy___0=function(){return(Zb=a._emscripten_bind_DracoUInt8Array___destroy___0=a.asm.emscripten_bind_DracoUInt8Array___destroy___0).apply(null,arguments)},Va=a._emscripten_bind_DracoInt16Array_DracoInt16Array_0=function(){return(Va=a._emscripten_bind_DracoInt16Array_DracoInt16Array_0=
63 | a.asm.emscripten_bind_DracoInt16Array_DracoInt16Array_0).apply(null,arguments)},$b=a._emscripten_bind_DracoInt16Array_GetValue_1=function(){return($b=a._emscripten_bind_DracoInt16Array_GetValue_1=a.asm.emscripten_bind_DracoInt16Array_GetValue_1).apply(null,arguments)},ac=a._emscripten_bind_DracoInt16Array_size_0=function(){return(ac=a._emscripten_bind_DracoInt16Array_size_0=a.asm.emscripten_bind_DracoInt16Array_size_0).apply(null,arguments)},bc=a._emscripten_bind_DracoInt16Array___destroy___0=function(){return(bc=
64 | a._emscripten_bind_DracoInt16Array___destroy___0=a.asm.emscripten_bind_DracoInt16Array___destroy___0).apply(null,arguments)},Wa=a._emscripten_bind_DracoUInt16Array_DracoUInt16Array_0=function(){return(Wa=a._emscripten_bind_DracoUInt16Array_DracoUInt16Array_0=a.asm.emscripten_bind_DracoUInt16Array_DracoUInt16Array_0).apply(null,arguments)},cc=a._emscripten_bind_DracoUInt16Array_GetValue_1=function(){return(cc=a._emscripten_bind_DracoUInt16Array_GetValue_1=a.asm.emscripten_bind_DracoUInt16Array_GetValue_1).apply(null,
65 | arguments)},dc=a._emscripten_bind_DracoUInt16Array_size_0=function(){return(dc=a._emscripten_bind_DracoUInt16Array_size_0=a.asm.emscripten_bind_DracoUInt16Array_size_0).apply(null,arguments)},ec=a._emscripten_bind_DracoUInt16Array___destroy___0=function(){return(ec=a._emscripten_bind_DracoUInt16Array___destroy___0=a.asm.emscripten_bind_DracoUInt16Array___destroy___0).apply(null,arguments)},Xa=a._emscripten_bind_DracoInt32Array_DracoInt32Array_0=function(){return(Xa=a._emscripten_bind_DracoInt32Array_DracoInt32Array_0=
66 | a.asm.emscripten_bind_DracoInt32Array_DracoInt32Array_0).apply(null,arguments)},fc=a._emscripten_bind_DracoInt32Array_GetValue_1=function(){return(fc=a._emscripten_bind_DracoInt32Array_GetValue_1=a.asm.emscripten_bind_DracoInt32Array_GetValue_1).apply(null,arguments)},gc=a._emscripten_bind_DracoInt32Array_size_0=function(){return(gc=a._emscripten_bind_DracoInt32Array_size_0=a.asm.emscripten_bind_DracoInt32Array_size_0).apply(null,arguments)},hc=a._emscripten_bind_DracoInt32Array___destroy___0=function(){return(hc=
67 | a._emscripten_bind_DracoInt32Array___destroy___0=a.asm.emscripten_bind_DracoInt32Array___destroy___0).apply(null,arguments)},Ya=a._emscripten_bind_DracoUInt32Array_DracoUInt32Array_0=function(){return(Ya=a._emscripten_bind_DracoUInt32Array_DracoUInt32Array_0=a.asm.emscripten_bind_DracoUInt32Array_DracoUInt32Array_0).apply(null,arguments)},ic=a._emscripten_bind_DracoUInt32Array_GetValue_1=function(){return(ic=a._emscripten_bind_DracoUInt32Array_GetValue_1=a.asm.emscripten_bind_DracoUInt32Array_GetValue_1).apply(null,
68 | arguments)},jc=a._emscripten_bind_DracoUInt32Array_size_0=function(){return(jc=a._emscripten_bind_DracoUInt32Array_size_0=a.asm.emscripten_bind_DracoUInt32Array_size_0).apply(null,arguments)},kc=a._emscripten_bind_DracoUInt32Array___destroy___0=function(){return(kc=a._emscripten_bind_DracoUInt32Array___destroy___0=a.asm.emscripten_bind_DracoUInt32Array___destroy___0).apply(null,arguments)},Za=a._emscripten_bind_MetadataQuerier_MetadataQuerier_0=function(){return(Za=a._emscripten_bind_MetadataQuerier_MetadataQuerier_0=
69 | a.asm.emscripten_bind_MetadataQuerier_MetadataQuerier_0).apply(null,arguments)},lc=a._emscripten_bind_MetadataQuerier_HasEntry_2=function(){return(lc=a._emscripten_bind_MetadataQuerier_HasEntry_2=a.asm.emscripten_bind_MetadataQuerier_HasEntry_2).apply(null,arguments)},mc=a._emscripten_bind_MetadataQuerier_GetIntEntry_2=function(){return(mc=a._emscripten_bind_MetadataQuerier_GetIntEntry_2=a.asm.emscripten_bind_MetadataQuerier_GetIntEntry_2).apply(null,arguments)},nc=a._emscripten_bind_MetadataQuerier_GetIntEntryArray_3=
70 | function(){return(nc=a._emscripten_bind_MetadataQuerier_GetIntEntryArray_3=a.asm.emscripten_bind_MetadataQuerier_GetIntEntryArray_3).apply(null,arguments)},oc=a._emscripten_bind_MetadataQuerier_GetDoubleEntry_2=function(){return(oc=a._emscripten_bind_MetadataQuerier_GetDoubleEntry_2=a.asm.emscripten_bind_MetadataQuerier_GetDoubleEntry_2).apply(null,arguments)},pc=a._emscripten_bind_MetadataQuerier_GetStringEntry_2=function(){return(pc=a._emscripten_bind_MetadataQuerier_GetStringEntry_2=a.asm.emscripten_bind_MetadataQuerier_GetStringEntry_2).apply(null,
71 | arguments)},qc=a._emscripten_bind_MetadataQuerier_NumEntries_1=function(){return(qc=a._emscripten_bind_MetadataQuerier_NumEntries_1=a.asm.emscripten_bind_MetadataQuerier_NumEntries_1).apply(null,arguments)},rc=a._emscripten_bind_MetadataQuerier_GetEntryName_2=function(){return(rc=a._emscripten_bind_MetadataQuerier_GetEntryName_2=a.asm.emscripten_bind_MetadataQuerier_GetEntryName_2).apply(null,arguments)},sc=a._emscripten_bind_MetadataQuerier___destroy___0=function(){return(sc=a._emscripten_bind_MetadataQuerier___destroy___0=
72 | a.asm.emscripten_bind_MetadataQuerier___destroy___0).apply(null,arguments)},$a=a._emscripten_bind_Decoder_Decoder_0=function(){return($a=a._emscripten_bind_Decoder_Decoder_0=a.asm.emscripten_bind_Decoder_Decoder_0).apply(null,arguments)},tc=a._emscripten_bind_Decoder_DecodeArrayToPointCloud_3=function(){return(tc=a._emscripten_bind_Decoder_DecodeArrayToPointCloud_3=a.asm.emscripten_bind_Decoder_DecodeArrayToPointCloud_3).apply(null,arguments)},uc=a._emscripten_bind_Decoder_DecodeArrayToMesh_3=function(){return(uc=
73 | a._emscripten_bind_Decoder_DecodeArrayToMesh_3=a.asm.emscripten_bind_Decoder_DecodeArrayToMesh_3).apply(null,arguments)},vc=a._emscripten_bind_Decoder_GetAttributeId_2=function(){return(vc=a._emscripten_bind_Decoder_GetAttributeId_2=a.asm.emscripten_bind_Decoder_GetAttributeId_2).apply(null,arguments)},wc=a._emscripten_bind_Decoder_GetAttributeIdByName_2=function(){return(wc=a._emscripten_bind_Decoder_GetAttributeIdByName_2=a.asm.emscripten_bind_Decoder_GetAttributeIdByName_2).apply(null,arguments)},
74 | xc=a._emscripten_bind_Decoder_GetAttributeIdByMetadataEntry_3=function(){return(xc=a._emscripten_bind_Decoder_GetAttributeIdByMetadataEntry_3=a.asm.emscripten_bind_Decoder_GetAttributeIdByMetadataEntry_3).apply(null,arguments)},yc=a._emscripten_bind_Decoder_GetAttribute_2=function(){return(yc=a._emscripten_bind_Decoder_GetAttribute_2=a.asm.emscripten_bind_Decoder_GetAttribute_2).apply(null,arguments)},zc=a._emscripten_bind_Decoder_GetAttributeByUniqueId_2=function(){return(zc=a._emscripten_bind_Decoder_GetAttributeByUniqueId_2=
75 | a.asm.emscripten_bind_Decoder_GetAttributeByUniqueId_2).apply(null,arguments)},Ac=a._emscripten_bind_Decoder_GetMetadata_1=function(){return(Ac=a._emscripten_bind_Decoder_GetMetadata_1=a.asm.emscripten_bind_Decoder_GetMetadata_1).apply(null,arguments)},Bc=a._emscripten_bind_Decoder_GetAttributeMetadata_2=function(){return(Bc=a._emscripten_bind_Decoder_GetAttributeMetadata_2=a.asm.emscripten_bind_Decoder_GetAttributeMetadata_2).apply(null,arguments)},Cc=a._emscripten_bind_Decoder_GetFaceFromMesh_3=
76 | function(){return(Cc=a._emscripten_bind_Decoder_GetFaceFromMesh_3=a.asm.emscripten_bind_Decoder_GetFaceFromMesh_3).apply(null,arguments)},Dc=a._emscripten_bind_Decoder_GetTriangleStripsFromMesh_2=function(){return(Dc=a._emscripten_bind_Decoder_GetTriangleStripsFromMesh_2=a.asm.emscripten_bind_Decoder_GetTriangleStripsFromMesh_2).apply(null,arguments)},Ec=a._emscripten_bind_Decoder_GetTrianglesUInt16Array_3=function(){return(Ec=a._emscripten_bind_Decoder_GetTrianglesUInt16Array_3=a.asm.emscripten_bind_Decoder_GetTrianglesUInt16Array_3).apply(null,
77 | arguments)},Fc=a._emscripten_bind_Decoder_GetTrianglesUInt32Array_3=function(){return(Fc=a._emscripten_bind_Decoder_GetTrianglesUInt32Array_3=a.asm.emscripten_bind_Decoder_GetTrianglesUInt32Array_3).apply(null,arguments)},Gc=a._emscripten_bind_Decoder_GetAttributeFloat_3=function(){return(Gc=a._emscripten_bind_Decoder_GetAttributeFloat_3=a.asm.emscripten_bind_Decoder_GetAttributeFloat_3).apply(null,arguments)},Hc=a._emscripten_bind_Decoder_GetAttributeFloatForAllPoints_3=function(){return(Hc=a._emscripten_bind_Decoder_GetAttributeFloatForAllPoints_3=
78 | a.asm.emscripten_bind_Decoder_GetAttributeFloatForAllPoints_3).apply(null,arguments)},Ic=a._emscripten_bind_Decoder_GetAttributeIntForAllPoints_3=function(){return(Ic=a._emscripten_bind_Decoder_GetAttributeIntForAllPoints_3=a.asm.emscripten_bind_Decoder_GetAttributeIntForAllPoints_3).apply(null,arguments)},Jc=a._emscripten_bind_Decoder_GetAttributeInt8ForAllPoints_3=function(){return(Jc=a._emscripten_bind_Decoder_GetAttributeInt8ForAllPoints_3=a.asm.emscripten_bind_Decoder_GetAttributeInt8ForAllPoints_3).apply(null,
79 | arguments)},Kc=a._emscripten_bind_Decoder_GetAttributeUInt8ForAllPoints_3=function(){return(Kc=a._emscripten_bind_Decoder_GetAttributeUInt8ForAllPoints_3=a.asm.emscripten_bind_Decoder_GetAttributeUInt8ForAllPoints_3).apply(null,arguments)},Lc=a._emscripten_bind_Decoder_GetAttributeInt16ForAllPoints_3=function(){return(Lc=a._emscripten_bind_Decoder_GetAttributeInt16ForAllPoints_3=a.asm.emscripten_bind_Decoder_GetAttributeInt16ForAllPoints_3).apply(null,arguments)},Mc=a._emscripten_bind_Decoder_GetAttributeUInt16ForAllPoints_3=
80 | function(){return(Mc=a._emscripten_bind_Decoder_GetAttributeUInt16ForAllPoints_3=a.asm.emscripten_bind_Decoder_GetAttributeUInt16ForAllPoints_3).apply(null,arguments)},Nc=a._emscripten_bind_Decoder_GetAttributeInt32ForAllPoints_3=function(){return(Nc=a._emscripten_bind_Decoder_GetAttributeInt32ForAllPoints_3=a.asm.emscripten_bind_Decoder_GetAttributeInt32ForAllPoints_3).apply(null,arguments)},Oc=a._emscripten_bind_Decoder_GetAttributeUInt32ForAllPoints_3=function(){return(Oc=a._emscripten_bind_Decoder_GetAttributeUInt32ForAllPoints_3=
81 | a.asm.emscripten_bind_Decoder_GetAttributeUInt32ForAllPoints_3).apply(null,arguments)},Pc=a._emscripten_bind_Decoder_GetAttributeDataArrayForAllPoints_5=function(){return(Pc=a._emscripten_bind_Decoder_GetAttributeDataArrayForAllPoints_5=a.asm.emscripten_bind_Decoder_GetAttributeDataArrayForAllPoints_5).apply(null,arguments)},Qc=a._emscripten_bind_Decoder_SkipAttributeTransform_1=function(){return(Qc=a._emscripten_bind_Decoder_SkipAttributeTransform_1=a.asm.emscripten_bind_Decoder_SkipAttributeTransform_1).apply(null,
82 | arguments)},Rc=a._emscripten_bind_Decoder_GetEncodedGeometryType_Deprecated_1=function(){return(Rc=a._emscripten_bind_Decoder_GetEncodedGeometryType_Deprecated_1=a.asm.emscripten_bind_Decoder_GetEncodedGeometryType_Deprecated_1).apply(null,arguments)},Sc=a._emscripten_bind_Decoder_DecodeBufferToPointCloud_2=function(){return(Sc=a._emscripten_bind_Decoder_DecodeBufferToPointCloud_2=a.asm.emscripten_bind_Decoder_DecodeBufferToPointCloud_2).apply(null,arguments)},Tc=a._emscripten_bind_Decoder_DecodeBufferToMesh_2=
83 | function(){return(Tc=a._emscripten_bind_Decoder_DecodeBufferToMesh_2=a.asm.emscripten_bind_Decoder_DecodeBufferToMesh_2).apply(null,arguments)},Uc=a._emscripten_bind_Decoder___destroy___0=function(){return(Uc=a._emscripten_bind_Decoder___destroy___0=a.asm.emscripten_bind_Decoder___destroy___0).apply(null,arguments)},Vc=a._emscripten_enum_draco_AttributeTransformType_ATTRIBUTE_INVALID_TRANSFORM=function(){return(Vc=a._emscripten_enum_draco_AttributeTransformType_ATTRIBUTE_INVALID_TRANSFORM=a.asm.emscripten_enum_draco_AttributeTransformType_ATTRIBUTE_INVALID_TRANSFORM).apply(null,
84 | arguments)},Wc=a._emscripten_enum_draco_AttributeTransformType_ATTRIBUTE_NO_TRANSFORM=function(){return(Wc=a._emscripten_enum_draco_AttributeTransformType_ATTRIBUTE_NO_TRANSFORM=a.asm.emscripten_enum_draco_AttributeTransformType_ATTRIBUTE_NO_TRANSFORM).apply(null,arguments)},Xc=a._emscripten_enum_draco_AttributeTransformType_ATTRIBUTE_QUANTIZATION_TRANSFORM=function(){return(Xc=a._emscripten_enum_draco_AttributeTransformType_ATTRIBUTE_QUANTIZATION_TRANSFORM=a.asm.emscripten_enum_draco_AttributeTransformType_ATTRIBUTE_QUANTIZATION_TRANSFORM).apply(null,
85 | arguments)},Yc=a._emscripten_enum_draco_AttributeTransformType_ATTRIBUTE_OCTAHEDRON_TRANSFORM=function(){return(Yc=a._emscripten_enum_draco_AttributeTransformType_ATTRIBUTE_OCTAHEDRON_TRANSFORM=a.asm.emscripten_enum_draco_AttributeTransformType_ATTRIBUTE_OCTAHEDRON_TRANSFORM).apply(null,arguments)},Zc=a._emscripten_enum_draco_GeometryAttribute_Type_INVALID=function(){return(Zc=a._emscripten_enum_draco_GeometryAttribute_Type_INVALID=a.asm.emscripten_enum_draco_GeometryAttribute_Type_INVALID).apply(null,
86 | arguments)},$c=a._emscripten_enum_draco_GeometryAttribute_Type_POSITION=function(){return($c=a._emscripten_enum_draco_GeometryAttribute_Type_POSITION=a.asm.emscripten_enum_draco_GeometryAttribute_Type_POSITION).apply(null,arguments)},ad=a._emscripten_enum_draco_GeometryAttribute_Type_NORMAL=function(){return(ad=a._emscripten_enum_draco_GeometryAttribute_Type_NORMAL=a.asm.emscripten_enum_draco_GeometryAttribute_Type_NORMAL).apply(null,arguments)},bd=a._emscripten_enum_draco_GeometryAttribute_Type_COLOR=
87 | function(){return(bd=a._emscripten_enum_draco_GeometryAttribute_Type_COLOR=a.asm.emscripten_enum_draco_GeometryAttribute_Type_COLOR).apply(null,arguments)},cd=a._emscripten_enum_draco_GeometryAttribute_Type_TEX_COORD=function(){return(cd=a._emscripten_enum_draco_GeometryAttribute_Type_TEX_COORD=a.asm.emscripten_enum_draco_GeometryAttribute_Type_TEX_COORD).apply(null,arguments)},dd=a._emscripten_enum_draco_GeometryAttribute_Type_GENERIC=function(){return(dd=a._emscripten_enum_draco_GeometryAttribute_Type_GENERIC=
88 | a.asm.emscripten_enum_draco_GeometryAttribute_Type_GENERIC).apply(null,arguments)},ed=a._emscripten_enum_draco_EncodedGeometryType_INVALID_GEOMETRY_TYPE=function(){return(ed=a._emscripten_enum_draco_EncodedGeometryType_INVALID_GEOMETRY_TYPE=a.asm.emscripten_enum_draco_EncodedGeometryType_INVALID_GEOMETRY_TYPE).apply(null,arguments)},fd=a._emscripten_enum_draco_EncodedGeometryType_POINT_CLOUD=function(){return(fd=a._emscripten_enum_draco_EncodedGeometryType_POINT_CLOUD=a.asm.emscripten_enum_draco_EncodedGeometryType_POINT_CLOUD).apply(null,
89 | arguments)},gd=a._emscripten_enum_draco_EncodedGeometryType_TRIANGULAR_MESH=function(){return(gd=a._emscripten_enum_draco_EncodedGeometryType_TRIANGULAR_MESH=a.asm.emscripten_enum_draco_EncodedGeometryType_TRIANGULAR_MESH).apply(null,arguments)},hd=a._emscripten_enum_draco_DataType_DT_INVALID=function(){return(hd=a._emscripten_enum_draco_DataType_DT_INVALID=a.asm.emscripten_enum_draco_DataType_DT_INVALID).apply(null,arguments)},id=a._emscripten_enum_draco_DataType_DT_INT8=function(){return(id=a._emscripten_enum_draco_DataType_DT_INT8=
90 | a.asm.emscripten_enum_draco_DataType_DT_INT8).apply(null,arguments)},jd=a._emscripten_enum_draco_DataType_DT_UINT8=function(){return(jd=a._emscripten_enum_draco_DataType_DT_UINT8=a.asm.emscripten_enum_draco_DataType_DT_UINT8).apply(null,arguments)},kd=a._emscripten_enum_draco_DataType_DT_INT16=function(){return(kd=a._emscripten_enum_draco_DataType_DT_INT16=a.asm.emscripten_enum_draco_DataType_DT_INT16).apply(null,arguments)},ld=a._emscripten_enum_draco_DataType_DT_UINT16=function(){return(ld=a._emscripten_enum_draco_DataType_DT_UINT16=
91 | a.asm.emscripten_enum_draco_DataType_DT_UINT16).apply(null,arguments)},md=a._emscripten_enum_draco_DataType_DT_INT32=function(){return(md=a._emscripten_enum_draco_DataType_DT_INT32=a.asm.emscripten_enum_draco_DataType_DT_INT32).apply(null,arguments)},nd=a._emscripten_enum_draco_DataType_DT_UINT32=function(){return(nd=a._emscripten_enum_draco_DataType_DT_UINT32=a.asm.emscripten_enum_draco_DataType_DT_UINT32).apply(null,arguments)},od=a._emscripten_enum_draco_DataType_DT_INT64=function(){return(od=
92 | a._emscripten_enum_draco_DataType_DT_INT64=a.asm.emscripten_enum_draco_DataType_DT_INT64).apply(null,arguments)},pd=a._emscripten_enum_draco_DataType_DT_UINT64=function(){return(pd=a._emscripten_enum_draco_DataType_DT_UINT64=a.asm.emscripten_enum_draco_DataType_DT_UINT64).apply(null,arguments)},qd=a._emscripten_enum_draco_DataType_DT_FLOAT32=function(){return(qd=a._emscripten_enum_draco_DataType_DT_FLOAT32=a.asm.emscripten_enum_draco_DataType_DT_FLOAT32).apply(null,arguments)},rd=a._emscripten_enum_draco_DataType_DT_FLOAT64=
93 | function(){return(rd=a._emscripten_enum_draco_DataType_DT_FLOAT64=a.asm.emscripten_enum_draco_DataType_DT_FLOAT64).apply(null,arguments)},sd=a._emscripten_enum_draco_DataType_DT_BOOL=function(){return(sd=a._emscripten_enum_draco_DataType_DT_BOOL=a.asm.emscripten_enum_draco_DataType_DT_BOOL).apply(null,arguments)},td=a._emscripten_enum_draco_DataType_DT_TYPES_COUNT=function(){return(td=a._emscripten_enum_draco_DataType_DT_TYPES_COUNT=a.asm.emscripten_enum_draco_DataType_DT_TYPES_COUNT).apply(null,
94 | arguments)},ud=a._emscripten_enum_draco_StatusCode_OK=function(){return(ud=a._emscripten_enum_draco_StatusCode_OK=a.asm.emscripten_enum_draco_StatusCode_OK).apply(null,arguments)},vd=a._emscripten_enum_draco_StatusCode_DRACO_ERROR=function(){return(vd=a._emscripten_enum_draco_StatusCode_DRACO_ERROR=a.asm.emscripten_enum_draco_StatusCode_DRACO_ERROR).apply(null,arguments)},wd=a._emscripten_enum_draco_StatusCode_IO_ERROR=function(){return(wd=a._emscripten_enum_draco_StatusCode_IO_ERROR=a.asm.emscripten_enum_draco_StatusCode_IO_ERROR).apply(null,
95 | arguments)},xd=a._emscripten_enum_draco_StatusCode_INVALID_PARAMETER=function(){return(xd=a._emscripten_enum_draco_StatusCode_INVALID_PARAMETER=a.asm.emscripten_enum_draco_StatusCode_INVALID_PARAMETER).apply(null,arguments)},yd=a._emscripten_enum_draco_StatusCode_UNSUPPORTED_VERSION=function(){return(yd=a._emscripten_enum_draco_StatusCode_UNSUPPORTED_VERSION=a.asm.emscripten_enum_draco_StatusCode_UNSUPPORTED_VERSION).apply(null,arguments)},zd=a._emscripten_enum_draco_StatusCode_UNKNOWN_VERSION=function(){return(zd=
96 | a._emscripten_enum_draco_StatusCode_UNKNOWN_VERSION=a.asm.emscripten_enum_draco_StatusCode_UNKNOWN_VERSION).apply(null,arguments)};a.___errno_location=function(){return(a.___errno_location=a.asm.__errno_location).apply(null,arguments)};a.stackSave=function(){return(a.stackSave=a.asm.stackSave).apply(null,arguments)};a.stackRestore=function(){return(a.stackRestore=a.asm.stackRestore).apply(null,arguments)};a.stackAlloc=function(){return(a.stackAlloc=a.asm.stackAlloc).apply(null,arguments)};a._setThrew=
97 | function(){return(a._setThrew=a.asm.setThrew).apply(null,arguments)};a._free=function(){return(a._free=a.asm.free).apply(null,arguments)};var fb=a._malloc=function(){return(fb=a._malloc=a.asm.malloc).apply(null,arguments)},sa;na=function b(){sa||ea();sa||(na=b)};a.run=ea;if(a.preInit)for("function"==typeof a.preInit&&(a.preInit=[a.preInit]);0=r.size?(q(0>>=0;switch(c.BYTES_PER_ELEMENT){case 2:d>>>=1;break;case 4:d>>>=2;break;case 8:d>>>=3}for(var g=0;gb.byteLength)return a.INVALID_GEOMETRY_TYPE;switch(b[7]){case 0:return a.POINT_CLOUD;case 1:return a.TRIANGULAR_MESH;default:return a.INVALID_GEOMETRY_TYPE}};return n.ready}}();"object"===typeof exports&&"object"===typeof module?module.exports=DracoDecoderModule:"function"===typeof define&&define.amd?define([],function(){return DracoDecoderModule}):"object"===typeof exports&&(exports.DracoDecoderModule=DracoDecoderModule);
131 |
--------------------------------------------------------------------------------