├── backend
├── .gitignore
├── package.json
├── src
│ ├── index.ts
│ └── outcomes.ts
├── tsconfig.json
└── package-lock.json
├── frontend
├── src
│ ├── components
│ │ ├── ui
│ │ │ ├── index.ts
│ │ │ └── Button.tsx
│ │ ├── index.ts
│ │ ├── Quotes.tsx
│ │ ├── Game.tsx
│ │ ├── FoundIssue.tsx
│ │ ├── Footer.tsx
│ │ ├── Simulate.tsx
│ │ ├── Simulation.tsx
│ │ └── Navbar.tsx
│ ├── vite-env.d.ts
│ ├── utils
│ │ └── index.ts
│ ├── game
│ │ ├── padding.ts
│ │ ├── constants.ts
│ │ ├── objects.ts
│ │ ├── classes
│ │ │ ├── Ball.ts
│ │ │ └── BallManager.ts
│ │ └── outcomes.ts
│ ├── main.tsx
│ ├── App.tsx
│ ├── App.css
│ ├── pages
│ │ ├── Game.tsx
│ │ ├── Simulation.tsx
│ │ └── Home.tsx
│ ├── index.css
│ └── assets
│ │ └── react.svg
├── postcss.config.js
├── vite.config.ts
├── tailwind.config.js
├── tsconfig.node.json
├── .gitignore
├── index.html
├── .eslintrc.cjs
├── tsconfig.json
├── package.json
├── README.md
└── public
│ └── vite.svg
├── version-1
└── index.html
└── tsconfig.json
/backend/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | dist
3 |
--------------------------------------------------------------------------------
/frontend/src/components/ui/index.ts:
--------------------------------------------------------------------------------
1 | export * from "./Button";
2 |
--------------------------------------------------------------------------------
/frontend/src/vite-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
--------------------------------------------------------------------------------
/frontend/src/utils/index.ts:
--------------------------------------------------------------------------------
1 | export const baseURL = "http://localhost:3000";
2 |
--------------------------------------------------------------------------------
/frontend/postcss.config.js:
--------------------------------------------------------------------------------
1 | export default {
2 | plugins: {
3 | tailwindcss: {},
4 | autoprefixer: {},
5 | },
6 | }
7 |
--------------------------------------------------------------------------------
/frontend/src/components/index.ts:
--------------------------------------------------------------------------------
1 | export * from "./Navbar";
2 | export * from "./Quotes";
3 | export * from "./Simulate";
4 | export * from "./Footer";
5 | export * from "./FoundIssue";
6 |
--------------------------------------------------------------------------------
/frontend/vite.config.ts:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'vite'
2 | import react from '@vitejs/plugin-react'
3 |
4 | // https://vitejs.dev/config/
5 | export default defineConfig({
6 | plugins: [react()],
7 | })
8 |
--------------------------------------------------------------------------------
/frontend/tailwind.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('tailwindcss').Config} */
2 | export default {
3 | content: ["./index.html", "./src/**/*.{js,ts,jsx,tsx}"],
4 | theme: {
5 | extend: {},
6 | },
7 | plugins: [],
8 | };
9 |
--------------------------------------------------------------------------------
/frontend/src/game/padding.ts:
--------------------------------------------------------------------------------
1 | export const DECIMAL_MULTIPLIER = 10000;
2 |
3 | export function pad(n: number) {
4 | return n * DECIMAL_MULTIPLIER;
5 | }
6 |
7 | export function unpad(n: number) {
8 | return Math.floor(n / DECIMAL_MULTIPLIER);
9 | }
10 |
--------------------------------------------------------------------------------
/frontend/src/main.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import ReactDOM from 'react-dom/client'
3 | import App from './App.tsx'
4 | import './index.css'
5 |
6 | ReactDOM.createRoot(document.getElementById('root')!).render(
7 |
8 |
9 | ,
10 | )
11 |
--------------------------------------------------------------------------------
/frontend/tsconfig.node.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "composite": true,
4 | "skipLibCheck": true,
5 | "module": "ESNext",
6 | "moduleResolution": "bundler",
7 | "allowSyntheticDefaultImports": true,
8 | "strict": true
9 | },
10 | "include": ["vite.config.ts"]
11 | }
12 |
--------------------------------------------------------------------------------
/frontend/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | pnpm-debug.log*
8 | lerna-debug.log*
9 |
10 | node_modules
11 | dist
12 | dist-ssr
13 | *.local
14 |
15 | # Editor directories and files
16 | .vscode/*
17 | !.vscode/extensions.json
18 | .idea
19 | .DS_Store
20 | *.suo
21 | *.ntvs*
22 | *.njsproj
23 | *.sln
24 | *.sw?
25 |
--------------------------------------------------------------------------------
/frontend/src/game/constants.ts:
--------------------------------------------------------------------------------
1 | import { pad } from "./padding";
2 |
3 | export const WIDTH = 800;
4 | export const HEIGHT = 800;
5 | export const ballRadius = 7;
6 | export const obstacleRadius = 4;
7 |
8 | export const gravity = pad(0.6);
9 | export const horizontalFriction = 0.4;
10 | export const verticalFriction = 0.8;
11 |
12 | export const sinkWidth = 36;
13 | export const NUM_SINKS = 17;
14 |
--------------------------------------------------------------------------------
/frontend/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Vite + React + TS
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/frontend/src/components/ui/Button.tsx:
--------------------------------------------------------------------------------
1 | export const Button = ({
2 | onClick,
3 | children,
4 | className,
5 | }: {
6 | onClick: () => void;
7 | children: React.ReactNode;
8 | className?: string;
9 | }) => {
10 | return (
11 |
15 | {children}
16 |
17 | );
18 | };
19 |
--------------------------------------------------------------------------------
/backend/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "backend",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "build": "tsc -b",
8 | "start": "node dist/index.js"
9 | },
10 | "keywords": [],
11 | "author": "",
12 | "license": "ISC",
13 | "dependencies": {
14 | "@types/cors": "^2.8.17",
15 | "@types/express": "^4.17.21",
16 | "cors": "^2.8.5",
17 | "express": "^4.19.2"
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/frontend/.eslintrc.cjs:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | root: true,
3 | env: { browser: true, es2020: true },
4 | extends: [
5 | 'eslint:recommended',
6 | 'plugin:@typescript-eslint/recommended',
7 | 'plugin:react-hooks/recommended',
8 | ],
9 | ignorePatterns: ['dist', '.eslintrc.cjs'],
10 | parser: '@typescript-eslint/parser',
11 | plugins: ['react-refresh'],
12 | rules: {
13 | 'react-refresh/only-export-components': [
14 | 'warn',
15 | { allowConstantExport: true },
16 | ],
17 | },
18 | }
19 |
--------------------------------------------------------------------------------
/frontend/src/App.tsx:
--------------------------------------------------------------------------------
1 | // import "./App.css";
2 | import { BrowserRouter, Routes, Route } from "react-router-dom";
3 | import { Simulation } from "./pages/Simulation";
4 | import { Game } from "./pages/Game";
5 | import { Footer, Navbar } from "./components";
6 | import { Home } from "./pages/Home";
7 |
8 | function App() {
9 | return (
10 |
11 |
12 |
13 | } />
14 | } />
15 | } />
16 |
17 |
18 |
19 | );
20 | }
21 |
22 | export default App;
23 |
--------------------------------------------------------------------------------
/frontend/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2020",
4 | "useDefineForClassFields": true,
5 | "lib": ["ES2020", "DOM", "DOM.Iterable"],
6 | "module": "ESNext",
7 | "skipLibCheck": true,
8 |
9 | /* Bundler mode */
10 | "moduleResolution": "bundler",
11 | "allowImportingTsExtensions": true,
12 | "resolveJsonModule": true,
13 | "isolatedModules": true,
14 | "noEmit": true,
15 | "jsx": "react-jsx",
16 |
17 | /* Linting */
18 | "strict": true,
19 | "noUnusedLocals": true,
20 | "noUnusedParameters": true,
21 | "noFallthroughCasesInSwitch": true
22 | },
23 | "include": ["src"],
24 | "references": [{ "path": "./tsconfig.node.json" }]
25 | }
26 |
--------------------------------------------------------------------------------
/frontend/src/App.css:
--------------------------------------------------------------------------------
1 | #root {
2 | max-width: 1280px;
3 | margin: 0 auto;
4 | padding: 2rem;
5 | text-align: center;
6 | }
7 |
8 | .logo {
9 | height: 6em;
10 | padding: 1.5em;
11 | will-change: filter;
12 | transition: filter 300ms;
13 | }
14 | .logo:hover {
15 | filter: drop-shadow(0 0 2em #646cffaa);
16 | }
17 | .logo.react:hover {
18 | filter: drop-shadow(0 0 2em #61dafbaa);
19 | }
20 |
21 | @keyframes logo-spin {
22 | from {
23 | transform: rotate(0deg);
24 | }
25 | to {
26 | transform: rotate(360deg);
27 | }
28 | }
29 |
30 | @media (prefers-reduced-motion: no-preference) {
31 | a:nth-of-type(2) .logo {
32 | animation: logo-spin infinite 20s linear;
33 | }
34 | }
35 |
36 | .card {
37 | padding: 2em;
38 | }
39 |
40 | .read-the-docs {
41 | color: #888;
42 | }
43 |
--------------------------------------------------------------------------------
/frontend/src/components/Quotes.tsx:
--------------------------------------------------------------------------------
1 | import { useNavigate } from "react-router-dom";
2 | import { Button } from "./ui/Button";
3 |
4 | export const Quotes = () => {
5 | const navigate = useNavigate();
6 | return (
7 |
8 |
Play Plinko, Earn More!
9 |
10 | Plinko lets players drop a ball from the top of our triangular pin
11 | pyramid to find the winning route down to a corresponding multiplier.
12 | Inspired by the Japanese mechanical game known as Pachinko, Plinko
13 | provides players with the ability to customise your risk factor and
14 | multipliers ensuring this Stake Original game is suited for everyone at
15 | our online casino !
16 |
17 | navigate("/game")}>
18 | Play Plinko
19 |
20 |
21 | );
22 | };
23 |
--------------------------------------------------------------------------------
/frontend/src/components/Game.tsx:
--------------------------------------------------------------------------------
1 | import { useEffect, useRef, useState } from "react"
2 | import { BallManager } from "../game/classes/BallManager";
3 | import axios from "axios";
4 |
5 |
6 | export function Game() {
7 | const [ballManager, setBallManager] = useState();
8 | const canvasRef = useRef();
9 |
10 | useEffect(() => {
11 | if (canvasRef.current) {
12 | const ballManager = new BallManager(canvasRef.current as unknown as HTMLCanvasElement,)
13 | setBallManager(ballManager)
14 | }
15 |
16 | }, [canvasRef])
17 |
18 | return (
19 |
20 |
21 | {
22 | const response = await axios.post("http://localhost:3000/game", {data: 1});
23 | if (ballManager) {
24 | ballManager.addBall(response.data.point);
25 | }
26 | }}>Add ball
27 |
28 | )
29 | }
--------------------------------------------------------------------------------
/frontend/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "frontend",
3 | "private": true,
4 | "version": "0.0.0",
5 | "type": "module",
6 | "scripts": {
7 | "dev": "vite",
8 | "build": "tsc && vite build",
9 | "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
10 | "preview": "vite preview"
11 | },
12 | "dependencies": {
13 | "axios": "^1.7.1",
14 | "react": "^18.2.0",
15 | "react-dom": "^18.2.0",
16 | "react-icons": "^5.2.1",
17 | "react-router-dom": "^6.23.1"
18 | },
19 | "devDependencies": {
20 | "@types/react": "^18.2.66",
21 | "@types/react-dom": "^18.2.22",
22 | "@typescript-eslint/eslint-plugin": "^7.2.0",
23 | "@typescript-eslint/parser": "^7.2.0",
24 | "@vitejs/plugin-react": "^4.2.1",
25 | "autoprefixer": "^10.4.19",
26 | "eslint": "^8.57.0",
27 | "eslint-plugin-react-hooks": "^4.6.0",
28 | "eslint-plugin-react-refresh": "^0.4.6",
29 | "postcss": "^8.4.38",
30 | "tailwindcss": "^3.4.3",
31 | "typescript": "^5.2.2",
32 | "vite": "^5.2.0"
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/backend/src/index.ts:
--------------------------------------------------------------------------------
1 |
2 | import express from "express";
3 | import { outcomes } from "./outcomes";
4 | import cors from "cors";
5 |
6 | const app = express();
7 | app.use(cors())
8 |
9 | const TOTAL_DROPS = 16;
10 |
11 | const MULTIPLIERS: {[ key: number ]: number} = {
12 | 0: 16,
13 | 1: 9,
14 | 2: 2,
15 | 3: 1.4,
16 | 4: 1.4,
17 | 5: 1.2,
18 | 6: 1.1,
19 | 7: 1,
20 | 8: 0.5,
21 | 9: 1,
22 | 10: 1.1,
23 | 11: 1.2,
24 | 12: 1.4,
25 | 13: 1.4,
26 | 14: 2,
27 | 15: 9,
28 | 16: 16
29 | }
30 |
31 | app.post("/game", (req, res) => {
32 | let outcome = 0;
33 | const pattern = []
34 | for (let i = 0; i < TOTAL_DROPS; i++) {
35 | if (Math.random() > 0.5) {
36 | pattern.push("R")
37 | outcome++;
38 | } else {
39 | pattern.push("L")
40 | }
41 | }
42 |
43 | const multiplier = MULTIPLIERS[outcome];
44 | const possiblieOutcomes = outcomes[outcome];
45 |
46 | res.send({
47 | point: possiblieOutcomes[Math.floor(Math.random() * possiblieOutcomes.length || 0)],
48 | multiplier,
49 | pattern
50 | });
51 | });
52 |
53 | app.listen(3000)
--------------------------------------------------------------------------------
/frontend/src/pages/Game.tsx:
--------------------------------------------------------------------------------
1 | import { useEffect, useRef, useState } from "react";
2 | import { BallManager } from "../game/classes/BallManager";
3 | import axios from "axios";
4 | import { Button } from "../components/ui";
5 | import { baseURL } from "../utils";
6 |
7 | export function Game() {
8 | const [ballManager, setBallManager] = useState();
9 | const canvasRef = useRef();
10 |
11 | useEffect(() => {
12 | if (canvasRef.current) {
13 | const ballManager = new BallManager(
14 | canvasRef.current as unknown as HTMLCanvasElement
15 | );
16 | setBallManager(ballManager);
17 | }
18 | }, [canvasRef]);
19 |
20 | return (
21 |
22 |
23 | {
26 | const response = await axios.post(`${baseURL}/game`, {
27 | data: 1,
28 | });
29 | if (ballManager) {
30 | ballManager.addBall(response.data.point);
31 | }
32 | }}
33 | >
34 | Add ball
35 |
36 |
37 | );
38 | }
39 |
--------------------------------------------------------------------------------
/frontend/README.md:
--------------------------------------------------------------------------------
1 | # React + TypeScript + Vite
2 |
3 | This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
4 |
5 | Currently, two official plugins are available:
6 |
7 | - [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh
8 | - [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh
9 |
10 | ## Expanding the ESLint configuration
11 |
12 | If you are developing a production application, we recommend updating the configuration to enable type aware lint rules:
13 |
14 | - Configure the top-level `parserOptions` property like this:
15 |
16 | ```js
17 | export default {
18 | // other rules...
19 | parserOptions: {
20 | ecmaVersion: 'latest',
21 | sourceType: 'module',
22 | project: ['./tsconfig.json', './tsconfig.node.json'],
23 | tsconfigRootDir: __dirname,
24 | },
25 | }
26 | ```
27 |
28 | - Replace `plugin:@typescript-eslint/recommended` to `plugin:@typescript-eslint/recommended-type-checked` or `plugin:@typescript-eslint/strict-type-checked`
29 | - Optionally add `plugin:@typescript-eslint/stylistic-type-checked`
30 | - Install [eslint-plugin-react](https://github.com/jsx-eslint/eslint-plugin-react) and add `plugin:react/recommended` & `plugin:react/jsx-runtime` to the `extends` list
31 |
--------------------------------------------------------------------------------
/frontend/public/vite.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/frontend/src/components/FoundIssue.tsx:
--------------------------------------------------------------------------------
1 | export const FoundIssue = () => {
2 | return (
3 |
4 |
5 |
6 |
10 |
11 |
12 |
13 | Found an Issue!
14 |
15 |
16 | Please create an issue in our github website below. You are also
17 | invited to contribute on the project.
18 |
19 |
20 |
25 |
30 | Github
31 |
32 |
33 |
34 |
35 | );
36 | };
37 |
--------------------------------------------------------------------------------
/frontend/src/index.css:
--------------------------------------------------------------------------------
1 | @tailwind base;
2 | @tailwind components;
3 | @tailwind utilities;
4 |
5 | :root {
6 | font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
7 | line-height: 1.5;
8 | font-weight: 400;
9 |
10 | color-scheme: light dark;
11 | color: rgba(255, 255, 255, 0.87);
12 | /* background-color: #213743; */
13 | background-color: #302e2b;
14 | font-synthesis: none;
15 | text-rendering: optimizeLegibility;
16 | -webkit-font-smoothing: antialiased;
17 | -moz-osx-font-smoothing: grayscale;
18 | font-family: "Times New Roman", Times, serif;
19 | }
20 | /*
21 | a {
22 | font-weight: 500;
23 | color: #646cff;
24 | text-decoration: inherit;
25 | }
26 | a:hover {
27 | color: #535bf2;
28 | }
29 |
30 | body {
31 | margin: 0;
32 | display: flex;
33 | place-items: center;
34 | min-width: 320px;
35 | min-height: 100vh;
36 | }
37 |
38 | h1 {
39 | font-size: 3.2em;
40 | line-height: 1.1;
41 | }
42 |
43 | button {
44 | border-radius: 8px;
45 | border: 1px solid transparent;
46 | padding: 0.6em 1.2em;
47 | font-size: 1em;
48 | font-weight: 500;
49 | font-family: inherit;
50 | background-color: #1a1a1a;
51 | cursor: pointer;
52 | transition: border-color 0.25s;
53 | }
54 | button:hover {
55 | border-color: #646cff;
56 | }
57 | button:focus,
58 | button:focus-visible {
59 | outline: 4px auto -webkit-focus-ring-color;
60 | }
61 |
62 | @media (prefers-color-scheme: light) {
63 | :root {
64 | color: #213547;
65 | background-color: #ffffff;
66 | }
67 | a:hover {
68 | color: #747bff;
69 | }
70 | button {
71 | background-color: #f9f9f9;
72 | }
73 | } */
74 |
--------------------------------------------------------------------------------
/frontend/src/components/Footer.tsx:
--------------------------------------------------------------------------------
1 | import { FaGithub, FaTwitter, FaYoutube } from "react-icons/fa";
2 | import { Link } from "react-router-dom";
3 |
4 | export const Footer = () => {
5 | return (
6 |
7 |
8 |
9 |
13 | {/*
*/}
18 |
19 | Plinkoo.100x
20 |
21 |
22 |
23 |
39 |
40 |
41 | );
42 | };
43 |
--------------------------------------------------------------------------------
/frontend/src/game/objects.ts:
--------------------------------------------------------------------------------
1 | import { HEIGHT, NUM_SINKS, WIDTH, obstacleRadius, sinkWidth } from "./constants";
2 | import { pad } from "./padding";
3 |
4 | export interface Obstacle {
5 | x: number;
6 | y: number;
7 | radius: number;
8 | }
9 |
10 | export interface Sink {
11 | x: number;
12 | y: number;
13 | width: number;
14 | height: number;
15 | multiplier?: number;
16 | }
17 |
18 | const MULTIPLIERS: {[ key: number ]: number} = {
19 | 1: 16,
20 | 2: 9,
21 | 3: 2,
22 | 4: 1.4,
23 | 5: 1.4,
24 | 6: 1.2,
25 | 7: 1.1,
26 | 8: 1,
27 | 9: 0.5,
28 | 10: 1,
29 | 11: 1.1,
30 | 12: 1.2,
31 | 13: 1.4,
32 | 14: 1.4,
33 | 15: 2,
34 | 16: 9,
35 | 17: 16
36 | }
37 |
38 | export const createObstacles = (): Obstacle[] => {
39 | const obstacles: Obstacle[] = [];
40 | const rows = 18;
41 | for (let row = 2; row < rows; row++) {
42 | const numObstacles = row + 1;
43 | const y = 0 + row * 35;
44 | const spacing = 36;
45 | for (let col = 0; col < numObstacles; col++) {
46 | const x = WIDTH / 2 - spacing * (row / 2 - col);
47 | obstacles.push({x: pad(x), y: pad(y), radius: obstacleRadius });
48 | }
49 | }
50 | return obstacles;
51 | }
52 |
53 | export const createSinks = (): Sink[] => {
54 | const sinks = [];
55 | const SPACING = obstacleRadius * 2;
56 |
57 | for (let i = 0; i < NUM_SINKS; i++) {
58 | const x = WIDTH / 2 + sinkWidth * (i - Math.floor(NUM_SINKS/2)) - SPACING * 1.5;
59 | const y = HEIGHT - 170;
60 | const width = sinkWidth;
61 | const height = width;
62 | sinks.push({ x, y, width, height, multiplier: MULTIPLIERS[i+1] });
63 | }
64 |
65 | return sinks;
66 | }
67 |
--------------------------------------------------------------------------------
/frontend/src/components/Simulate.tsx:
--------------------------------------------------------------------------------
1 | import { useEffect, useRef, useState } from "react";
2 |
3 | import { useNavigate } from "react-router-dom";
4 | import { BallManager } from "../game/classes/BallManager";
5 | import { pad } from "../game/padding";
6 | import { WIDTH } from "../game/constants";
7 |
8 | export const Simulate = () => {
9 | const navigate = useNavigate();
10 |
11 | const canvasRef = useRef();
12 | let [outputs, setOutputs] = useState<{ [key: number]: number[] }>({
13 | 0: [],
14 | 1: [],
15 | 2: [],
16 | 3: [],
17 | 4: [],
18 | 5: [],
19 | 6: [],
20 | 7: [],
21 | 8: [],
22 | 9: [],
23 | 10: [],
24 | 11: [],
25 | 12: [],
26 | 13: [],
27 | 14: [],
28 | 15: [],
29 | 16: [],
30 | 17: [],
31 | });
32 |
33 | async function simulate(ballManager: BallManager) {
34 | let i = 0;
35 | while (1) {
36 | i++;
37 | ballManager.addBall(pad(WIDTH / 2 + 20 * (Math.random() - 0.5)));
38 | await new Promise((resolve) => setTimeout(resolve, 1000));
39 | }
40 | }
41 |
42 | useEffect(() => {
43 | if (canvasRef.current) {
44 | const ballManager = new BallManager(
45 | canvasRef.current as unknown as HTMLCanvasElement,
46 | (index: number, startX?: number) => {
47 | setOutputs((outputs: any) => {
48 | return {
49 | ...outputs,
50 | [index]: [...(outputs[index] as number[]), startX],
51 | };
52 | });
53 | }
54 | );
55 | simulate(ballManager);
56 |
57 | return () => {
58 | ballManager.stop();
59 | };
60 | }
61 | }, [canvasRef]);
62 |
63 | return (
64 |
65 |
66 |
67 | );
68 | };
69 |
--------------------------------------------------------------------------------
/frontend/src/pages/Simulation.tsx:
--------------------------------------------------------------------------------
1 | import { useEffect, useRef, useState } from "react";
2 | import { BallManager } from "../game/classes/BallManager";
3 | import { WIDTH } from "../game/constants";
4 | import { pad } from "../game/padding";
5 |
6 | export function Simulation() {
7 | const canvasRef = useRef();
8 | let [outputs, setOutputs] = useState<{ [key: number]: number[] }>({
9 | 0: [],
10 | 1: [],
11 | 2: [],
12 | 3: [],
13 | 4: [],
14 | 5: [],
15 | 6: [],
16 | 7: [],
17 | 8: [],
18 | 9: [],
19 | 10: [],
20 | 11: [],
21 | 12: [],
22 | 13: [],
23 | 14: [],
24 | 15: [],
25 | 16: [],
26 | 17: [],
27 | });
28 |
29 | async function simulate(ballManager: BallManager) {
30 | let i = 0;
31 | while (1) {
32 | i++;
33 | ballManager.addBall(pad(WIDTH / 2 + 20 * (Math.random() - 0.5)));
34 | await new Promise((resolve) => setTimeout(resolve, 1000));
35 | }
36 | }
37 |
38 | useEffect(() => {
39 | if (canvasRef.current) {
40 | const ballManager = new BallManager(
41 | canvasRef.current as unknown as HTMLCanvasElement,
42 | (index: number, startX?: number) => {
43 | setOutputs((outputs: any) => {
44 | return {
45 | ...outputs,
46 | [index]: [...(outputs[index] as number[]), startX],
47 | };
48 | });
49 | }
50 | );
51 | simulate(ballManager);
52 |
53 | return () => {
54 | ballManager.stop();
55 | };
56 | }
57 | }, [canvasRef]);
58 |
59 | return (
60 |
61 |
62 | {JSON.stringify(outputs, null, 2)}
63 |
64 |
65 |
66 |
67 |
68 | );
69 | }
70 |
--------------------------------------------------------------------------------
/frontend/src/pages/Home.tsx:
--------------------------------------------------------------------------------
1 | import { useEffect, useRef, useState } from "react";
2 | import { BallManager } from "../game/classes/BallManager";
3 | import { WIDTH } from "../game/constants";
4 | import { pad } from "../game/padding";
5 | import { useNavigate } from "react-router-dom";
6 | import { Simulate } from "../components/Simulate";
7 | import { Quotes, FoundIssue } from "../components";
8 |
9 | export function Home() {
10 | const navigate = useNavigate();
11 |
12 | const canvasRef = useRef();
13 | let [outputs, setOutputs] = useState<{ [key: number]: number[] }>({
14 | 0: [],
15 | 1: [],
16 | 2: [],
17 | 3: [],
18 | 4: [],
19 | 5: [],
20 | 6: [],
21 | 7: [],
22 | 8: [],
23 | 9: [],
24 | 10: [],
25 | 11: [],
26 | 12: [],
27 | 13: [],
28 | 14: [],
29 | 15: [],
30 | 16: [],
31 | 17: [],
32 | });
33 |
34 | async function simulate(ballManager: BallManager) {
35 | let i = 0;
36 | while (1) {
37 | i++;
38 | ballManager.addBall(pad(WIDTH / 2 + 20 * (Math.random() - 0.5)));
39 | await new Promise((resolve) => setTimeout(resolve, 1000));
40 | }
41 | }
42 |
43 | useEffect(() => {
44 | if (canvasRef.current) {
45 | const ballManager = new BallManager(
46 | canvasRef.current as unknown as HTMLCanvasElement,
47 | (index: number, startX?: number) => {
48 | setOutputs((outputs: any) => {
49 | return {
50 | ...outputs,
51 | [index]: [...(outputs[index] as number[]), startX],
52 | };
53 | });
54 | }
55 | );
56 | simulate(ballManager);
57 |
58 | return () => {
59 | ballManager.stop();
60 | };
61 | }
62 | }, [canvasRef]);
63 |
64 | return (
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 | );
73 | }
74 |
--------------------------------------------------------------------------------
/frontend/src/components/Simulation.tsx:
--------------------------------------------------------------------------------
1 | import { useEffect, useRef, useState } from "react"
2 | import { BallManager } from "../game/classes/BallManager";
3 | import { WIDTH } from "../game/constants";
4 | import { pad } from "../game/padding";
5 |
6 |
7 | export function Simulation() {
8 | const canvasRef = useRef();
9 | let [outputs, setOutputs] = useState<{[key: number]: number[]}>({
10 | 0: [],
11 | 1: [],
12 | 2: [],
13 | 3: [],
14 | 4: [],
15 | 5: [],
16 | 6: [],
17 | 7: [],
18 | 8: [],
19 | 9: [],
20 | 10: [],
21 | 11: [],
22 | 12: [],
23 | 13: [],
24 | 14: [],
25 | 15: [],
26 | 16: [],
27 | 17: []
28 | });
29 |
30 | async function simulate(ballManager: BallManager) {
31 | let i = 0;
32 | while (1) {
33 | i++
34 | ballManager.addBall(pad(WIDTH / 2 + 20 * (Math.random() - 0.5)))
35 | await new Promise(resolve => setTimeout(resolve, 1000));
36 | }
37 | }
38 |
39 | useEffect(() => {
40 | if (canvasRef.current) {
41 | const ballManager = new BallManager(canvasRef.current as unknown as HTMLCanvasElement, (index: number, startX?: number) => {
42 | setOutputs((outputs: any) => {
43 | return {
44 | ...outputs,
45 | [index]: [...outputs[index] as number[], startX]
46 | }
47 | })
48 | })
49 | simulate(ballManager);
50 |
51 | return () => {
52 | ballManager.stop();
53 | }
54 | }
55 |
56 | }, [canvasRef])
57 |
58 | return (
59 |
60 |
61 | {JSON.stringify(outputs, null, 2)}
62 |
63 |
64 |
65 |
66 |
67 | )
68 | }
69 |
--------------------------------------------------------------------------------
/frontend/src/components/Navbar.tsx:
--------------------------------------------------------------------------------
1 | import { RxHamburgerMenu } from "react-icons/rx";
2 | import { Button } from "./ui";
3 | import { Link, useNavigate } from "react-router-dom";
4 | import { useState } from "react";
5 |
6 | export const Navbar = () => {
7 | const [isMenuOpen, setIsMenuOpen] = useState(false);
8 | const navigate = useNavigate();
9 | return (
10 |
11 |
12 |
16 | {/*
*/}
21 |
22 | Plinkoo.100x
23 |
24 |
25 |
{
29 | setIsMenuOpen(!isMenuOpen);
30 | }}
31 | >
32 | Open main menu
33 |
34 | {" "}
35 |
41 | navigate("/simulation")}
44 | >
45 | Simulation
46 |
47 | navigate("/game")}
50 | >
51 | Game
52 |
53 |
54 |
55 | navigate("/simulation")}
58 | >
59 | Simulation
60 |
61 | navigate("/game")}
64 | >
65 | Game
66 |
67 |
68 |
69 |
70 | );
71 | };
72 |
--------------------------------------------------------------------------------
/frontend/src/game/classes/Ball.ts:
--------------------------------------------------------------------------------
1 | import { gravity, horizontalFriction, verticalFriction } from "../constants";
2 | import { Obstacle, Sink } from "../objects";
3 | import { pad, unpad } from "../padding";
4 |
5 | export class Ball {
6 | private x: number;
7 | private y: number;
8 | private radius: number;
9 | private color: string;
10 | private vx: number;
11 | private vy: number;
12 | private ctx: CanvasRenderingContext2D;
13 | private obstacles: Obstacle[]
14 | private sinks: Sink[]
15 | private onFinish: (index: number) => void;
16 |
17 | constructor(x: number, y: number, radius: number, color: string, ctx: CanvasRenderingContext2D, obstacles: Obstacle[], sinks: Sink[], onFinish: (index: number) => void) {
18 | this.x = x;
19 | this.y = y;
20 | this.radius = radius;
21 | this.color = color;
22 | this.vx = 0;
23 | this.vy = 0;
24 | this.ctx = ctx;
25 | this.obstacles = obstacles;
26 | this.sinks = sinks;
27 | this.onFinish = onFinish;
28 | }
29 |
30 | draw() {
31 | this.ctx.beginPath();
32 | this.ctx.arc(unpad(this.x), unpad(this.y), this.radius, 0, Math.PI * 2);
33 | this.ctx.fillStyle = this.color;
34 | this.ctx.fill();
35 | this.ctx.closePath();
36 | }
37 |
38 | update() {
39 | this.vy += gravity;
40 | this.x += this.vx;
41 | this.y += this.vy;
42 |
43 | // Collision with obstacles
44 | this.obstacles.forEach(obstacle => {
45 | const dist = Math.hypot(this.x - obstacle.x, this.y - obstacle.y);
46 | if (dist < pad(this.radius + obstacle.radius)) {
47 | // Calculate collision angle
48 | const angle = Math.atan2(this.y - obstacle.y, this.x - obstacle.x);
49 | // Reflect velocity
50 | const speed = Math.sqrt(this.vx * this.vx + this.vy * this.vy);
51 | this.vx = (Math.cos(angle) * speed * horizontalFriction);
52 | this.vy = Math.sin(angle) * speed * verticalFriction;
53 |
54 | // Adjust position to prevent sticking
55 | const overlap = this.radius + obstacle.radius - unpad(dist);
56 | this.x += pad(Math.cos(angle) * overlap);
57 | this.y += pad(Math.sin(angle) * overlap);
58 | }
59 | });
60 |
61 | // Collision with sinks
62 | for (let i = 0; i < this.sinks.length; i++) {
63 | const sink = this.sinks[i];
64 | if (
65 | unpad(this.x) > sink.x - sink.width / 2 &&
66 | unpad(this.x) < sink.x + sink.width / 2 &&
67 | (unpad(this.y) + this.radius) > (sink.y - sink.height / 2)
68 | ) {
69 | this.vx = 0;
70 | this.vy = 0;
71 | this.onFinish(i);
72 | break;
73 | }
74 | }
75 | }
76 |
77 | }
--------------------------------------------------------------------------------
/frontend/src/game/classes/BallManager.ts:
--------------------------------------------------------------------------------
1 | import { HEIGHT, WIDTH, ballRadius, obstacleRadius, sinkWidth } from "../constants";
2 | import { Obstacle, Sink, createObstacles, createSinks } from "../objects";
3 | import { pad, unpad } from "../padding";
4 | import { Ball } from "./Ball";
5 |
6 | export class BallManager {
7 | private balls: Ball[];
8 | private canvasRef: HTMLCanvasElement;
9 | private ctx: CanvasRenderingContext2D;
10 | private obstacles: Obstacle[]
11 | private sinks: Sink[]
12 | private requestId?: number;
13 | private onFinish?: (index: number,startX?: number) => void;
14 |
15 | constructor(canvasRef: HTMLCanvasElement, onFinish?: (index: number,startX?: number) => void) {
16 | this.balls = [];
17 | this.canvasRef = canvasRef;
18 | this.ctx = this.canvasRef.getContext("2d")!;
19 | this.obstacles = createObstacles();
20 | this.sinks = createSinks();
21 | this.update();
22 | this.onFinish = onFinish;
23 | }
24 |
25 | addBall(startX?: number) {
26 | const newBall = new Ball(startX || pad(WIDTH / 2 + 13), pad(50), ballRadius, 'red', this.ctx, this.obstacles, this.sinks, (index) => {
27 | this.balls = this.balls.filter(ball => ball !== newBall);
28 | this.onFinish?.(index, startX)
29 | });
30 | this.balls.push(newBall);
31 | }
32 |
33 | drawObstacles() {
34 | this.ctx.fillStyle = 'white';
35 | this.obstacles.forEach((obstacle) => {
36 | this.ctx.beginPath();
37 | this.ctx.arc(unpad(obstacle.x), unpad(obstacle.y), obstacle.radius, 0, Math.PI * 2);
38 | this.ctx.fill();
39 | this.ctx.closePath();
40 | });
41 | }
42 |
43 | getColor(index: number) {
44 | if (index <3 || index > this.sinks.length - 3) {
45 | return {background: '#ff003f', color: 'white'};
46 | }
47 | if (index < 6 || index > this.sinks.length - 6) {
48 | return {background: '#ff7f00', color: 'white'};
49 | }
50 | if (index < 9 || index > this.sinks.length - 9) {
51 | return {background: '#ffbf00', color: 'black'};
52 | }
53 | if (index < 12 || index > this.sinks.length - 12) {
54 | return {background: '#ffff00', color: 'black'};
55 | }
56 | if (index < 15 || index > this.sinks.length - 15) {
57 | return {background: '#bfff00', color: 'black'};
58 | }
59 | return {background: '#7fff00', color: 'black'};
60 | }
61 | drawSinks() {
62 | this.ctx.fillStyle = 'green';
63 | const SPACING = obstacleRadius * 2;
64 | for (let i = 0; i {
79 | ball.draw();
80 | ball.update();
81 | });
82 | }
83 |
84 | update() {
85 | this.draw();
86 | this.requestId = requestAnimationFrame(this.update.bind(this));
87 | }
88 |
89 | stop() {
90 | if (this.requestId) {
91 | cancelAnimationFrame(this.requestId);
92 | }
93 | }
94 | }
--------------------------------------------------------------------------------
/frontend/src/assets/react.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/version-1/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Canvas Game
8 |
22 |
23 |
24 |
25 |
26 | Add Ball
27 |
185 |
186 |
187 |
188 |
--------------------------------------------------------------------------------
/frontend/src/game/outcomes.ts:
--------------------------------------------------------------------------------
1 | export const outcomes = { "0": [], "1": [ 3964963.452981615, 3910113.3998412564 ], "2": [ 3980805.7004139693, 3945617.6504109767, 4027628.395823398, 3902115.8620758583, 3938709.5467746584 ], "3": [ 3975554.824601942, 3965805.769610554, 3909279.443666201, 3940971.550465178, 3909606.717374134, 3915484.1741136736, 3977018.430328505, 3979167.5933461944, 3995981.0273005674, 3974177.78840204 ], "4": [ 3943174.7607756723, 3992961.0886867167, 3914511.2798374896, 3950487.300703086, 3973378.3900412438, 4012888.985549594, 4040961.8767680754, 4066503.3857407006, 3944573.7194061875, 3979876.769324002, 4042712.772834604, 4032991.0303322095, 4046340.7919081766, 3912597.9665436875, 4068852.495940549, 4064879.257329362, 3996796.04239161, 4045062.2783860737, 3964680.919169739 ], "5": [ 3953045.1447091424, 3947374.62976226, 3924082.6101653073, 3919085.269354398, 3902650.4008744615, 3934968.1593932374, 4044126.7590222214, 3928499.8807134246, 3913801.9247018984, 3909595.4432100505, 4082827.827013994, 3979739.108665962, 4077651.317785833, 4008030.8883127486, 3950951.6007580766, 3992039.9053288833, 4021810.0928285993, 4052650.560434505, 3994806.267259329, 3959327.3735489477, 3940455.7641962855, 3998822.2807239015, 3998803.9335444313, 4068193.3913483596, 3938798.911585438 ], "6": [ 4065643.7049927213, 3936841.961313155, 3948472.8991447487, 4004510.5975928125, 3933695.6888747592, 4011296.1958215656, 4093232.84383817, 3945658.6170622837, 4063199.5117669366, 4037864.799653558, 3931477.3517858014, 4091381.513010509, 4000895.053297006, 4042867.6535872207, 4090947.938511616, 3989468.333758437, 3943335.764879169, 3947278.536321405, 4022304.817103859, 3902177.8466275427, 3925270.959381573, 3955253.4540312397, 3986641.0060988157, 3927696.2396482667, 4064571.150949869, 3991167.946685552, 3973041.308793569, 3987377.180906899, 3917262.667253392, 4002606.795366179, 4033596.992526079, 3901372.366183016, 4015207.583244224, 3955421.290959922, 3952223.0425123484, 3941774.4498685915, 3977289.3718391117, 4024943.3014183883, 4024885.5052148327, 4016596.7449097126, 3910164.1864616796, 4023400.498352244, 3981421.8628830933, 3913377.3496230906, 4045958.9425667236, 4071139.892029292, 4019862.922309672, 4027992.2300945413, 4030455.1701347437, 4060673.10227606, 3996564.062673036, 4009801.4052053, 4007734.404953163, 4046612.754675019, 3944956.9979153597, 3977382.889196781, 3906636.5132748624, 4080470.0674178666, 3996210.4877184015, 3956216.294023866, 3940040.183231992 ], "7": [ 3926739.9104774813, 4091374.44234272, 4061919.9903071183, 3976066.7555194413, 3948801.1936986246, 4043233.7830772344, 4010011.7658794387, 3936431.4108806592, 3942776.8649452417, 3909995.011479453, 4012272.43979473, 3989907.069429411, 3996182.4336681785, 4078644.79693604, 4081624.0834239917, 4025044.731614778, 4033602.5381773794, 3913189.826642105, 3910500.674962151, 4055296.6588616692, 4005574.8641647273, 4079800.3518520766, 4092763.5236495608, 3952185.4910905147, 3945510.495018459, 3920891.8818843197, 3997101.789672143, 3991974.822516503, 3949265.4371072412, 3933412.4749754136, 3933181.8312838264, 4063875.6616431624, 3998206.7252218956, 3959006.1987530286, 3924067.917601976, 3902914.4459602935, 3905347.098696195, 4000831.565288375, 3944915.3251241, 3930343.481158048, 4025858.616981573, 4026496.026592473, 3948116.019901921, 4067143.737297127, 3995156.000931595, 3905006.3301882823, 4035783.4852589793, 3956461.6106608217, 4032886.6912715673, 3913146.10237042, 3930772.085213345, 3984887.619042549, 4053031.0321973227, 3913395.137097174, 3993579.678508536, 3932427.236196532, 3984279.0886106077 ], "8": [ 4099062.75134143, 4085894.4181278455, 3991123.0115790954, 3973053.5827605873, 3968190.564301313, 3925604.5066868863, 3933898.7590061547, 4089919.7991958153, 4076997.5225973814, 3957630.60529322, 3948999.35996541, 3963938.9455971997, 4044805.7991237757, 3905133.2109927135, 4074463.6876271376, 3939301.0655442886, 4040571.320635691, 4020510.19979044, 3959835.4618981928, 4037241.67248416, 4043105.87901907, 3912654.2409310103, 3929773.262095125, 3950802.527033251, 4068582.4605300324, 3946792.6177569656, 4078475.9982660934, 3972024.763383927, 3947150.677862883, 3963410.9779685168, 3999134.851845996, 3909374.1117644133, 3942761.896008833, 4071253.4107468165, 4050534.50171971, 3988521.4618817912, 3929940.089627246, 4029305.1056314665, 4087943.221841722, 3910909.3079385986, 4046944.0552393594, 4006944.159180551, 4014707.657017377, 3925473.574267122, 4012158.905329344, 4042197.149473071, 3998434.6078570196, 4047267.2747256896, 3964753.3725316986, 3955821.0222197613, 3973475.662585886, 3917189.0280630635, 4027132.7848505056, 3905368.7668914935, 3936654.62186107, 4092566.3229272505, 4026541.0685970024, 4038770.6420815475, 4067262.4257867294, 4050430.5327158393, 3980149.8069138955, 4052184.5678737606, 3942299.598280835, 4079754.687607573, 4021112.5651541506, 3961023.3381184433, 3937025.1424917267, 3964607.486702018, 4001319.0133674755, 3941648.5232227165, 4030587.9685114417, 4044067.1579758436, 4058158.522928313 ], "9": [ 3911530.315770063, 4024711.492410591, 3967652.4297853387, 4098886.3793751886, 4026117.0283389515, 4045045.4095477182, 4034571.220507859, 4088809.303306565, 3900806.968890352, 3913166.9251142726, 4059594.3600833854, 3945137.694311404, 3902668.8160601873, 4054646.2889849013, 4053898.6542759663, 3959251.11275926, 3963475.882565954, 3967968.9310842347, 4075078.929914972, 4035117.4533019722, 4047608.2592268144, 3913024.5010530455, 4081362.0390194473, 4098538.7144543654, 4049336.7774994993, 4056844.5727342237, 3917845.6810319433, 4098332.1779752634, 3979547.7686487637, 4026747.155594485, 3944692.803167993, 3960649.105237204, 4081040.2295870385, 4005698.9658651184, 4074183.694152899, 3976184.3586868607, 4007157.5084493076, 3918927.3398626954, 3918166.0285542854, 3953868.3374998523, 3963648.6249533077, 4065036.1837552087, 3964230.698479104, 3992799.530672317, 3931113.922813188, 4082916.6661583954, 3919236.111874976, 4012743.1541231154, 3900406.2441578982, 4031396.764516756, 4088712.2834741194, 3921570.4946371615, 4077416.64169384, 3962807.6000533635 ], "10": [ 4069582.648305392, 3966300.3577461895, 4047184.7847023425, 3962656.256238744, 3934682.0223851865, 4089620.291559703, 3996605.065672608, 3921656.567101851, 3950930.30704122, 4052733.606190915, 4046762.051641918, 3912718.72211605, 3942094.6698735086, 4017504.735499972, 4016206.1612997893, 4060896.040328729, 4077224.686824909, 3988932.185505723, 4016550.502499315, 3959104.134236025, 3903531.023685199, 3939907.5585800377, 3969464.753065079, 4036549.7059165714, 3938844.715578784, 3985594.4268763512, 4011615.276676018, 3949739.058361909, 4064041.8926257566, 4004767.498301687, 3996411.8026064364, 4035064.3182208547, 3988008.7378418343, 4015638.96642283, 3967068.722994021, 4082965.2856357233, 3951302.134707721, 3948101.1830631103, 3978745.8509503608, 4068638.265329366, 4018433.726155858, 4032765.523475676 ], "11": [ 4055462.593704495, 4027576.362231998, 4011290.7395424685, 4034848.6574270525, 4064298.598636101, 3997022.919190929, 4053625.932623065, 4064234.3514714935, 4075348.9710445153, 4060118.5348266517, 4065992.932112665, 4063162.143518177, 4060798.1858924176, 3956764.654354398, 3912916.1668887464, 4018282.0763658765, 4065575.3280486814, 3967348.3916016137, 4034992.477051428, 4069123.2018048204, 3939281.4172981237, 4022103.802712647, 4083993.320300048, 4034478.871034405, 4068844.513451607, 4097187.535489012, 3981130.4047553614, 4068312.6406908804, 4050921.0879167155, 4048297.277514315, 3953878.475004285, 3998627.3710734197 ], "12": [ 4007152.5182738686, 4014664.8542149696, 4095619.5802802853, 4018084.7270321106, 4072050.3744347296, 4026256.723716898, 4095827.9573665825, 4023631.9896559394, 4046751.9125588783, 3973758.674124694, 4081927.075527175, 3922485.387310559, 4001549.2805312183, 4050417.849670596, 3987607.4531957353, 4060206.9664999805, 4080316.8473846694, 4030455.1532406537, 4087714.965906726, 4028165.0792610054, 4032588.5261474997, 3980546.468460318, 4090408.033691761, 3990019.103297975, 4088755.998466496, 4092162.22327816, 4029036.6583707742, 4055066.505591603, 4081998.821392285, 4079550.553314541 ], "13": [ 3905319.849889843, 4054719.0660902266, 4055596.4319745116, 3992648.989962779, 3924972.5941170114, 4095167.7814041013, 3912740.1944122575, 4024882.9438952096, 4023171.3988155797, 4059892.954049364, 4068510.96886605, 4093838.431690223, 4070524.1327491063 ], "14": [ 4092261.8249403643, 3956304.3865069468, 4069053.2302732924, 4038890.8473817194 ], "15": [ 4013891.110502415, 3977489.9532032954, 4044335.989753631, 4066199.8081775964 ], "16": [ 3979706.1687804307, 4024156.037977316 ], "17": [] }
--------------------------------------------------------------------------------
/backend/src/outcomes.ts:
--------------------------------------------------------------------------------
1 | export const outcomes: {[key: string]: number[]} = { "0": [], "1": [ 3964963.452981615, 3910113.3998412564 ], "2": [ 3980805.7004139693, 3945617.6504109767, 4027628.395823398, 3902115.8620758583, 3938709.5467746584 ], "3": [ 3975554.824601942, 3965805.769610554, 3909279.443666201, 3940971.550465178, 3909606.717374134, 3915484.1741136736, 3977018.430328505, 3979167.5933461944, 3995981.0273005674, 3974177.78840204 ], "4": [ 3943174.7607756723, 3992961.0886867167, 3914511.2798374896, 3950487.300703086, 3973378.3900412438, 4012888.985549594, 4040961.8767680754, 4066503.3857407006, 3944573.7194061875, 3979876.769324002, 4042712.772834604, 4032991.0303322095, 4046340.7919081766, 3912597.9665436875, 4068852.495940549, 4064879.257329362, 3996796.04239161, 4045062.2783860737, 3964680.919169739 ], "5": [ 3953045.1447091424, 3947374.62976226, 3924082.6101653073, 3919085.269354398, 3902650.4008744615, 3934968.1593932374, 4044126.7590222214, 3928499.8807134246, 3913801.9247018984, 3909595.4432100505, 4082827.827013994, 3979739.108665962, 4077651.317785833, 4008030.8883127486, 3950951.6007580766, 3992039.9053288833, 4021810.0928285993, 4052650.560434505, 3994806.267259329, 3959327.3735489477, 3940455.7641962855, 3998822.2807239015, 3998803.9335444313, 4068193.3913483596, 3938798.911585438 ], "6": [ 4065643.7049927213, 3936841.961313155, 3948472.8991447487, 4004510.5975928125, 3933695.6888747592, 4011296.1958215656, 4093232.84383817, 3945658.6170622837, 4063199.5117669366, 4037864.799653558, 3931477.3517858014, 4091381.513010509, 4000895.053297006, 4042867.6535872207, 4090947.938511616, 3989468.333758437, 3943335.764879169, 3947278.536321405, 4022304.817103859, 3902177.8466275427, 3925270.959381573, 3955253.4540312397, 3986641.0060988157, 3927696.2396482667, 4064571.150949869, 3991167.946685552, 3973041.308793569, 3987377.180906899, 3917262.667253392, 4002606.795366179, 4033596.992526079, 3901372.366183016, 4015207.583244224, 3955421.290959922, 3952223.0425123484, 3941774.4498685915, 3977289.3718391117, 4024943.3014183883, 4024885.5052148327, 4016596.7449097126, 3910164.1864616796, 4023400.498352244, 3981421.8628830933, 3913377.3496230906, 4045958.9425667236, 4071139.892029292, 4019862.922309672, 4027992.2300945413, 4030455.1701347437, 4060673.10227606, 3996564.062673036, 4009801.4052053, 4007734.404953163, 4046612.754675019, 3944956.9979153597, 3977382.889196781, 3906636.5132748624, 4080470.0674178666, 3996210.4877184015, 3956216.294023866, 3940040.183231992 ], "7": [ 3926739.9104774813, 4091374.44234272, 4061919.9903071183, 3976066.7555194413, 3948801.1936986246, 4043233.7830772344, 4010011.7658794387, 3936431.4108806592, 3942776.8649452417, 3909995.011479453, 4012272.43979473, 3989907.069429411, 3996182.4336681785, 4078644.79693604, 4081624.0834239917, 4025044.731614778, 4033602.5381773794, 3913189.826642105, 3910500.674962151, 4055296.6588616692, 4005574.8641647273, 4079800.3518520766, 4092763.5236495608, 3952185.4910905147, 3945510.495018459, 3920891.8818843197, 3997101.789672143, 3991974.822516503, 3949265.4371072412, 3933412.4749754136, 3933181.8312838264, 4063875.6616431624, 3998206.7252218956, 3959006.1987530286, 3924067.917601976, 3902914.4459602935, 3905347.098696195, 4000831.565288375, 3944915.3251241, 3930343.481158048, 4025858.616981573, 4026496.026592473, 3948116.019901921, 4067143.737297127, 3995156.000931595, 3905006.3301882823, 4035783.4852589793, 3956461.6106608217, 4032886.6912715673, 3913146.10237042, 3930772.085213345, 3984887.619042549, 4053031.0321973227, 3913395.137097174, 3993579.678508536, 3932427.236196532, 3984279.0886106077 ], "8": [ 4099062.75134143, 4085894.4181278455, 3991123.0115790954, 3973053.5827605873, 3968190.564301313, 3925604.5066868863, 3933898.7590061547, 4089919.7991958153, 4076997.5225973814, 3957630.60529322, 3948999.35996541, 3963938.9455971997, 4044805.7991237757, 3905133.2109927135, 4074463.6876271376, 3939301.0655442886, 4040571.320635691, 4020510.19979044, 3959835.4618981928, 4037241.67248416, 4043105.87901907, 3912654.2409310103, 3929773.262095125, 3950802.527033251, 4068582.4605300324, 3946792.6177569656, 4078475.9982660934, 3972024.763383927, 3947150.677862883, 3963410.9779685168, 3999134.851845996, 3909374.1117644133, 3942761.896008833, 4071253.4107468165, 4050534.50171971, 3988521.4618817912, 3929940.089627246, 4029305.1056314665, 4087943.221841722, 3910909.3079385986, 4046944.0552393594, 4006944.159180551, 4014707.657017377, 3925473.574267122, 4012158.905329344, 4042197.149473071, 3998434.6078570196, 4047267.2747256896, 3964753.3725316986, 3955821.0222197613, 3973475.662585886, 3917189.0280630635, 4027132.7848505056, 3905368.7668914935, 3936654.62186107, 4092566.3229272505, 4026541.0685970024, 4038770.6420815475, 4067262.4257867294, 4050430.5327158393, 3980149.8069138955, 4052184.5678737606, 3942299.598280835, 4079754.687607573, 4021112.5651541506, 3961023.3381184433, 3937025.1424917267, 3964607.486702018, 4001319.0133674755, 3941648.5232227165, 4030587.9685114417, 4044067.1579758436, 4058158.522928313 ], "9": [ 3911530.315770063, 4024711.492410591, 3967652.4297853387, 4098886.3793751886, 4026117.0283389515, 4045045.4095477182, 4034571.220507859, 4088809.303306565, 3900806.968890352, 3913166.9251142726, 4059594.3600833854, 3945137.694311404, 3902668.8160601873, 4054646.2889849013, 4053898.6542759663, 3959251.11275926, 3963475.882565954, 3967968.9310842347, 4075078.929914972, 4035117.4533019722, 4047608.2592268144, 3913024.5010530455, 4081362.0390194473, 4098538.7144543654, 4049336.7774994993, 4056844.5727342237, 3917845.6810319433, 4098332.1779752634, 3979547.7686487637, 4026747.155594485, 3944692.803167993, 3960649.105237204, 4081040.2295870385, 4005698.9658651184, 4074183.694152899, 3976184.3586868607, 4007157.5084493076, 3918927.3398626954, 3918166.0285542854, 3953868.3374998523, 3963648.6249533077, 4065036.1837552087, 3964230.698479104, 3992799.530672317, 3931113.922813188, 4082916.6661583954, 3919236.111874976, 4012743.1541231154, 3900406.2441578982, 4031396.764516756, 4088712.2834741194, 3921570.4946371615, 4077416.64169384, 3962807.6000533635 ], "10": [ 4069582.648305392, 3966300.3577461895, 4047184.7847023425, 3962656.256238744, 3934682.0223851865, 4089620.291559703, 3996605.065672608, 3921656.567101851, 3950930.30704122, 4052733.606190915, 4046762.051641918, 3912718.72211605, 3942094.6698735086, 4017504.735499972, 4016206.1612997893, 4060896.040328729, 4077224.686824909, 3988932.185505723, 4016550.502499315, 3959104.134236025, 3903531.023685199, 3939907.5585800377, 3969464.753065079, 4036549.7059165714, 3938844.715578784, 3985594.4268763512, 4011615.276676018, 3949739.058361909, 4064041.8926257566, 4004767.498301687, 3996411.8026064364, 4035064.3182208547, 3988008.7378418343, 4015638.96642283, 3967068.722994021, 4082965.2856357233, 3951302.134707721, 3948101.1830631103, 3978745.8509503608, 4068638.265329366, 4018433.726155858, 4032765.523475676 ], "11": [ 4055462.593704495, 4027576.362231998, 4011290.7395424685, 4034848.6574270525, 4064298.598636101, 3997022.919190929, 4053625.932623065, 4064234.3514714935, 4075348.9710445153, 4060118.5348266517, 4065992.932112665, 4063162.143518177, 4060798.1858924176, 3956764.654354398, 3912916.1668887464, 4018282.0763658765, 4065575.3280486814, 3967348.3916016137, 4034992.477051428, 4069123.2018048204, 3939281.4172981237, 4022103.802712647, 4083993.320300048, 4034478.871034405, 4068844.513451607, 4097187.535489012, 3981130.4047553614, 4068312.6406908804, 4050921.0879167155, 4048297.277514315, 3953878.475004285, 3998627.3710734197 ], "12": [ 4007152.5182738686, 4014664.8542149696, 4095619.5802802853, 4018084.7270321106, 4072050.3744347296, 4026256.723716898, 4095827.9573665825, 4023631.9896559394, 4046751.9125588783, 3973758.674124694, 4081927.075527175, 3922485.387310559, 4001549.2805312183, 4050417.849670596, 3987607.4531957353, 4060206.9664999805, 4080316.8473846694, 4030455.1532406537, 4087714.965906726, 4028165.0792610054, 4032588.5261474997, 3980546.468460318, 4090408.033691761, 3990019.103297975, 4088755.998466496, 4092162.22327816, 4029036.6583707742, 4055066.505591603, 4081998.821392285, 4079550.553314541 ], "13": [ 3905319.849889843, 4054719.0660902266, 4055596.4319745116, 3992648.989962779, 3924972.5941170114, 4095167.7814041013, 3912740.1944122575, 4024882.9438952096, 4023171.3988155797, 4059892.954049364, 4068510.96886605, 4093838.431690223, 4070524.1327491063 ], "14": [ 4092261.8249403643, 3956304.3865069468, 4069053.2302732924, 4038890.8473817194 ], "15": [ 4013891.110502415, 3977489.9532032954, 4044335.989753631, 4066199.8081775964 ], "16": [ 3979706.1687804307, 4024156.037977316 ], "17": [] }
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | /* Visit https://aka.ms/tsconfig to read more about this file */
4 |
5 | /* Projects */
6 | // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */
7 | // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */
8 | // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */
9 | // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */
10 | // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */
11 | // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */
12 |
13 | /* Language and Environment */
14 | "target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
15 | // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
16 | // "jsx": "preserve", /* Specify what JSX code is generated. */
17 | // "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */
18 | // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */
19 | // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */
20 | // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */
21 | // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */
22 | // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */
23 | // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */
24 | // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */
25 | // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */
26 |
27 | /* Modules */
28 | "module": "commonjs", /* Specify what module code is generated. */
29 | // "rootDir": "./", /* Specify the root folder within your source files. */
30 | // "moduleResolution": "node10", /* Specify how TypeScript looks up a file from a given module specifier. */
31 | // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
32 | // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */
33 | // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */
34 | // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */
35 | // "types": [], /* Specify type package names to be included without being referenced in a source file. */
36 | // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
37 | // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */
38 | // "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */
39 | // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */
40 | // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */
41 | // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */
42 | // "resolveJsonModule": true, /* Enable importing .json files. */
43 | // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */
44 | // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */
45 |
46 | /* JavaScript Support */
47 | // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */
48 | // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */
49 | // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */
50 |
51 | /* Emit */
52 | // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
53 | // "declarationMap": true, /* Create sourcemaps for d.ts files. */
54 | // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */
55 | // "sourceMap": true, /* Create source map files for emitted JavaScript files. */
56 | // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */
57 | // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */
58 | // "outDir": "./", /* Specify an output folder for all emitted files. */
59 | // "removeComments": true, /* Disable emitting comments. */
60 | // "noEmit": true, /* Disable emitting files from a compilation. */
61 | // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */
62 | // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */
63 | // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */
64 | // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */
65 | // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
66 | // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */
67 | // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */
68 | // "newLine": "crlf", /* Set the newline character for emitting files. */
69 | // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */
70 | // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */
71 | // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */
72 | // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */
73 | // "declarationDir": "./", /* Specify the output directory for generated declaration files. */
74 | // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */
75 |
76 | /* Interop Constraints */
77 | // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
78 | // "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */
79 | // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */
80 | "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */
81 | // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */
82 | "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */
83 |
84 | /* Type Checking */
85 | "strict": true, /* Enable all strict type-checking options. */
86 | // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */
87 | // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */
88 | // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */
89 | // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */
90 | // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */
91 | // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */
92 | // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */
93 | // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */
94 | // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */
95 | // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */
96 | // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */
97 | // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */
98 | // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */
99 | // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */
100 | // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */
101 | // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */
102 | // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */
103 | // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */
104 |
105 | /* Completeness */
106 | // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */
107 | "skipLibCheck": true /* Skip type checking all .d.ts files. */
108 | }
109 | }
110 |
--------------------------------------------------------------------------------
/backend/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | /* Visit https://aka.ms/tsconfig to read more about this file */
4 |
5 | /* Projects */
6 | // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */
7 | // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */
8 | // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */
9 | // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */
10 | // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */
11 | // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */
12 |
13 | /* Language and Environment */
14 | "target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
15 | // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
16 | // "jsx": "preserve", /* Specify what JSX code is generated. */
17 | // "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */
18 | // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */
19 | // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */
20 | // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */
21 | // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */
22 | // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */
23 | // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */
24 | // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */
25 | // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */
26 |
27 | /* Modules */
28 | "module": "commonjs", /* Specify what module code is generated. */
29 | "rootDir": "./src", /* Specify the root folder within your source files. */
30 | // "moduleResolution": "node10", /* Specify how TypeScript looks up a file from a given module specifier. */
31 | // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
32 | // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */
33 | // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */
34 | // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */
35 | // "types": [], /* Specify type package names to be included without being referenced in a source file. */
36 | // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
37 | // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */
38 | // "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */
39 | // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */
40 | // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */
41 | // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */
42 | // "resolveJsonModule": true, /* Enable importing .json files. */
43 | // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */
44 | // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */
45 |
46 | /* JavaScript Support */
47 | // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */
48 | // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */
49 | // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */
50 |
51 | /* Emit */
52 | // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
53 | // "declarationMap": true, /* Create sourcemaps for d.ts files. */
54 | // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */
55 | // "sourceMap": true, /* Create source map files for emitted JavaScript files. */
56 | // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */
57 | // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */
58 | "outDir": "./dist", /* Specify an output folder for all emitted files. */
59 | // "removeComments": true, /* Disable emitting comments. */
60 | // "noEmit": true, /* Disable emitting files from a compilation. */
61 | // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */
62 | // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */
63 | // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */
64 | // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */
65 | // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
66 | // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */
67 | // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */
68 | // "newLine": "crlf", /* Set the newline character for emitting files. */
69 | // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */
70 | // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */
71 | // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */
72 | // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */
73 | // "declarationDir": "./", /* Specify the output directory for generated declaration files. */
74 | // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */
75 |
76 | /* Interop Constraints */
77 | // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
78 | // "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */
79 | // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */
80 | "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */
81 | // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */
82 | "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */
83 |
84 | /* Type Checking */
85 | "strict": true, /* Enable all strict type-checking options. */
86 | // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */
87 | // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */
88 | // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */
89 | // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */
90 | // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */
91 | // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */
92 | // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */
93 | // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */
94 | // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */
95 | // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */
96 | // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */
97 | // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */
98 | // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */
99 | // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */
100 | // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */
101 | // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */
102 | // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */
103 | // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */
104 |
105 | /* Completeness */
106 | // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */
107 | "skipLibCheck": true /* Skip type checking all .d.ts files. */
108 | }
109 | }
110 |
--------------------------------------------------------------------------------
/backend/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "backend",
3 | "version": "1.0.0",
4 | "lockfileVersion": 3,
5 | "requires": true,
6 | "packages": {
7 | "": {
8 | "name": "backend",
9 | "version": "1.0.0",
10 | "license": "ISC",
11 | "dependencies": {
12 | "@types/cors": "^2.8.17",
13 | "@types/express": "^4.17.21",
14 | "cors": "^2.8.5",
15 | "express": "^4.19.2"
16 | }
17 | },
18 | "node_modules/@types/body-parser": {
19 | "version": "1.19.5",
20 | "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz",
21 | "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==",
22 | "dependencies": {
23 | "@types/connect": "*",
24 | "@types/node": "*"
25 | }
26 | },
27 | "node_modules/@types/connect": {
28 | "version": "3.4.38",
29 | "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz",
30 | "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==",
31 | "dependencies": {
32 | "@types/node": "*"
33 | }
34 | },
35 | "node_modules/@types/cors": {
36 | "version": "2.8.17",
37 | "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.17.tgz",
38 | "integrity": "sha512-8CGDvrBj1zgo2qE+oS3pOCyYNqCPryMWY2bGfwA0dcfopWGgxs+78df0Rs3rc9THP4JkOhLsAa+15VdpAqkcUA==",
39 | "dependencies": {
40 | "@types/node": "*"
41 | }
42 | },
43 | "node_modules/@types/express": {
44 | "version": "4.17.21",
45 | "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz",
46 | "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==",
47 | "dependencies": {
48 | "@types/body-parser": "*",
49 | "@types/express-serve-static-core": "^4.17.33",
50 | "@types/qs": "*",
51 | "@types/serve-static": "*"
52 | }
53 | },
54 | "node_modules/@types/express-serve-static-core": {
55 | "version": "4.19.0",
56 | "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.0.tgz",
57 | "integrity": "sha512-bGyep3JqPCRry1wq+O5n7oiBgGWmeIJXPjXXCo8EK0u8duZGSYar7cGqd3ML2JUsLGeB7fmc06KYo9fLGWqPvQ==",
58 | "dependencies": {
59 | "@types/node": "*",
60 | "@types/qs": "*",
61 | "@types/range-parser": "*",
62 | "@types/send": "*"
63 | }
64 | },
65 | "node_modules/@types/http-errors": {
66 | "version": "2.0.4",
67 | "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz",
68 | "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA=="
69 | },
70 | "node_modules/@types/mime": {
71 | "version": "1.3.5",
72 | "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz",
73 | "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w=="
74 | },
75 | "node_modules/@types/node": {
76 | "version": "20.12.12",
77 | "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.12.tgz",
78 | "integrity": "sha512-eWLDGF/FOSPtAvEqeRAQ4C8LSA7M1I7i0ky1I8U7kD1J5ITyW3AsRhQrKVoWf5pFKZ2kILsEGJhsI9r93PYnOw==",
79 | "dependencies": {
80 | "undici-types": "~5.26.4"
81 | }
82 | },
83 | "node_modules/@types/qs": {
84 | "version": "6.9.15",
85 | "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.15.tgz",
86 | "integrity": "sha512-uXHQKES6DQKKCLh441Xv/dwxOq1TVS3JPUMlEqoEglvlhR6Mxnlew/Xq/LRVHpLyk7iK3zODe1qYHIMltO7XGg=="
87 | },
88 | "node_modules/@types/range-parser": {
89 | "version": "1.2.7",
90 | "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz",
91 | "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ=="
92 | },
93 | "node_modules/@types/send": {
94 | "version": "0.17.4",
95 | "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz",
96 | "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==",
97 | "dependencies": {
98 | "@types/mime": "^1",
99 | "@types/node": "*"
100 | }
101 | },
102 | "node_modules/@types/serve-static": {
103 | "version": "1.15.7",
104 | "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.7.tgz",
105 | "integrity": "sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==",
106 | "dependencies": {
107 | "@types/http-errors": "*",
108 | "@types/node": "*",
109 | "@types/send": "*"
110 | }
111 | },
112 | "node_modules/accepts": {
113 | "version": "1.3.8",
114 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
115 | "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==",
116 | "dependencies": {
117 | "mime-types": "~2.1.34",
118 | "negotiator": "0.6.3"
119 | },
120 | "engines": {
121 | "node": ">= 0.6"
122 | }
123 | },
124 | "node_modules/array-flatten": {
125 | "version": "1.1.1",
126 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
127 | "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg=="
128 | },
129 | "node_modules/body-parser": {
130 | "version": "1.20.2",
131 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz",
132 | "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==",
133 | "dependencies": {
134 | "bytes": "3.1.2",
135 | "content-type": "~1.0.5",
136 | "debug": "2.6.9",
137 | "depd": "2.0.0",
138 | "destroy": "1.2.0",
139 | "http-errors": "2.0.0",
140 | "iconv-lite": "0.4.24",
141 | "on-finished": "2.4.1",
142 | "qs": "6.11.0",
143 | "raw-body": "2.5.2",
144 | "type-is": "~1.6.18",
145 | "unpipe": "1.0.0"
146 | },
147 | "engines": {
148 | "node": ">= 0.8",
149 | "npm": "1.2.8000 || >= 1.4.16"
150 | }
151 | },
152 | "node_modules/bytes": {
153 | "version": "3.1.2",
154 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
155 | "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
156 | "engines": {
157 | "node": ">= 0.8"
158 | }
159 | },
160 | "node_modules/call-bind": {
161 | "version": "1.0.7",
162 | "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz",
163 | "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==",
164 | "dependencies": {
165 | "es-define-property": "^1.0.0",
166 | "es-errors": "^1.3.0",
167 | "function-bind": "^1.1.2",
168 | "get-intrinsic": "^1.2.4",
169 | "set-function-length": "^1.2.1"
170 | },
171 | "engines": {
172 | "node": ">= 0.4"
173 | },
174 | "funding": {
175 | "url": "https://github.com/sponsors/ljharb"
176 | }
177 | },
178 | "node_modules/content-disposition": {
179 | "version": "0.5.4",
180 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
181 | "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==",
182 | "dependencies": {
183 | "safe-buffer": "5.2.1"
184 | },
185 | "engines": {
186 | "node": ">= 0.6"
187 | }
188 | },
189 | "node_modules/content-type": {
190 | "version": "1.0.5",
191 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz",
192 | "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==",
193 | "engines": {
194 | "node": ">= 0.6"
195 | }
196 | },
197 | "node_modules/cookie": {
198 | "version": "0.6.0",
199 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz",
200 | "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==",
201 | "engines": {
202 | "node": ">= 0.6"
203 | }
204 | },
205 | "node_modules/cookie-signature": {
206 | "version": "1.0.6",
207 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
208 | "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ=="
209 | },
210 | "node_modules/cors": {
211 | "version": "2.8.5",
212 | "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
213 | "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
214 | "dependencies": {
215 | "object-assign": "^4",
216 | "vary": "^1"
217 | },
218 | "engines": {
219 | "node": ">= 0.10"
220 | }
221 | },
222 | "node_modules/debug": {
223 | "version": "2.6.9",
224 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
225 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
226 | "dependencies": {
227 | "ms": "2.0.0"
228 | }
229 | },
230 | "node_modules/define-data-property": {
231 | "version": "1.1.4",
232 | "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz",
233 | "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==",
234 | "dependencies": {
235 | "es-define-property": "^1.0.0",
236 | "es-errors": "^1.3.0",
237 | "gopd": "^1.0.1"
238 | },
239 | "engines": {
240 | "node": ">= 0.4"
241 | },
242 | "funding": {
243 | "url": "https://github.com/sponsors/ljharb"
244 | }
245 | },
246 | "node_modules/depd": {
247 | "version": "2.0.0",
248 | "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
249 | "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
250 | "engines": {
251 | "node": ">= 0.8"
252 | }
253 | },
254 | "node_modules/destroy": {
255 | "version": "1.2.0",
256 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz",
257 | "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==",
258 | "engines": {
259 | "node": ">= 0.8",
260 | "npm": "1.2.8000 || >= 1.4.16"
261 | }
262 | },
263 | "node_modules/ee-first": {
264 | "version": "1.1.1",
265 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
266 | "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="
267 | },
268 | "node_modules/encodeurl": {
269 | "version": "1.0.2",
270 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
271 | "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==",
272 | "engines": {
273 | "node": ">= 0.8"
274 | }
275 | },
276 | "node_modules/es-define-property": {
277 | "version": "1.0.0",
278 | "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz",
279 | "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==",
280 | "dependencies": {
281 | "get-intrinsic": "^1.2.4"
282 | },
283 | "engines": {
284 | "node": ">= 0.4"
285 | }
286 | },
287 | "node_modules/es-errors": {
288 | "version": "1.3.0",
289 | "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
290 | "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
291 | "engines": {
292 | "node": ">= 0.4"
293 | }
294 | },
295 | "node_modules/escape-html": {
296 | "version": "1.0.3",
297 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
298 | "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow=="
299 | },
300 | "node_modules/etag": {
301 | "version": "1.8.1",
302 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
303 | "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==",
304 | "engines": {
305 | "node": ">= 0.6"
306 | }
307 | },
308 | "node_modules/express": {
309 | "version": "4.19.2",
310 | "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz",
311 | "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==",
312 | "dependencies": {
313 | "accepts": "~1.3.8",
314 | "array-flatten": "1.1.1",
315 | "body-parser": "1.20.2",
316 | "content-disposition": "0.5.4",
317 | "content-type": "~1.0.4",
318 | "cookie": "0.6.0",
319 | "cookie-signature": "1.0.6",
320 | "debug": "2.6.9",
321 | "depd": "2.0.0",
322 | "encodeurl": "~1.0.2",
323 | "escape-html": "~1.0.3",
324 | "etag": "~1.8.1",
325 | "finalhandler": "1.2.0",
326 | "fresh": "0.5.2",
327 | "http-errors": "2.0.0",
328 | "merge-descriptors": "1.0.1",
329 | "methods": "~1.1.2",
330 | "on-finished": "2.4.1",
331 | "parseurl": "~1.3.3",
332 | "path-to-regexp": "0.1.7",
333 | "proxy-addr": "~2.0.7",
334 | "qs": "6.11.0",
335 | "range-parser": "~1.2.1",
336 | "safe-buffer": "5.2.1",
337 | "send": "0.18.0",
338 | "serve-static": "1.15.0",
339 | "setprototypeof": "1.2.0",
340 | "statuses": "2.0.1",
341 | "type-is": "~1.6.18",
342 | "utils-merge": "1.0.1",
343 | "vary": "~1.1.2"
344 | },
345 | "engines": {
346 | "node": ">= 0.10.0"
347 | }
348 | },
349 | "node_modules/finalhandler": {
350 | "version": "1.2.0",
351 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz",
352 | "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==",
353 | "dependencies": {
354 | "debug": "2.6.9",
355 | "encodeurl": "~1.0.2",
356 | "escape-html": "~1.0.3",
357 | "on-finished": "2.4.1",
358 | "parseurl": "~1.3.3",
359 | "statuses": "2.0.1",
360 | "unpipe": "~1.0.0"
361 | },
362 | "engines": {
363 | "node": ">= 0.8"
364 | }
365 | },
366 | "node_modules/forwarded": {
367 | "version": "0.2.0",
368 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
369 | "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==",
370 | "engines": {
371 | "node": ">= 0.6"
372 | }
373 | },
374 | "node_modules/fresh": {
375 | "version": "0.5.2",
376 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
377 | "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==",
378 | "engines": {
379 | "node": ">= 0.6"
380 | }
381 | },
382 | "node_modules/function-bind": {
383 | "version": "1.1.2",
384 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
385 | "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
386 | "funding": {
387 | "url": "https://github.com/sponsors/ljharb"
388 | }
389 | },
390 | "node_modules/get-intrinsic": {
391 | "version": "1.2.4",
392 | "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz",
393 | "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==",
394 | "dependencies": {
395 | "es-errors": "^1.3.0",
396 | "function-bind": "^1.1.2",
397 | "has-proto": "^1.0.1",
398 | "has-symbols": "^1.0.3",
399 | "hasown": "^2.0.0"
400 | },
401 | "engines": {
402 | "node": ">= 0.4"
403 | },
404 | "funding": {
405 | "url": "https://github.com/sponsors/ljharb"
406 | }
407 | },
408 | "node_modules/gopd": {
409 | "version": "1.0.1",
410 | "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz",
411 | "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==",
412 | "dependencies": {
413 | "get-intrinsic": "^1.1.3"
414 | },
415 | "funding": {
416 | "url": "https://github.com/sponsors/ljharb"
417 | }
418 | },
419 | "node_modules/has-property-descriptors": {
420 | "version": "1.0.2",
421 | "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz",
422 | "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==",
423 | "dependencies": {
424 | "es-define-property": "^1.0.0"
425 | },
426 | "funding": {
427 | "url": "https://github.com/sponsors/ljharb"
428 | }
429 | },
430 | "node_modules/has-proto": {
431 | "version": "1.0.3",
432 | "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz",
433 | "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==",
434 | "engines": {
435 | "node": ">= 0.4"
436 | },
437 | "funding": {
438 | "url": "https://github.com/sponsors/ljharb"
439 | }
440 | },
441 | "node_modules/has-symbols": {
442 | "version": "1.0.3",
443 | "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
444 | "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
445 | "engines": {
446 | "node": ">= 0.4"
447 | },
448 | "funding": {
449 | "url": "https://github.com/sponsors/ljharb"
450 | }
451 | },
452 | "node_modules/hasown": {
453 | "version": "2.0.2",
454 | "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
455 | "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
456 | "dependencies": {
457 | "function-bind": "^1.1.2"
458 | },
459 | "engines": {
460 | "node": ">= 0.4"
461 | }
462 | },
463 | "node_modules/http-errors": {
464 | "version": "2.0.0",
465 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
466 | "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==",
467 | "dependencies": {
468 | "depd": "2.0.0",
469 | "inherits": "2.0.4",
470 | "setprototypeof": "1.2.0",
471 | "statuses": "2.0.1",
472 | "toidentifier": "1.0.1"
473 | },
474 | "engines": {
475 | "node": ">= 0.8"
476 | }
477 | },
478 | "node_modules/iconv-lite": {
479 | "version": "0.4.24",
480 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
481 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
482 | "dependencies": {
483 | "safer-buffer": ">= 2.1.2 < 3"
484 | },
485 | "engines": {
486 | "node": ">=0.10.0"
487 | }
488 | },
489 | "node_modules/inherits": {
490 | "version": "2.0.4",
491 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
492 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
493 | },
494 | "node_modules/ipaddr.js": {
495 | "version": "1.9.1",
496 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
497 | "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
498 | "engines": {
499 | "node": ">= 0.10"
500 | }
501 | },
502 | "node_modules/media-typer": {
503 | "version": "0.3.0",
504 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
505 | "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==",
506 | "engines": {
507 | "node": ">= 0.6"
508 | }
509 | },
510 | "node_modules/merge-descriptors": {
511 | "version": "1.0.1",
512 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
513 | "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w=="
514 | },
515 | "node_modules/methods": {
516 | "version": "1.1.2",
517 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
518 | "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==",
519 | "engines": {
520 | "node": ">= 0.6"
521 | }
522 | },
523 | "node_modules/mime": {
524 | "version": "1.6.0",
525 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
526 | "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
527 | "bin": {
528 | "mime": "cli.js"
529 | },
530 | "engines": {
531 | "node": ">=4"
532 | }
533 | },
534 | "node_modules/mime-db": {
535 | "version": "1.52.0",
536 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
537 | "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
538 | "engines": {
539 | "node": ">= 0.6"
540 | }
541 | },
542 | "node_modules/mime-types": {
543 | "version": "2.1.35",
544 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
545 | "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
546 | "dependencies": {
547 | "mime-db": "1.52.0"
548 | },
549 | "engines": {
550 | "node": ">= 0.6"
551 | }
552 | },
553 | "node_modules/ms": {
554 | "version": "2.0.0",
555 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
556 | "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
557 | },
558 | "node_modules/negotiator": {
559 | "version": "0.6.3",
560 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
561 | "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==",
562 | "engines": {
563 | "node": ">= 0.6"
564 | }
565 | },
566 | "node_modules/object-assign": {
567 | "version": "4.1.1",
568 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
569 | "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
570 | "engines": {
571 | "node": ">=0.10.0"
572 | }
573 | },
574 | "node_modules/object-inspect": {
575 | "version": "1.13.1",
576 | "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz",
577 | "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==",
578 | "funding": {
579 | "url": "https://github.com/sponsors/ljharb"
580 | }
581 | },
582 | "node_modules/on-finished": {
583 | "version": "2.4.1",
584 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
585 | "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
586 | "dependencies": {
587 | "ee-first": "1.1.1"
588 | },
589 | "engines": {
590 | "node": ">= 0.8"
591 | }
592 | },
593 | "node_modules/parseurl": {
594 | "version": "1.3.3",
595 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
596 | "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
597 | "engines": {
598 | "node": ">= 0.8"
599 | }
600 | },
601 | "node_modules/path-to-regexp": {
602 | "version": "0.1.7",
603 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
604 | "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ=="
605 | },
606 | "node_modules/proxy-addr": {
607 | "version": "2.0.7",
608 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
609 | "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
610 | "dependencies": {
611 | "forwarded": "0.2.0",
612 | "ipaddr.js": "1.9.1"
613 | },
614 | "engines": {
615 | "node": ">= 0.10"
616 | }
617 | },
618 | "node_modules/qs": {
619 | "version": "6.11.0",
620 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz",
621 | "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==",
622 | "dependencies": {
623 | "side-channel": "^1.0.4"
624 | },
625 | "engines": {
626 | "node": ">=0.6"
627 | },
628 | "funding": {
629 | "url": "https://github.com/sponsors/ljharb"
630 | }
631 | },
632 | "node_modules/range-parser": {
633 | "version": "1.2.1",
634 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
635 | "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
636 | "engines": {
637 | "node": ">= 0.6"
638 | }
639 | },
640 | "node_modules/raw-body": {
641 | "version": "2.5.2",
642 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz",
643 | "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==",
644 | "dependencies": {
645 | "bytes": "3.1.2",
646 | "http-errors": "2.0.0",
647 | "iconv-lite": "0.4.24",
648 | "unpipe": "1.0.0"
649 | },
650 | "engines": {
651 | "node": ">= 0.8"
652 | }
653 | },
654 | "node_modules/safe-buffer": {
655 | "version": "5.2.1",
656 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
657 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
658 | "funding": [
659 | {
660 | "type": "github",
661 | "url": "https://github.com/sponsors/feross"
662 | },
663 | {
664 | "type": "patreon",
665 | "url": "https://www.patreon.com/feross"
666 | },
667 | {
668 | "type": "consulting",
669 | "url": "https://feross.org/support"
670 | }
671 | ]
672 | },
673 | "node_modules/safer-buffer": {
674 | "version": "2.1.2",
675 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
676 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
677 | },
678 | "node_modules/send": {
679 | "version": "0.18.0",
680 | "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz",
681 | "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==",
682 | "dependencies": {
683 | "debug": "2.6.9",
684 | "depd": "2.0.0",
685 | "destroy": "1.2.0",
686 | "encodeurl": "~1.0.2",
687 | "escape-html": "~1.0.3",
688 | "etag": "~1.8.1",
689 | "fresh": "0.5.2",
690 | "http-errors": "2.0.0",
691 | "mime": "1.6.0",
692 | "ms": "2.1.3",
693 | "on-finished": "2.4.1",
694 | "range-parser": "~1.2.1",
695 | "statuses": "2.0.1"
696 | },
697 | "engines": {
698 | "node": ">= 0.8.0"
699 | }
700 | },
701 | "node_modules/send/node_modules/ms": {
702 | "version": "2.1.3",
703 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
704 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
705 | },
706 | "node_modules/serve-static": {
707 | "version": "1.15.0",
708 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz",
709 | "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==",
710 | "dependencies": {
711 | "encodeurl": "~1.0.2",
712 | "escape-html": "~1.0.3",
713 | "parseurl": "~1.3.3",
714 | "send": "0.18.0"
715 | },
716 | "engines": {
717 | "node": ">= 0.8.0"
718 | }
719 | },
720 | "node_modules/set-function-length": {
721 | "version": "1.2.2",
722 | "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz",
723 | "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==",
724 | "dependencies": {
725 | "define-data-property": "^1.1.4",
726 | "es-errors": "^1.3.0",
727 | "function-bind": "^1.1.2",
728 | "get-intrinsic": "^1.2.4",
729 | "gopd": "^1.0.1",
730 | "has-property-descriptors": "^1.0.2"
731 | },
732 | "engines": {
733 | "node": ">= 0.4"
734 | }
735 | },
736 | "node_modules/setprototypeof": {
737 | "version": "1.2.0",
738 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
739 | "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="
740 | },
741 | "node_modules/side-channel": {
742 | "version": "1.0.6",
743 | "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz",
744 | "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==",
745 | "dependencies": {
746 | "call-bind": "^1.0.7",
747 | "es-errors": "^1.3.0",
748 | "get-intrinsic": "^1.2.4",
749 | "object-inspect": "^1.13.1"
750 | },
751 | "engines": {
752 | "node": ">= 0.4"
753 | },
754 | "funding": {
755 | "url": "https://github.com/sponsors/ljharb"
756 | }
757 | },
758 | "node_modules/statuses": {
759 | "version": "2.0.1",
760 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
761 | "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
762 | "engines": {
763 | "node": ">= 0.8"
764 | }
765 | },
766 | "node_modules/toidentifier": {
767 | "version": "1.0.1",
768 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
769 | "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
770 | "engines": {
771 | "node": ">=0.6"
772 | }
773 | },
774 | "node_modules/type-is": {
775 | "version": "1.6.18",
776 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
777 | "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
778 | "dependencies": {
779 | "media-typer": "0.3.0",
780 | "mime-types": "~2.1.24"
781 | },
782 | "engines": {
783 | "node": ">= 0.6"
784 | }
785 | },
786 | "node_modules/undici-types": {
787 | "version": "5.26.5",
788 | "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
789 | "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="
790 | },
791 | "node_modules/unpipe": {
792 | "version": "1.0.0",
793 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
794 | "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==",
795 | "engines": {
796 | "node": ">= 0.8"
797 | }
798 | },
799 | "node_modules/utils-merge": {
800 | "version": "1.0.1",
801 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
802 | "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==",
803 | "engines": {
804 | "node": ">= 0.4.0"
805 | }
806 | },
807 | "node_modules/vary": {
808 | "version": "1.1.2",
809 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
810 | "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==",
811 | "engines": {
812 | "node": ">= 0.8"
813 | }
814 | }
815 | }
816 | }
817 |
--------------------------------------------------------------------------------