diff --git a/assets/image/Lastwar.png b/assets/image/Lastwar.png new file mode 100644 index 000000000..212f07439 Binary files /dev/null and b/assets/image/Lastwar.png differ diff --git "a/assets/image/M\303\243_QR.png" "b/assets/image/M\303\243_QR.png" new file mode 100644 index 000000000..6a1405a66 Binary files /dev/null and "b/assets/image/M\303\243_QR.png" differ diff --git a/assets/image/amazon_clone_card.jpeg b/assets/image/amazon_clone_card.jpeg new file mode 100644 index 000000000..1ed9e35ab Binary files /dev/null and b/assets/image/amazon_clone_card.jpeg differ diff --git a/assets/image/buildingblock.png b/assets/image/buildingblock.png new file mode 100644 index 000000000..ace88f446 Binary files /dev/null and b/assets/image/buildingblock.png differ diff --git a/assets/image/candy.png b/assets/image/candy.png new file mode 100644 index 000000000..9b2574a4f Binary files /dev/null and b/assets/image/candy.png differ diff --git a/assets/image/chat-7767693_1280.jpg b/assets/image/chat-7767693_1280.jpg new file mode 100644 index 000000000..fa4d62e73 Binary files /dev/null and b/assets/image/chat-7767693_1280.jpg differ diff --git a/assets/image/spaceinvade.png b/assets/image/spaceinvade.png new file mode 100644 index 000000000..342ee4ed3 Binary files /dev/null and b/assets/image/spaceinvade.png differ diff --git a/assets/image/supermario.png b/assets/image/supermario.png new file mode 100644 index 000000000..e7e31219d Binary files /dev/null and b/assets/image/supermario.png differ diff --git a/assets/image/tiltingmaze.png b/assets/image/tiltingmaze.png new file mode 100644 index 000000000..7e4e9b293 Binary files /dev/null and b/assets/image/tiltingmaze.png differ diff --git a/assets/image/traintrack.png b/assets/image/traintrack.png new file mode 100644 index 000000000..be0ec6a1e Binary files /dev/null and b/assets/image/traintrack.png differ diff --git a/assets/image/vp.jpg b/assets/image/vp.jpg new file mode 100644 index 000000000..934a63e8b Binary files /dev/null and b/assets/image/vp.jpg differ diff --git a/css/style.css b/css/style.css index e2ab53d7e..35bdcac77 100644 --- a/css/style.css +++ b/css/style.css @@ -82,6 +82,13 @@ body { padding: 1rem; } +/* Hover Effects for Project */ +.projects-container a:hover { + background-color: #f9cbd3; + transform: translateY(-6px); + transition: transform 0.3s ease, background-color 0.3s ease; + } + .card { background: var(--card); border-radius: 8px; diff --git a/index.html b/index.html index 6956d6c8b..af88332a5 100644 --- a/index.html +++ b/index.html @@ -62,6 +62,17 @@

Counter

+ +
+ +
+
+

Last War

+

+ Save the world by planting trees. +

+
+
@@ -431,7 +442,25 @@

Typing Speed Test

Test Your Speed on Typing

+ + + +
+
+ pet +
+
+

Virtual Pet Game

+

+ Adopt, care, and interact with virtual pets +

+
+
+ + + --> +
Rolling Triumph @@ -492,7 +521,10 @@

Dictionary

Dictionary app

-
+ + + +
@@ -514,7 +546,7 @@

Brick Breaker

A Brick Breaker Game.

-
+
@@ -535,7 +567,7 @@

TRIVIA

GeoQuest

- Explore the World, One Challenge at a Time!

+ Explore the World, One Challenge at a Time!

@@ -562,7 +594,7 @@

Whack a Mole

- +
@@ -575,6 +607,17 @@

Pokedex

+ +
+ Super Mario +
+
+

Super Mario

+

+ A Popular Game. +

+
+
@@ -660,14 +703,17 @@

Flappy Bird

- - - - - - - - + +
+ Candy Game +
+
+

Candy Game

+

+ A Candy game. +

+
+
Stick Hero @@ -679,7 +725,6 @@

Stick Hero

-
Among Us @@ -713,6 +758,28 @@

Doodle Jump

Enjoy and Jump.

+
+ +
+ Train Track Game +
+
+

Train Track Game

+

+ A Train Track Game which is created by Three Js. +

+
+
+ +
+ Building Block +
+
+

Building Block

+

+ A Building Block Game. +

+
@@ -746,6 +813,17 @@

Mole Bop

Catch the Bop.

+
+ +
+ Tilting Maze Game +
+
+

Tilting Maze Game

+

+ A Tilting Maze Game. +

+
@@ -758,6 +836,17 @@

Maze Game

+ +
+ Space Invader +
+
+

Space Invader

+

+ A fun Space Invader game. +

+
+
Virtual Keyboard' @@ -794,7 +883,31 @@

Tetris Game

+ +
+ Qr +
+
+

QR Generator

+

+ QR Generator using HTML, CSS & Js +

+
+
+ +
+ link tree icon +
+
+

Amazon clone

+

+ get the feeling of real developer +

+
+
+ +
@@ -807,7 +920,17 @@

Connect4(Two player)

- + +
+ a coin representing how to win the game +
+
+

Space Collision Game

+

+ Space Collision: Catch Coins and avoid Enemies to Score +

+
+
@@ -821,10 +944,21 @@

Piano

- - + +
+ chatbot +
+
+

Chatbot

+

+ A simple chatbot.
+ Please use your own google gemini api key for the chatbot to work. +

+
+
+ - + diff --git a/node_modules/.package-lock.json b/node_modules/.package-lock.json index dda6fdb12..a52231b65 100644 --- a/node_modules/.package-lock.json +++ b/node_modules/.package-lock.json @@ -266,6 +266,18 @@ "npm": "1.2.8000 || >= 1.4.16" } }, + "node_modules/dotenv": { + "version": "16.4.5", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz", + "integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", diff --git a/package-lock.json b/package-lock.json index e973e5209..70c056628 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,6 +10,7 @@ "license": "ISC", "dependencies": { "body-parser": "^1.20.3", + "dotenv": "^16.4.5", "ejs": "^3.1.10", "express": "^4.21.0", "mongoose": "^8.7.0" @@ -277,6 +278,18 @@ "npm": "1.2.8000 || >= 1.4.16" } }, + "node_modules/dotenv": { + "version": "16.4.5", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz", + "integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", diff --git a/package.json b/package.json index 538094b56..d41d3ce50 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,7 @@ "license": "ISC", "dependencies": { "body-parser": "^1.20.3", + "dotenv": "^16.4.5", "ejs": "^3.1.10", "express": "^4.21.0", "mongoose": "^8.7.0" diff --git a/projects/Building Block/index.html b/projects/Building Block/index.html new file mode 100644 index 000000000..18d0b262b --- /dev/null +++ b/projects/Building Block/index.html @@ -0,0 +1,28 @@ + + + + + + Building Block + + + + + +
+
+

Stack the blocks on top of each other

+

Click, tap or press Space when a block is above the stack. Can you reach the blue color blocks?

+

Click, tap or press Space to start game

+
+
+
+
+

You missed the block

+

To reset the game press R

+
+
+
0
+ + + \ No newline at end of file diff --git a/projects/Building Block/script.js b/projects/Building Block/script.js new file mode 100644 index 000000000..1265bd557 --- /dev/null +++ b/projects/Building Block/script.js @@ -0,0 +1,331 @@ +window.focus(); + +let camera, scene, renderer; // ThreeJS globals +let world; // CannonJs world +let lastTime; // Last timestamp of animation +let stack; // Parts that stay solid on top of each other +let overhangs; // Overhanging parts that fall down +const boxHeight = 1; // Height of each layer +const originalBoxSize = 3; // Original width and height of a box +let autopilot; +let gameEnded; +let robotPrecision; // Determines how precise the game is on autopilot + +const scoreElement = document.getElementById("score"); +const instructionsElement = document.getElementById("instructions"); +const resultsElement = document.getElementById("results"); + +init(); + +function setRobotPrecision() { + robotPrecision = Math.random() * 1 - 0.5; +} + +function init() { + autopilot = true; + gameEnded = false; + lastTime = 0; + stack = []; + overhangs = []; + setRobotPrecision(); + + // Initialize CannonJS + world = new CANNON.World(); + world.gravity.set(0, -10, 0); // Gravity pulls things down + world.broadphase = new CANNON.NaiveBroadphase(); + world.solver.iterations = 40; + + // Initialize ThreeJs + const aspect = window.innerWidth / window.innerHeight; + const width = 10; + const height = width / aspect; + + camera = new THREE.OrthographicCamera( + width / -2, // left + width / 2, // right + height / 2, // top + height / -2, // bottom + 0, // near plane + 100 // far plane + ); + + camera.position.set(4, 4, 4); + camera.lookAt(0, 0, 0); + + scene = new THREE.Scene(); + + // Foundation + addLayer(0, 0, originalBoxSize, originalBoxSize); + + // First layer + addLayer(-10, 0, originalBoxSize, originalBoxSize, "x"); + + // Set up lights + const ambientLight = new THREE.AmbientLight(0xffffff, 0.6); + scene.add(ambientLight); + + const dirLight = new THREE.DirectionalLight(0xffffff, 0.6); + dirLight.position.set(10, 20, 0); + scene.add(dirLight); + + // Set up renderer + renderer = new THREE.WebGLRenderer({ antialias: true }); + renderer.setSize(window.innerWidth, window.innerHeight); + renderer.setAnimationLoop(animation); + document.body.appendChild(renderer.domElement); +} + +function startGame() { + autopilot = false; + gameEnded = false; + lastTime = 0; + stack = []; + overhangs = []; + + if (instructionsElement) instructionsElement.style.display = "none"; + if (resultsElement) resultsElement.style.display = "none"; + if (scoreElement) scoreElement.innerText = 0; + + if (world) { + // Remove every object from world + while (world.bodies.length > 0) { + world.remove(world.bodies[0]); + } + } + + if (scene) { + // Remove every Mesh from the scene + while (scene.children.find((c) => c.type == "Mesh")) { + const mesh = scene.children.find((c) => c.type == "Mesh"); + scene.remove(mesh); + } + + // Foundation + addLayer(0, 0, originalBoxSize, originalBoxSize); + + // First layer + addLayer(-10, 0, originalBoxSize, originalBoxSize, "x"); + } + + if (camera) { + // Reset camera positions + camera.position.set(4, 4, 4); + camera.lookAt(0, 0, 0); + } +} + +function addLayer(x, z, width, depth, direction) { + const y = boxHeight * stack.length; // Add the new box one layer higher + const layer = generateBox(x, y, z, width, depth, false); + layer.direction = direction; + stack.push(layer); +} + +function addOverhang(x, z, width, depth) { + const y = boxHeight * (stack.length - 1); // Add the new box one the same layer + const overhang = generateBox(x, y, z, width, depth, true); + overhangs.push(overhang); +} + +function generateBox(x, y, z, width, depth, falls) { + // ThreeJS + const geometry = new THREE.BoxGeometry(width, boxHeight, depth); + const color = new THREE.Color(`hsl(${30 + stack.length * 4}, 100%, 50%)`); + const material = new THREE.MeshLambertMaterial({ color }); + const mesh = new THREE.Mesh(geometry, material); + mesh.position.set(x, y, z); + scene.add(mesh); + + // CannonJS + const shape = new CANNON.Box( + new CANNON.Vec3(width / 2, boxHeight / 2, depth / 2) + ); + let mass = falls ? 5 : 0; + mass *= width / originalBoxSize; + mass *= depth / originalBoxSize; + const body = new CANNON.Body({ mass, shape }); + body.position.set(x, y, z); + world.addBody(body); + + return { + threejs: mesh, + cannonjs: body, + width, + depth + }; +} + +function cutBox(topLayer, overlap, size, delta) { + const direction = topLayer.direction; + const newWidth = direction == "x" ? overlap : topLayer.width; + const newDepth = direction == "z" ? overlap : topLayer.depth; + + // Update metadata + topLayer.width = newWidth; + topLayer.depth = newDepth; + + // Update ThreeJS model + topLayer.threejs.scale[direction] = overlap / size; + topLayer.threejs.position[direction] -= delta / 2; + + // Update CannonJS model + topLayer.cannonjs.position[direction] -= delta / 2; + + const shape = new CANNON.Box( + new CANNON.Vec3(newWidth / 2, boxHeight / 2, newDepth / 2) + ); + topLayer.cannonjs.shapes = []; + topLayer.cannonjs.addShape(shape); +} + +window.addEventListener("mousedown", eventHandler); +window.addEventListener("touchstart", eventHandler); +window.addEventListener("keydown", function (event) { + if (event.key == " ") { + event.preventDefault(); + eventHandler(); + return; + } + if (event.key == "R" || event.key == "r") { + event.preventDefault(); + startGame(); + return; + } +}); + +function eventHandler() { + if (autopilot) startGame(); + else splitBlockAndAddNextOneIfOverlaps(); +} + +function splitBlockAndAddNextOneIfOverlaps() { + if (gameEnded) return; + + const topLayer = stack[stack.length - 1]; + const previousLayer = stack[stack.length - 2]; + + const direction = topLayer.direction; + + const size = direction == "x" ? topLayer.width : topLayer.depth; + const delta = + topLayer.threejs.position[direction] - + previousLayer.threejs.position[direction]; + const overhangSize = Math.abs(delta); + const overlap = size - overhangSize; + + if (overlap > 0) { + cutBox(topLayer, overlap, size, delta); + + // Overhang + const overhangShift = (overlap / 2 + overhangSize / 2) * Math.sign(delta); + const overhangX = + direction == "x" + ? topLayer.threejs.position.x + overhangShift + : topLayer.threejs.position.x; + const overhangZ = + direction == "z" + ? topLayer.threejs.position.z + overhangShift + : topLayer.threejs.position.z; + const overhangWidth = direction == "x" ? overhangSize : topLayer.width; + const overhangDepth = direction == "z" ? overhangSize : topLayer.depth; + + addOverhang(overhangX, overhangZ, overhangWidth, overhangDepth); + + // Next layer + const nextX = direction == "x" ? topLayer.threejs.position.x : -10; + const nextZ = direction == "z" ? topLayer.threejs.position.z : -10; + const newWidth = topLayer.width; // New layer has the same size as the cut top layer + const newDepth = topLayer.depth; // New layer has the same size as the cut top layer + const nextDirection = direction == "x" ? "z" : "x"; + + if (scoreElement) scoreElement.innerText = stack.length - 1; + addLayer(nextX, nextZ, newWidth, newDepth, nextDirection); + } else { + missedTheSpot(); + } +} + +function missedTheSpot() { + const topLayer = stack[stack.length - 1]; + + // Turn to top layer into an overhang and let it fall down + addOverhang( + topLayer.threejs.position.x, + topLayer.threejs.position.z, + topLayer.width, + topLayer.depth + ); + world.remove(topLayer.cannonjs); + scene.remove(topLayer.threejs); + + gameEnded = true; + if (resultsElement && !autopilot) resultsElement.style.display = "flex"; +} + +function animation(time) { + if (lastTime) { + const timePassed = time - lastTime; + const speed = 0.008; + + const topLayer = stack[stack.length - 1]; + const previousLayer = stack[stack.length - 2]; + + const boxShouldMove = + !gameEnded && + (!autopilot || + (autopilot && + topLayer.threejs.position[topLayer.direction] < + previousLayer.threejs.position[topLayer.direction] + + robotPrecision)); + + if (boxShouldMove) { + // Keep the position visible on UI and the position in the model in sync + topLayer.threejs.position[topLayer.direction] += speed * timePassed; + topLayer.cannonjs.position[topLayer.direction] += speed * timePassed; + + // If the box went beyond the stack then show up the fail screen + if (topLayer.threejs.position[topLayer.direction] > 10) { + missedTheSpot(); + } + } else { + if (autopilot) { + splitBlockAndAddNextOneIfOverlaps(); + setRobotPrecision(); + } + } + + // 4 is the initial camera height + if (camera.position.y < boxHeight * (stack.length - 2) + 4) { + camera.position.y += speed * timePassed; + } + + updatePhysics(timePassed); + renderer.render(scene, camera); + } + lastTime = time; +} + +function updatePhysics(timePassed) { + world.step(timePassed / 1000); // Step the physics world + + // Copy coordinates from Cannon.js to Three.js + overhangs.forEach((element) => { + element.threejs.position.copy(element.cannonjs.position); + element.threejs.quaternion.copy(element.cannonjs.quaternion); + }); +} + +window.addEventListener("resize", () => { + // Adjust camera + console.log("resize", window.innerWidth, window.innerHeight); + const aspect = window.innerWidth / window.innerHeight; + const width = 10; + const height = width / aspect; + + camera.top = height / 2; + camera.bottom = height / -2; + + // Reset renderer + renderer.setSize(window.innerWidth, window.innerHeight); + renderer.render(scene, camera); +}); diff --git a/projects/Building Block/style.css b/projects/Building Block/style.css new file mode 100644 index 000000000..cda966f13 --- /dev/null +++ b/projects/Building Block/style.css @@ -0,0 +1,48 @@ +@import url("https://fonts.googleapis.com/css2?family=Montserrat:wght@900&display=swap"); + +body { + margin: 0; + color: white; + font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif; + cursor: pointer; +} + +#instructions { + display: none; +} + +#results, +body:hover #instructions { + position: absolute; + display: flex; + align-items: center; + justify-content: center; + height: 100%; + width: 100%; + background-color: rgba(20, 20, 20, 0.75); +} + +a:visited { + color: inherit; +} + +#results { + display: none; + cursor: default; +} + +#results .content, +#instructions .content { + max-width: 300px; + padding: 50px; + border-radius: 20px; +} + +#score { + position: absolute; + color: white; + font-size: 3em; + font-weight: bold; + top: 30px; + right: 30px; +} \ No newline at end of file diff --git a/projects/Candy Game/background.jpg b/projects/Candy Game/background.jpg new file mode 100644 index 000000000..4115b1105 Binary files /dev/null and b/projects/Candy Game/background.jpg differ diff --git a/projects/Candy Game/candy.css b/projects/Candy Game/candy.css new file mode 100644 index 000000000..6182b55b6 --- /dev/null +++ b/projects/Candy Game/candy.css @@ -0,0 +1,23 @@ +body { + background: url("./background.jpg") no-repeat center center fixed; + background-size: cover; + font-family: Arial, Helvetica, sans-serif; + color: white; + text-align: center; +} + +#board { + width: 450px; + height: 450px; + background-color: lightblue; + border: 5px solid slategray; + border-radius: 10px; + margin: 0 auto; + display: flex; + flex-wrap: wrap; +} + +#board img { + width: 50px; + height: 50px; +} \ No newline at end of file diff --git a/projects/Candy Game/candy.js b/projects/Candy Game/candy.js new file mode 100644 index 000000000..329b673b1 --- /dev/null +++ b/projects/Candy Game/candy.js @@ -0,0 +1,204 @@ + +var candies = ["Blue", "Orange", "Green", "Yellow", "Red", "Purple"]; +var board = []; +var rows = 9; +var columns = 9; +var score = 0; + +var currTile; +var otherTile; + + +window.onload = function() { + startGame(); + + //1/10th of a second + window.setInterval(function(){ + crushCandy(); + slideCandy(); + generateCandy(); + }, 100); +} + +function randomCandy() { + return candies[Math.floor(Math.random() * candies.length)]; //0 - 5.99 +} + +function startGame() { + for (let r = 0; r < rows; r++) { + let row = []; + for (let c = 0; c < columns; c++) { + // + let tile = document.createElement("img"); + tile.id = r.toString() + "-" + c.toString(); + tile.src = "./images/" + randomCandy() + ".png"; + + //DRAG FUNCTIONALITY + tile.addEventListener("dragstart", dragStart); //click on a candy, initialize drag process + tile.addEventListener("dragover", dragOver); //clicking on candy, moving mouse to drag the candy + tile.addEventListener("dragenter", dragEnter); //dragging candy onto another candy + tile.addEventListener("dragleave", dragLeave); //leave candy over another candy + tile.addEventListener("drop", dragDrop); //dropping a candy over another candy + tile.addEventListener("dragend", dragEnd); //after drag process completed, we swap candies + + document.getElementById("board").append(tile); + row.push(tile); + } + board.push(row); + } + + console.log(board); +} + +function dragStart() { + //this refers to tile that was clicked on for dragging + currTile = this; +} + +function dragOver(e) { + e.preventDefault(); +} + +function dragEnter(e) { + e.preventDefault(); +} + +function dragLeave() { + +} + +function dragDrop() { + //this refers to the target tile that was dropped on + otherTile = this; +} + +function dragEnd() { + + if (currTile.src.includes("blank") || otherTile.src.includes("blank")) { + return; + } + + let currCoords = currTile.id.split("-"); // id="0-0" -> ["0", "0"] + let r = parseInt(currCoords[0]); + let c = parseInt(currCoords[1]); + + let otherCoords = otherTile.id.split("-"); + let r2 = parseInt(otherCoords[0]); + let c2 = parseInt(otherCoords[1]); + + let moveLeft = c2 == c-1 && r == r2; + let moveRight = c2 == c+1 && r == r2; + + let moveUp = r2 == r-1 && c == c2; + let moveDown = r2 == r+1 && c == c2; + + let isAdjacent = moveLeft || moveRight || moveUp || moveDown; + + if (isAdjacent) { + let currImg = currTile.src; + let otherImg = otherTile.src; + currTile.src = otherImg; + otherTile.src = currImg; + + let validMove = checkValid(); + if (!validMove) { + let currImg = currTile.src; + let otherImg = otherTile.src; + currTile.src = otherImg; + otherTile.src = currImg; + } + } +} + +function crushCandy() { + //crushFive(); + //crushFour(); + crushThree(); + document.getElementById("score").innerText = score; + +} + +function crushThree() { + //check rows + for (let r = 0; r < rows; r++) { + for (let c = 0; c < columns-2; c++) { + let candy1 = board[r][c]; + let candy2 = board[r][c+1]; + let candy3 = board[r][c+2]; + if (candy1.src == candy2.src && candy2.src == candy3.src && !candy1.src.includes("blank")) { + candy1.src = "./images/blank.png"; + candy2.src = "./images/blank.png"; + candy3.src = "./images/blank.png"; + score += 30; + } + } + } + + //check columns + for (let c = 0; c < columns; c++) { + for (let r = 0; r < rows-2; r++) { + let candy1 = board[r][c]; + let candy2 = board[r+1][c]; + let candy3 = board[r+2][c]; + if (candy1.src == candy2.src && candy2.src == candy3.src && !candy1.src.includes("blank")) { + candy1.src = "./images/blank.png"; + candy2.src = "./images/blank.png"; + candy3.src = "./images/blank.png"; + score += 30; + } + } + } +} + +function checkValid() { + //check rows + for (let r = 0; r < rows; r++) { + for (let c = 0; c < columns-2; c++) { + let candy1 = board[r][c]; + let candy2 = board[r][c+1]; + let candy3 = board[r][c+2]; + if (candy1.src == candy2.src && candy2.src == candy3.src && !candy1.src.includes("blank")) { + return true; + } + } + } + + //check columns + for (let c = 0; c < columns; c++) { + for (let r = 0; r < rows-2; r++) { + let candy1 = board[r][c]; + let candy2 = board[r+1][c]; + let candy3 = board[r+2][c]; + if (candy1.src == candy2.src && candy2.src == candy3.src && !candy1.src.includes("blank")) { + return true; + } + } + } + + return false; +} + + +function slideCandy() { + for (let c = 0; c < columns; c++) { + let ind = rows - 1; + for (let r = columns-1; r >= 0; r--) { + if (!board[r][c].src.includes("blank")) { + board[ind][c].src = board[r][c].src; + ind -= 1; + } + } + + for (let r = ind; r >= 0; r--) { + board[r][c].src = "./images/blank.png"; + } + } +} + +function generateCandy() { + for (let c = 0; c < columns; c++) { + if (board[0][c].src.includes("blank")) { + board[0][c].src = "./images/" + randomCandy() + ".png"; + } + } +} \ No newline at end of file diff --git a/projects/Candy Game/images/Blue-Striped-Horizontal.png b/projects/Candy Game/images/Blue-Striped-Horizontal.png new file mode 100644 index 000000000..d079458a5 Binary files /dev/null and b/projects/Candy Game/images/Blue-Striped-Horizontal.png differ diff --git a/projects/Candy Game/images/Blue-Striped-Vertical.png b/projects/Candy Game/images/Blue-Striped-Vertical.png new file mode 100644 index 000000000..2fea99144 Binary files /dev/null and b/projects/Candy Game/images/Blue-Striped-Vertical.png differ diff --git a/projects/Candy Game/images/Blue-Wrapped.png b/projects/Candy Game/images/Blue-Wrapped.png new file mode 100644 index 000000000..63514ff0e Binary files /dev/null and b/projects/Candy Game/images/Blue-Wrapped.png differ diff --git a/projects/Candy Game/images/Blue.png b/projects/Candy Game/images/Blue.png new file mode 100644 index 000000000..5b358796d Binary files /dev/null and b/projects/Candy Game/images/Blue.png differ diff --git a/projects/Candy Game/images/Choco.png b/projects/Candy Game/images/Choco.png new file mode 100644 index 000000000..732d6f3d9 Binary files /dev/null and b/projects/Candy Game/images/Choco.png differ diff --git a/projects/Candy Game/images/Green-Striped-Horizontal.png b/projects/Candy Game/images/Green-Striped-Horizontal.png new file mode 100644 index 000000000..0c1cea5f3 Binary files /dev/null and b/projects/Candy Game/images/Green-Striped-Horizontal.png differ diff --git a/projects/Candy Game/images/Green-Striped-Vertical.png b/projects/Candy Game/images/Green-Striped-Vertical.png new file mode 100644 index 000000000..78fa92c3d Binary files /dev/null and b/projects/Candy Game/images/Green-Striped-Vertical.png differ diff --git a/projects/Candy Game/images/Green-Wrapped.png b/projects/Candy Game/images/Green-Wrapped.png new file mode 100644 index 000000000..1710264fc Binary files /dev/null and b/projects/Candy Game/images/Green-Wrapped.png differ diff --git a/projects/Candy Game/images/Green.png b/projects/Candy Game/images/Green.png new file mode 100644 index 000000000..9ffea2a99 Binary files /dev/null and b/projects/Candy Game/images/Green.png differ diff --git a/projects/Candy Game/images/Orange-Striped-Horizontal.png b/projects/Candy Game/images/Orange-Striped-Horizontal.png new file mode 100644 index 000000000..b64bfcfa1 Binary files /dev/null and b/projects/Candy Game/images/Orange-Striped-Horizontal.png differ diff --git a/projects/Candy Game/images/Orange-Striped-Vertical.png b/projects/Candy Game/images/Orange-Striped-Vertical.png new file mode 100644 index 000000000..a6da76fc2 Binary files /dev/null and b/projects/Candy Game/images/Orange-Striped-Vertical.png differ diff --git a/projects/Candy Game/images/Orange-Wrapped.png b/projects/Candy Game/images/Orange-Wrapped.png new file mode 100644 index 000000000..2af5190e2 Binary files /dev/null and b/projects/Candy Game/images/Orange-Wrapped.png differ diff --git a/projects/Candy Game/images/Orange.png b/projects/Candy Game/images/Orange.png new file mode 100644 index 000000000..fdeda79c4 Binary files /dev/null and b/projects/Candy Game/images/Orange.png differ diff --git a/projects/Candy Game/images/Purple-Striped-Horizontal.png b/projects/Candy Game/images/Purple-Striped-Horizontal.png new file mode 100644 index 000000000..3e1b67466 Binary files /dev/null and b/projects/Candy Game/images/Purple-Striped-Horizontal.png differ diff --git a/projects/Candy Game/images/Purple-Striped-Vertical.png b/projects/Candy Game/images/Purple-Striped-Vertical.png new file mode 100644 index 000000000..989f11f09 Binary files /dev/null and b/projects/Candy Game/images/Purple-Striped-Vertical.png differ diff --git a/projects/Candy Game/images/Purple-Wrapped.png b/projects/Candy Game/images/Purple-Wrapped.png new file mode 100644 index 000000000..32a944f62 Binary files /dev/null and b/projects/Candy Game/images/Purple-Wrapped.png differ diff --git a/projects/Candy Game/images/Purple.png b/projects/Candy Game/images/Purple.png new file mode 100644 index 000000000..65e5bf93b Binary files /dev/null and b/projects/Candy Game/images/Purple.png differ diff --git a/projects/Candy Game/images/Red-Striped-Horizontal.png b/projects/Candy Game/images/Red-Striped-Horizontal.png new file mode 100644 index 000000000..b22694c6d Binary files /dev/null and b/projects/Candy Game/images/Red-Striped-Horizontal.png differ diff --git a/projects/Candy Game/images/Red-Striped-Vertical.png b/projects/Candy Game/images/Red-Striped-Vertical.png new file mode 100644 index 000000000..f9217e687 Binary files /dev/null and b/projects/Candy Game/images/Red-Striped-Vertical.png differ diff --git a/projects/Candy Game/images/Red-Wrapped.png b/projects/Candy Game/images/Red-Wrapped.png new file mode 100644 index 000000000..2c30a3ac0 Binary files /dev/null and b/projects/Candy Game/images/Red-Wrapped.png differ diff --git a/projects/Candy Game/images/Red.png b/projects/Candy Game/images/Red.png new file mode 100644 index 000000000..4b3136364 Binary files /dev/null and b/projects/Candy Game/images/Red.png differ diff --git a/projects/Candy Game/images/Yellow-Striped-Horizontal.png b/projects/Candy Game/images/Yellow-Striped-Horizontal.png new file mode 100644 index 000000000..f1a40e7cc Binary files /dev/null and b/projects/Candy Game/images/Yellow-Striped-Horizontal.png differ diff --git a/projects/Candy Game/images/Yellow-Striped-Vertical.png b/projects/Candy Game/images/Yellow-Striped-Vertical.png new file mode 100644 index 000000000..7d9cbf3fa Binary files /dev/null and b/projects/Candy Game/images/Yellow-Striped-Vertical.png differ diff --git a/projects/Candy Game/images/Yellow-Wrapped.png b/projects/Candy Game/images/Yellow-Wrapped.png new file mode 100644 index 000000000..ea48a9bd2 Binary files /dev/null and b/projects/Candy Game/images/Yellow-Wrapped.png differ diff --git a/projects/Candy Game/images/Yellow.png b/projects/Candy Game/images/Yellow.png new file mode 100644 index 000000000..39a8e9e68 Binary files /dev/null and b/projects/Candy Game/images/Yellow.png differ diff --git a/projects/Candy Game/images/blank.png b/projects/Candy Game/images/blank.png new file mode 100644 index 000000000..acbc4fe83 Binary files /dev/null and b/projects/Candy Game/images/blank.png differ diff --git a/projects/Candy Game/index.html b/projects/Candy Game/index.html new file mode 100644 index 000000000..049a1a309 --- /dev/null +++ b/projects/Candy Game/index.html @@ -0,0 +1,16 @@ + + + + + + + Candy Crush + + + + + +

Score: 0

+
+ + \ No newline at end of file diff --git a/projects/Chatbot/index.html b/projects/Chatbot/index.html new file mode 100644 index 000000000..7dd9e2a6d --- /dev/null +++ b/projects/Chatbot/index.html @@ -0,0 +1,33 @@ + + + + + + Chatbot + + + + + +
+
+

Chatbot

+
+ +
+ + Send +
+ +
+ + + + \ No newline at end of file diff --git a/projects/Chatbot/script.js b/projects/Chatbot/script.js new file mode 100644 index 000000000..f9a7eaf8a --- /dev/null +++ b/projects/Chatbot/script.js @@ -0,0 +1,63 @@ +const chatInput = document.querySelector(".chat-input textarea"); +const sendChatBtn = document.querySelector(".chat-input span"); +const chatbox = document.querySelector(".chatbox"); + +let userMessage = ""; +const API_KEY=""; + +const createChatLi = (message, className) => { + const chatLi = document.createElement("li"); + chatLi.classList.add("chat", className); + let chatContent = + className === "outgoing" + ? `

` + : `smart_toy

`; + chatLi.innerHTML = chatContent; + chatLi.querySelector("p").textContent = message; + return chatLi; +}; + +const generateResponse = (incomingChatLi) => { + const API_URL = `https://generativelanguage.googleapis.com/v1/models/gemini-pro:generateContent?key=${API_KEY}`; + const messageElement = incomingChatLi.querySelector("p"); + const requestOptions = { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + contents: [ + { + role: "user", + parts: [{ text: userMessage }], + }, + ], + }), + }; + fetch(API_URL, requestOptions) + .then((res) => res.json()) + .then((data) => { + messageElement.textContent = data.candidates[0].content.parts[0].text; + }) + .catch((error) => { + messageElement.textContent = + "Oops! Something went wrong. Please try again later."; + }) + .finally(() => chatbox.scrollTo(0, chatbox.scrollHeight)); +}; + +const handleChat = () => { + userMessage = chatInput.value.trim(); + if (!userMessage) return; + chatInput.value = ""; + + chatbox.appendChild(createChatLi(userMessage, "outgoing")); + chatbox.scrollTo(0, chatbox.scrollHeight); + + setTimeout(() => { + const incomingChatLi = createChatLi("Thinking....", "incoming"); + chatbox.appendChild(incomingChatLi); + chatbox.scrollTo(0, chatbox.scrollHeight); + generateResponse(incomingChatLi); + }, 600); +}; + +sendChatBtn.addEventListener("click", handleChat); diff --git a/projects/Chatbot/style.css b/projects/Chatbot/style.css new file mode 100644 index 000000000..d3dfe7ed7 --- /dev/null +++ b/projects/Chatbot/style.css @@ -0,0 +1,162 @@ +@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600&display=swap'); + +* { + box-sizing: border-box; + margin: 0; + padding: 0; + font-family: 'Poppins', sans-serif; +} + +body { + background: #E3F2FD; +} + + +.chatbot { + width: 550px; + height: 600px; + position: fixed; + left: 600px; + top: 100px; + pointer-events: none; + overflow: hidden; + background: #fff; + border-radius: 15px; + box-shadow: 0 0 128px 0 rgba(0, 0, 0, 0.1), + 0 32px 64px -48px rgba(0, 0, 0, 0.5); +} + +.show-chatbot .chatbot { + transform: scale(1); + opacity: 1; + pointer-events: auto; +} + +.chatbot header { + background: #724ae8; + padding: 26px; + text-align: center; + position: relative; +} + + +.chatbot header h2 { + color: #fff; + font-size: 1.8rem; +} + +.chatbot header span { + position: absolute; + right: 20px; + top: 50%; + color: #fff; + cursor: pointer; + display: none; + transform: translateY(-50%); +} + +.chatbot .chatbox { + height: 510px; + overflow-y: auto; + padding: 30px 20px 100px; +} + +.chatbox .chat { + display: flex; + +} + +.chatbox .incoming span { + height: 32px; + width: 32px; + color: #fff; + align-self: flex-end; + background: #724ae8; + text-align: center; + line-height: 32px; + border-radius: 4px; + margin: 0 10px 7px 0; + +} + +.chatbox .outgoing { + margin: 20px 0; + justify-content: flex-end; +} + + +.chatbox .chat p { + color: #fff; + max-width: 75%; + white-space: pre-wrap; + + font-size: 0.95rem; + padding: 12px 16px; + border-radius: 10px 10px 0 10px; + background: #724ae8; +} + +.chatbox .incoming p { + color: #000; + background: #f2f2f2; + border-radius: 10px 10px 10px 0; +} + +.chatbot .chat-input { + position: absolute; + bottom: 0; + width: 100%; + display: flex; + gap: 5px; + background: #fff; + padding: 5px 20px; + border-top: 1px solid #ccc; +} + +.chat-input textarea { + height: 55px; + width: 100%; + border: none; + outline: none; + font-size: 0.95rem; + resize: none; + padding: 16px 15px 16px 0; +} + +.chat-input span { + align-self: flex-end; + height: 55px; + line-height: 55px; + color: #724ae8; + font-size: 1.35rem; + cursor: pointer; + visibility: hidden; +} + +.chat-input textarea:valid~span { + visibility: visible; +} + +@media(max-width:790px) { + .chatbot { + position: fixed; + top: 15px; + left: 22px; + right: 45px; + bottom: 55px; + height: auto; + width: auto; + + + + border-radius: 5px; + } + + .chatbot .chatbox { + height: 90%; + } + + .chatbot header span { + display: block; + } +} \ No newline at end of file diff --git a/projects/Gen-AI-Quiz-Application/components.json b/projects/Gen-AI-Quiz-Application/components.json new file mode 100644 index 000000000..4d01f8ba3 --- /dev/null +++ b/projects/Gen-AI-Quiz-Application/components.json @@ -0,0 +1,17 @@ +{ + "$schema": "https://ui.shadcn.com/schema.json", + "style": "default", + "rsc": true, + "tsx": true, + "tailwind": { + "config": "tailwind.config.js", + "css": "src/app/globals.css", + "baseColor": "slate", + "cssVariables": true, + "prefix": "" + }, + "aliases": { + "components": "@/components", + "utils": "@/lib/utils" + } +} \ No newline at end of file diff --git a/projects/Gen-AI-Quiz-Application/next-env.d.ts b/projects/Gen-AI-Quiz-Application/next-env.d.ts new file mode 100644 index 000000000..62b8a52d3 --- /dev/null +++ b/projects/Gen-AI-Quiz-Application/next-env.d.ts @@ -0,0 +1,5 @@ +/// +/// + +// NOTE: This file should not be edited +// see https://nextjs.org/docs/basic-features/typescript for more information. diff --git a/projects/Gen-AI-Quiz-Application/next.config.js b/projects/Gen-AI-Quiz-Application/next.config.js new file mode 100644 index 000000000..767719fc4 --- /dev/null +++ b/projects/Gen-AI-Quiz-Application/next.config.js @@ -0,0 +1,4 @@ +/** @type {import('next').NextConfig} */ +const nextConfig = {} + +module.exports = nextConfig diff --git a/projects/Gen-AI-Quiz-Application/package-lock.json b/projects/Gen-AI-Quiz-Application/package-lock.json new file mode 100644 index 000000000..5e0ddec91 --- /dev/null +++ b/projects/Gen-AI-Quiz-Application/package-lock.json @@ -0,0 +1,4768 @@ +{ + "name": "quiz", + "version": "0.1.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "quiz", + "version": "0.1.0", + "dependencies": { + "@google/generative-ai": "^0.1.3", + "@radix-ui/react-slot": "^1.0.2", + "class-variance-authority": "^0.7.0", + "clsx": "^2.1.0", + "lucide-react": "^0.303.0", + "next": "14.2.10", + "react": "^18", + "react-dom": "^18", + "react-icons": "^4.12.0", + "react-toastify": "^9.1.3", + "tailwind-merge": "^2.2.0", + "tailwindcss-animate": "^1.0.7" + }, + "devDependencies": { + "@types/node": "^20", + "@types/react": "^18", + "@types/react-dom": "^18", + "autoprefixer": "^10.0.1", + "eslint": "^8", + "eslint-config-next": "14.0.4", + "postcss": "^8", + "tailwindcss": "^3.3.0", + "typescript": "^5" + } + }, + "node_modules/@aashutoshrathi/word-wrap": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", + "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@alloc/quick-lru": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", + "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==", + "engines": { + "node": ">=10" + } + }, + "node_modules/@babel/runtime": { + "version": "7.23.7", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.7.tgz", + "integrity": "sha512-w06OXVOFso7LcbzMiDGt+3X7Rh7Ho8MmgPoWU3rarH+8upf+wSU/grlGbWzQyr3DkdN6ZeuMFjpdwW0Q+HxobA==", + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", + "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", + "dev": true, + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "dev": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/js": { + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.56.0.tgz", + "integrity": "sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@google/generative-ai": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@google/generative-ai/-/generative-ai-0.1.3.tgz", + "integrity": "sha512-Cm4uJX1sKarpm1mje/MiOIinM7zdUUrQp/5/qGPAgznbdd/B9zup5ehT6c1qGqycFcSopTA1J1HpqHS5kJR8hQ==", + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.11.13", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.13.tgz", + "integrity": "sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ==", + "dev": true, + "dependencies": { + "@humanwhocodes/object-schema": "^2.0.1", + "debug": "^4.1.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.1.tgz", + "integrity": "sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==", + "dev": true + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", + "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "dependencies": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", + "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.20", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz", + "integrity": "sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@next/env": { + "version": "14.2.10", + "resolved": "https://registry.npmjs.org/@next/env/-/env-14.2.10.tgz", + "integrity": "sha512-dZIu93Bf5LUtluBXIv4woQw2cZVZ2DJTjax5/5DOs3lzEOeKLy7GxRSr4caK9/SCPdaW6bCgpye6+n4Dh9oJPw==" + }, + "node_modules/@next/eslint-plugin-next": { + "version": "14.0.4", + "resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-14.0.4.tgz", + "integrity": "sha512-U3qMNHmEZoVmHA0j/57nRfi3AscXNvkOnxDmle/69Jz/G0o/gWjXTDdlgILZdrxQ0Lw/jv2mPW8PGy0EGIHXhQ==", + "dev": true, + "dependencies": { + "glob": "7.1.7" + } + }, + "node_modules/@next/swc-darwin-arm64": { + "version": "14.2.10", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.2.10.tgz", + "integrity": "sha512-V3z10NV+cvMAfxQUMhKgfQnPbjw+Ew3cnr64b0lr8MDiBJs3eLnM6RpGC46nhfMZsiXgQngCJKWGTC/yDcgrDQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-darwin-x64": { + "version": "14.2.10", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.2.10.tgz", + "integrity": "sha512-Y0TC+FXbFUQ2MQgimJ/7Ina2mXIKhE7F+GUe1SgnzRmwFY3hX2z8nyVCxE82I2RicspdkZnSWMn4oTjIKz4uzA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-gnu": { + "version": "14.2.10", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.2.10.tgz", + "integrity": "sha512-ZfQ7yOy5zyskSj9rFpa0Yd7gkrBnJTkYVSya95hX3zeBG9E55Z6OTNPn1j2BTFWvOVVj65C3T+qsjOyVI9DQpA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-musl": { + "version": "14.2.10", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.2.10.tgz", + "integrity": "sha512-n2i5o3y2jpBfXFRxDREr342BGIQCJbdAUi/K4q6Env3aSx8erM9VuKXHw5KNROK9ejFSPf0LhoSkU/ZiNdacpQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-gnu": { + "version": "14.2.10", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.2.10.tgz", + "integrity": "sha512-GXvajAWh2woTT0GKEDlkVhFNxhJS/XdDmrVHrPOA83pLzlGPQnixqxD8u3bBB9oATBKB//5e4vpACnx5Vaxdqg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-musl": { + "version": "14.2.10", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.2.10.tgz", + "integrity": "sha512-opFFN5B0SnO+HTz4Wq4HaylXGFV+iHrVxd3YvREUX9K+xfc4ePbRrxqOuPOFjtSuiVouwe6uLeDtabjEIbkmDA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-arm64-msvc": { + "version": "14.2.10", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.2.10.tgz", + "integrity": "sha512-9NUzZuR8WiXTvv+EiU/MXdcQ1XUvFixbLIMNQiVHuzs7ZIFrJDLJDaOF1KaqttoTujpcxljM/RNAOmw1GhPPQQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-ia32-msvc": { + "version": "14.2.10", + "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.2.10.tgz", + "integrity": "sha512-fr3aEbSd1GeW3YUMBkWAu4hcdjZ6g4NBl1uku4gAn661tcxd1bHs1THWYzdsbTRLcCKLjrDZlNp6j2HTfrw+Bg==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-x64-msvc": { + "version": "14.2.10", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.2.10.tgz", + "integrity": "sha512-UjeVoRGKNL2zfbcQ6fscmgjBAS/inHBh63mjIlfPg/NG8Yn2ztqylXt5qilYb6hoHIwaU2ogHknHWWmahJjgZQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@radix-ui/react-compose-refs": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.0.1.tgz", + "integrity": "sha512-fDSBgd44FKHa1FRMU59qBMPFcl2PZE+2nmqunj+BWFyYYjnhIDWL2ItDs3rrbJDQOtzt5nIebLCQc4QRfz6LJw==", + "dependencies": { + "@babel/runtime": "^7.13.10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-slot": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.0.2.tgz", + "integrity": "sha512-YeTpuq4deV+6DusvVUW4ivBgnkHwECUu0BiN43L5UCDFgdhsRUWAghhTF5MbvNTPzmiFOx90asDSUjWuCNapwg==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-compose-refs": "1.0.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@rushstack/eslint-patch": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.6.1.tgz", + "integrity": "sha512-UY+FGM/2jjMkzQLn8pxcHGMaVLh9aEitG3zY2CiY7XHdLiz3bZOwa6oDxNqEMv7zZkV+cj5DOdz0cQ1BP5Hjgw==", + "dev": true + }, + "node_modules/@swc/counter": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz", + "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==" + }, + "node_modules/@swc/helpers": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.5.tgz", + "integrity": "sha512-KGYxvIOXcceOAbEk4bi/dVLEK9z8sZ0uBB3Il5b1rhfClSpcX0yfRO0KmTkqR2cnQDymwLB+25ZyMzICg/cm/A==", + "dependencies": { + "@swc/counter": "^0.1.3", + "tslib": "^2.4.0" + } + }, + "node_modules/@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", + "dev": true + }, + "node_modules/@types/node": { + "version": "20.10.6", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.6.tgz", + "integrity": "sha512-Vac8H+NlRNNlAmDfGUP7b5h/KA+AtWIzuXy0E6OyP8f1tCLYAtPvKRRDJjAPqhpCb0t6U2j7/xqAuLEebW2kiw==", + "dev": true, + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/@types/prop-types": { + "version": "15.7.11", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.11.tgz", + "integrity": "sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng==", + "devOptional": true + }, + "node_modules/@types/react": { + "version": "18.2.46", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.46.tgz", + "integrity": "sha512-nNCvVBcZlvX4NU1nRRNV/mFl1nNRuTuslAJglQsq+8ldXe5Xv0Wd2f7WTE3jOxhLH2BFfiZGC6GCp+kHQbgG+w==", + "devOptional": true, + "dependencies": { + "@types/prop-types": "*", + "@types/scheduler": "*", + "csstype": "^3.0.2" + } + }, + "node_modules/@types/react-dom": { + "version": "18.2.18", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.18.tgz", + "integrity": "sha512-TJxDm6OfAX2KJWJdMEVTwWke5Sc/E/RlnPGvGfS0W7+6ocy2xhDVQVh/KvC2Uf7kACs+gDytdusDSdWfWkaNzw==", + "dev": true, + "dependencies": { + "@types/react": "*" + } + }, + "node_modules/@types/scheduler": { + "version": "0.16.8", + "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.8.tgz", + "integrity": "sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A==", + "devOptional": true + }, + "node_modules/@typescript-eslint/parser": { + "version": "6.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.16.0.tgz", + "integrity": "sha512-H2GM3eUo12HpKZU9njig3DF5zJ58ja6ahj1GoHEHOgQvYxzoFJJEvC1MQ7T2l9Ha+69ZSOn7RTxOdpC/y3ikMw==", + "dev": true, + "dependencies": { + "@typescript-eslint/scope-manager": "6.16.0", + "@typescript-eslint/types": "6.16.0", + "@typescript-eslint/typescript-estree": "6.16.0", + "@typescript-eslint/visitor-keys": "6.16.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "6.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.16.0.tgz", + "integrity": "sha512-0N7Y9DSPdaBQ3sqSCwlrm9zJwkpOuc6HYm7LpzLAPqBL7dmzAUimr4M29dMkOP/tEwvOCC/Cxo//yOfJD3HUiw==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.16.0", + "@typescript-eslint/visitor-keys": "6.16.0" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "6.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.16.0.tgz", + "integrity": "sha512-hvDFpLEvTJoHutVl87+MG/c5C8I6LOgEx05zExTSJDEVU7hhR3jhV8M5zuggbdFCw98+HhZWPHZeKS97kS3JoQ==", + "dev": true, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "6.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.16.0.tgz", + "integrity": "sha512-VTWZuixh/vr7nih6CfrdpmFNLEnoVBF1skfjdyGnNwXOH1SLeHItGdZDHhhAIzd3ACazyY2Fg76zuzOVTaknGA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.16.0", + "@typescript-eslint/visitor-keys": "6.16.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "minimatch": "9.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "6.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.16.0.tgz", + "integrity": "sha512-QSFQLruk7fhs91a/Ep/LqRdbJCZ1Rq03rqBdKT5Ky17Sz8zRLUksqIe9DW0pKtg/Z35/ztbLQ6qpOCN6rOC11A==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.16.0", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "dev": true + }, + "node_modules/acorn": { + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==" + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/arg": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==" + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/aria-query": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", + "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", + "dev": true, + "dependencies": { + "dequal": "^2.0.3" + } + }, + "node_modules/array-buffer-byte-length": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz", + "integrity": "sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "is-array-buffer": "^3.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-includes": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.7.tgz", + "integrity": "sha512-dlcsNBIiWhPkHdOEEKnehA+RNUWDc4UqFtnIXU4uuYDPtA4LDkr7qip2p0VvFAEXNDr0yWZ9PJyIRiGjRLQzwQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "get-intrinsic": "^1.2.1", + "is-string": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/array.prototype.findlastindex": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.3.tgz", + "integrity": "sha512-LzLoiOMAxvy+Gd3BAq3B7VeIgPdo+Q8hthvKtXybMvRV0jrXfJM/t8mw7nNlpEcVlVUnCnM2KSX4XU5HmpodOA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0", + "get-intrinsic": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flat": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", + "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flatmap": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz", + "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.tosorted": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.2.tgz", + "integrity": "sha512-HuQCHOlk1Weat5jzStICBCd83NxiIMwqDg/dHEsoefabn/hJRj5pVdWcPUSpRrwhwxZOsQassMpgN/xRYFBMIg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0", + "get-intrinsic": "^1.2.1" + } + }, + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.2.tgz", + "integrity": "sha512-yMBKppFur/fbHu9/6USUe03bZ4knMYiwFBcyiaXB8Go0qNehwX6inYPzK9U0NeQvGxKthcmHcaR8P5MStSRBAw==", + "dev": true, + "dependencies": { + "array-buffer-byte-length": "^1.0.0", + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "get-intrinsic": "^1.2.1", + "is-array-buffer": "^3.0.2", + "is-shared-array-buffer": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ast-types-flow": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.8.tgz", + "integrity": "sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==", + "dev": true + }, + "node_modules/asynciterator.prototype": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/asynciterator.prototype/-/asynciterator.prototype-1.0.0.tgz", + "integrity": "sha512-wwHYEIS0Q80f5mosx3L/dfG5t5rjEa9Ft51GTaNt862EnpyGHpgz2RkZvLPp1oF5TnAiTohkEKVEu8pQPJI7Vg==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.3" + } + }, + "node_modules/autoprefixer": { + "version": "10.4.16", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.16.tgz", + "integrity": "sha512-7vd3UC6xKp0HLfua5IjZlcXvGAGy7cBAXTg2lyQ/8WpNhd6SiZ8Be+xm3FyBSYJx5GKcpRCzBh7RH4/0dnY+uQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/autoprefixer" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "browserslist": "^4.21.10", + "caniuse-lite": "^1.0.30001538", + "fraction.js": "^4.3.6", + "normalize-range": "^0.1.2", + "picocolors": "^1.0.0", + "postcss-value-parser": "^4.2.0" + }, + "bin": { + "autoprefixer": "bin/autoprefixer" + }, + "engines": { + "node": "^10 || ^12 || >=14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/available-typed-arrays": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", + "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/axe-core": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.7.0.tgz", + "integrity": "sha512-M0JtH+hlOL5pLQwHOLNYZaXuhqmvS8oExsqB1SBYgA4Dk7u/xx+YdGHXaK5pyUfed5mYXdlYiphWq3G8cRi5JQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/axobject-query": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-3.2.1.tgz", + "integrity": "sha512-jsyHu61e6N4Vbz/v18DHwWYKK0bSWLqn47eeDSKPB7m8tqMHF9YJ+mhIk2lVteyZrY8tnSj/jHOv4YiTCuCJgg==", + "dev": true, + "dependencies": { + "dequal": "^2.0.3" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "engines": { + "node": ">=8" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.22.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.2.tgz", + "integrity": "sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "caniuse-lite": "^1.0.30001565", + "electron-to-chromium": "^1.4.601", + "node-releases": "^2.0.14", + "update-browserslist-db": "^1.0.13" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/busboy": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", + "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", + "dependencies": { + "streamsearch": "^1.1.0" + }, + "engines": { + "node": ">=10.16.0" + } + }, + "node_modules/call-bind": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz", + "integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.1", + "set-function-length": "^1.1.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase-css": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", + "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001667", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001667.tgz", + "integrity": "sha512-7LTwJjcRkzKFmtqGsibMeuXmvFDfZq/nzIjnmgCGzKKRVzjD72selLDK1oPF/Oxzmt4fNcPvTDvGqSDG4tCALw==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ] + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chokidar/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/class-variance-authority": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/class-variance-authority/-/class-variance-authority-0.7.0.tgz", + "integrity": "sha512-jFI8IQw4hczaL4ALINxqLEXQbWcNjoSkloa4IaufXCJr6QawJyw7tuRysRsrE8w2p/4gGaxKIt/hX3qz/IbD1A==", + "dependencies": { + "clsx": "2.0.0" + }, + "funding": { + "url": "https://joebell.co.uk" + } + }, + "node_modules/class-variance-authority/node_modules/clsx": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.0.0.tgz", + "integrity": "sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q==", + "engines": { + "node": ">=6" + } + }, + "node_modules/client-only": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", + "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==" + }, + "node_modules/clsx": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.0.tgz", + "integrity": "sha512-m3iNNWpd9rl3jvvcBnu70ylMdrXt8Vlq4HYadnU5fwcOtvkSQWPmj7amUcDT2qYI7risszBjI5AUIUox9D16pg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", + "devOptional": true + }, + "node_modules/damerau-levenshtein": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", + "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==", + "dev": true + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, + "node_modules/define-data-property": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz", + "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.1", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dev": true, + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/didyoumean": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", + "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==" + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/dlv": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", + "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==" + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==" + }, + "node_modules/electron-to-chromium": { + "version": "1.4.616", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.616.tgz", + "integrity": "sha512-1n7zWYh8eS0L9Uy+GskE0lkBUNK83cXTVJI0pU3mGprFsbfSdAc15VTFbo+A+Bq4pwstmL30AVcEU3Fo463lNg==", + "dev": true + }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" + }, + "node_modules/enhanced-resolve": { + "version": "5.15.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz", + "integrity": "sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/es-abstract": { + "version": "1.22.3", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.3.tgz", + "integrity": "sha512-eiiY8HQeYfYH2Con2berK+To6GrK2RxbPawDkGq4UiCQQfZHb6wX9qQqkbpPqaxQFcl8d9QzZqo0tGE0VcrdwA==", + "dev": true, + "dependencies": { + "array-buffer-byte-length": "^1.0.0", + "arraybuffer.prototype.slice": "^1.0.2", + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.5", + "es-set-tostringtag": "^2.0.1", + "es-to-primitive": "^1.2.1", + "function.prototype.name": "^1.1.6", + "get-intrinsic": "^1.2.2", + "get-symbol-description": "^1.0.0", + "globalthis": "^1.0.3", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0", + "internal-slot": "^1.0.5", + "is-array-buffer": "^3.0.2", + "is-callable": "^1.2.7", + "is-negative-zero": "^2.0.2", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.2", + "is-string": "^1.0.7", + "is-typed-array": "^1.1.12", + "is-weakref": "^1.0.2", + "object-inspect": "^1.13.1", + "object-keys": "^1.1.1", + "object.assign": "^4.1.4", + "regexp.prototype.flags": "^1.5.1", + "safe-array-concat": "^1.0.1", + "safe-regex-test": "^1.0.0", + "string.prototype.trim": "^1.2.8", + "string.prototype.trimend": "^1.0.7", + "string.prototype.trimstart": "^1.0.7", + "typed-array-buffer": "^1.0.0", + "typed-array-byte-length": "^1.0.0", + "typed-array-byte-offset": "^1.0.0", + "typed-array-length": "^1.0.4", + "unbox-primitive": "^1.0.2", + "which-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-iterator-helpers": { + "version": "1.0.15", + "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.0.15.tgz", + "integrity": "sha512-GhoY8uYqd6iwUl2kgjTm4CZAf6oo5mHK7BPqx3rKgx893YSsy0LGHV6gfqqQvZt/8xM8xeOnfXBCfqclMKkJ5g==", + "dev": true, + "dependencies": { + "asynciterator.prototype": "^1.0.0", + "call-bind": "^1.0.2", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.1", + "es-set-tostringtag": "^2.0.1", + "function-bind": "^1.1.1", + "get-intrinsic": "^1.2.1", + "globalthis": "^1.0.3", + "has-property-descriptors": "^1.0.0", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.5", + "iterator.prototype": "^1.1.2", + "safe-array-concat": "^1.0.1" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.2.tgz", + "integrity": "sha512-BuDyupZt65P9D2D2vA/zqcI3G5xRsklm5N3xCwuiy+/vKy8i0ifdsQP1sLgO4tZDSCaQUSnmC48khknGMV3D2Q==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.2", + "has-tostringtag": "^1.0.0", + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-shim-unscopables": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz", + "integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==", + "dev": true, + "dependencies": { + "hasown": "^2.0.0" + } + }, + "node_modules/es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "dependencies": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.56.0.tgz", + "integrity": "sha512-Go19xM6T9puCOWntie1/P997aXxFsOi37JIHRWI514Hc6ZnaHGKY9xFhrU65RT6CcBEzZoGG1e6Nq+DT04ZtZQ==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.56.0", + "@humanwhocodes/config-array": "^0.11.13", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-config-next": { + "version": "14.0.4", + "resolved": "https://registry.npmjs.org/eslint-config-next/-/eslint-config-next-14.0.4.tgz", + "integrity": "sha512-9/xbOHEQOmQtqvQ1UsTQZpnA7SlDMBtuKJ//S4JnoyK3oGLhILKXdBgu/UO7lQo/2xOykQULS1qQ6p2+EpHgAQ==", + "dev": true, + "dependencies": { + "@next/eslint-plugin-next": "14.0.4", + "@rushstack/eslint-patch": "^1.3.3", + "@typescript-eslint/parser": "^5.4.2 || ^6.0.0", + "eslint-import-resolver-node": "^0.3.6", + "eslint-import-resolver-typescript": "^3.5.2", + "eslint-plugin-import": "^2.28.1", + "eslint-plugin-jsx-a11y": "^6.7.1", + "eslint-plugin-react": "^7.33.2", + "eslint-plugin-react-hooks": "^4.5.0 || 5.0.0-canary-7118f5dd7-20230705" + }, + "peerDependencies": { + "eslint": "^7.23.0 || ^8.0.0", + "typescript": ">=3.3.1" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/eslint-import-resolver-node": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", + "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", + "dev": true, + "dependencies": { + "debug": "^3.2.7", + "is-core-module": "^2.13.0", + "resolve": "^1.22.4" + } + }, + "node_modules/eslint-import-resolver-node/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-import-resolver-typescript": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.6.1.tgz", + "integrity": "sha512-xgdptdoi5W3niYeuQxKmzVDTATvLYqhpwmykwsh7f6HIOStGWEIL9iqZgQDF9u9OEzrRwR8no5q2VT+bjAujTg==", + "dev": true, + "dependencies": { + "debug": "^4.3.4", + "enhanced-resolve": "^5.12.0", + "eslint-module-utils": "^2.7.4", + "fast-glob": "^3.3.1", + "get-tsconfig": "^4.5.0", + "is-core-module": "^2.11.0", + "is-glob": "^4.0.3" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts/projects/eslint-import-resolver-ts" + }, + "peerDependencies": { + "eslint": "*", + "eslint-plugin-import": "*" + } + }, + "node_modules/eslint-module-utils": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz", + "integrity": "sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==", + "dev": true, + "dependencies": { + "debug": "^3.2.7" + }, + "engines": { + "node": ">=4" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } + } + }, + "node_modules/eslint-module-utils/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import": { + "version": "2.29.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz", + "integrity": "sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==", + "dev": true, + "dependencies": { + "array-includes": "^3.1.7", + "array.prototype.findlastindex": "^1.2.3", + "array.prototype.flat": "^1.3.2", + "array.prototype.flatmap": "^1.3.2", + "debug": "^3.2.7", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.9", + "eslint-module-utils": "^2.8.0", + "hasown": "^2.0.0", + "is-core-module": "^2.13.1", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.fromentries": "^2.0.7", + "object.groupby": "^1.0.1", + "object.values": "^1.1.7", + "semver": "^6.3.1", + "tsconfig-paths": "^3.15.0" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" + } + }, + "node_modules/eslint-plugin-import/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-import/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/eslint-plugin-jsx-a11y": { + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.8.0.tgz", + "integrity": "sha512-Hdh937BS3KdwwbBaKd5+PLCOmYY6U4f2h9Z2ktwtNKvIdIEu137rjYbcb9ApSbVJfWxANNuiKTD/9tOKjK9qOA==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.23.2", + "aria-query": "^5.3.0", + "array-includes": "^3.1.7", + "array.prototype.flatmap": "^1.3.2", + "ast-types-flow": "^0.0.8", + "axe-core": "=4.7.0", + "axobject-query": "^3.2.1", + "damerau-levenshtein": "^1.0.8", + "emoji-regex": "^9.2.2", + "es-iterator-helpers": "^1.0.15", + "hasown": "^2.0.0", + "jsx-ast-utils": "^3.3.5", + "language-tags": "^1.0.9", + "minimatch": "^3.1.2", + "object.entries": "^1.1.7", + "object.fromentries": "^2.0.7" + }, + "engines": { + "node": ">=4.0" + }, + "peerDependencies": { + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8" + } + }, + "node_modules/eslint-plugin-react": { + "version": "7.33.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.33.2.tgz", + "integrity": "sha512-73QQMKALArI8/7xGLNI/3LylrEYrlKZSb5C9+q3OtOewTnMQi5cT+aE9E41sLCmli3I9PGGmD1yiZydyo4FEPw==", + "dev": true, + "dependencies": { + "array-includes": "^3.1.6", + "array.prototype.flatmap": "^1.3.1", + "array.prototype.tosorted": "^1.1.1", + "doctrine": "^2.1.0", + "es-iterator-helpers": "^1.0.12", + "estraverse": "^5.3.0", + "jsx-ast-utils": "^2.4.1 || ^3.0.0", + "minimatch": "^3.1.2", + "object.entries": "^1.1.6", + "object.fromentries": "^2.0.6", + "object.hasown": "^1.1.2", + "object.values": "^1.1.6", + "prop-types": "^15.8.1", + "resolve": "^2.0.0-next.4", + "semver": "^6.3.1", + "string.prototype.matchall": "^4.0.8" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8" + } + }, + "node_modules/eslint-plugin-react-hooks": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz", + "integrity": "sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==", + "dev": true, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0" + } + }, + "node_modules/eslint-plugin-react/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-react/node_modules/resolve": { + "version": "2.0.0-next.5", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz", + "integrity": "sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==", + "dev": true, + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/eslint-plugin-react/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "dev": true, + "dependencies": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "dev": true, + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "node_modules/fast-glob": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true + }, + "node_modules/fastq": { + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.16.0.tgz", + "integrity": "sha512-ifCoaXsDrsdkWTtiNJX5uzHDsrck5TzfKKDcuFFTIrrc/BS076qgEIfoIy1VeZqViznfKiysPYTh/QeHtnIsYA==", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", + "dev": true, + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.3", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flatted": { + "version": "3.2.9", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.9.tgz", + "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==", + "dev": true + }, + "node_modules/for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "dev": true, + "dependencies": { + "is-callable": "^1.1.3" + } + }, + "node_modules/foreground-child": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", + "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/fraction.js": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", + "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==", + "dev": true, + "engines": { + "node": "*" + }, + "funding": { + "type": "patreon", + "url": "https://github.com/sponsors/rawify" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/function.prototype.name": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", + "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "functions-have-names": "^1.2.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz", + "integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-symbol-description": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", + "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-tsconfig": { + "version": "4.7.2", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.2.tgz", + "integrity": "sha512-wuMsz4leaj5hbGgg4IvDU0bqJagpftG5l5cXIAvo8uZrqn0NJqwtfupTN00VnkQJPcIRrxYrm1Ue24btpCha2A==", + "dev": true, + "dependencies": { + "resolve-pkg-maps": "^1.0.0" + }, + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + } + }, + "node_modules/glob": { + "version": "7.1.7", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", + "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globalthis": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", + "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", + "dev": true, + "dependencies": { + "define-properties": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" + }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true + }, + "node_modules/has-bigints": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", + "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz", + "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", + "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", + "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/ignore": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.0.tgz", + "integrity": "sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/internal-slot": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.6.tgz", + "integrity": "sha512-Xj6dv+PsbtwyPpEflsejS+oIZxmMlV44zAhG479uYu89MsjcYOhCFnNyKrkJrihbsiasQyY0afoCl/9BLR65bg==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.2", + "hasown": "^2.0.0", + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-array-buffer": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz", + "integrity": "sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.0", + "is-typed-array": "^1.1.10" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-async-function": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.0.0.tgz", + "integrity": "sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "dev": true, + "dependencies": { + "has-bigints": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-boolean-object": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-core-module": { + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", + "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", + "dependencies": { + "hasown": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-finalizationregistry": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.0.2.tgz", + "integrity": "sha512-0by5vtUJs8iFQb5TYUHHPudOR+qXYIMKtiUzvLIZITZUjknFmziyBJuLhVRc+Ds0dREFlskDNJKYIdIzu/9pfw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-generator-function": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", + "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-map": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.2.tgz", + "integrity": "sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-negative-zero": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", + "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-number-object": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", + "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-set": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.2.tgz", + "integrity": "sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", + "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.12.tgz", + "integrity": "sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==", + "dev": true, + "dependencies": { + "which-typed-array": "^1.1.11" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakmap": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.1.tgz", + "integrity": "sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakref": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakset": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.2.tgz", + "integrity": "sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + }, + "node_modules/iterator.prototype": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.2.tgz", + "integrity": "sha512-DR33HMMr8EzwuRL8Y9D3u2BMj8+RqSE850jfGu59kS7tbmPLzGkZmVSfyCFSDxuZiEY6Rzt3T2NA/qU+NwVj1w==", + "dev": true, + "dependencies": { + "define-properties": "^1.2.1", + "get-intrinsic": "^1.2.1", + "has-symbols": "^1.0.3", + "reflect.getprototypeof": "^1.0.4", + "set-function-name": "^2.0.1" + } + }, + "node_modules/jackspeak": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz", + "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/jiti": { + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.0.tgz", + "integrity": "sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q==", + "bin": { + "jiti": "bin/jiti.js" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true + }, + "node_modules/json5": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "dev": true, + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/jsx-ast-utils": { + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", + "integrity": "sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==", + "dev": true, + "dependencies": { + "array-includes": "^3.1.6", + "array.prototype.flat": "^1.3.1", + "object.assign": "^4.1.4", + "object.values": "^1.1.6" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/language-subtag-registry": { + "version": "0.3.22", + "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.22.tgz", + "integrity": "sha512-tN0MCzyWnoz/4nHS6uxdlFWoUZT7ABptwKPQ52Ea7URk6vll88bWBVhodtnlfEuCcKWNGoc+uGbw1cwa9IKh/w==", + "dev": true + }, + "node_modules/language-tags": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.9.tgz", + "integrity": "sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==", + "dev": true, + "dependencies": { + "language-subtag-registry": "^0.3.20" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lilconfig": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", + "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", + "engines": { + "node": ">=10" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/lucide-react": { + "version": "0.303.0", + "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.303.0.tgz", + "integrity": "sha512-B0B9T3dLEFBYPCUlnUS1mvAhW1craSbF9HO+JfBjAtpFUJ7gMIqmEwNSclikY3RiN2OnCkj/V1ReAQpaHae8Bg==", + "peerDependencies": { + "react": "^16.5.1 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minipass": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", + "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/mz": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "dependencies": { + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" + } + }, + "node_modules/nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true + }, + "node_modules/next": { + "version": "14.2.10", + "resolved": "https://registry.npmjs.org/next/-/next-14.2.10.tgz", + "integrity": "sha512-sDDExXnh33cY3RkS9JuFEKaS4HmlWmDKP1VJioucCG6z5KuA008DPsDZOzi8UfqEk3Ii+2NCQSJrfbEWtZZfww==", + "dependencies": { + "@next/env": "14.2.10", + "@swc/helpers": "0.5.5", + "busboy": "1.6.0", + "caniuse-lite": "^1.0.30001579", + "graceful-fs": "^4.2.11", + "postcss": "8.4.31", + "styled-jsx": "5.1.1" + }, + "bin": { + "next": "dist/bin/next" + }, + "engines": { + "node": ">=18.17.0" + }, + "optionalDependencies": { + "@next/swc-darwin-arm64": "14.2.10", + "@next/swc-darwin-x64": "14.2.10", + "@next/swc-linux-arm64-gnu": "14.2.10", + "@next/swc-linux-arm64-musl": "14.2.10", + "@next/swc-linux-x64-gnu": "14.2.10", + "@next/swc-linux-x64-musl": "14.2.10", + "@next/swc-win32-arm64-msvc": "14.2.10", + "@next/swc-win32-ia32-msvc": "14.2.10", + "@next/swc-win32-x64-msvc": "14.2.10" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.1.0", + "@playwright/test": "^1.41.2", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "sass": "^1.3.0" + }, + "peerDependenciesMeta": { + "@opentelemetry/api": { + "optional": true + }, + "@playwright/test": { + "optional": true + }, + "sass": { + "optional": true + } + } + }, + "node_modules/next/node_modules/postcss": { + "version": "8.4.31", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", + "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "nanoid": "^3.3.6", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/node-releases": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", + "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", + "dev": true + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-hash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", + "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/object-inspect": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", + "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "has-symbols": "^1.0.3", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.entries": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.7.tgz", + "integrity": "sha512-jCBs/0plmPsOnrKAfFQXRG2NFjlhZgjjcBLSmTnEhU8U6vVTsVe8ANeQJCHTl3gSsI4J+0emOoCgoKlmQPMgmA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.fromentries": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.7.tgz", + "integrity": "sha512-UPbPHML6sL8PI/mOqPwsH4G6iyXcCGzLin8KvEPenOZN5lpCNBZZQ+V62vdjB1mQHrmqGQt5/OJzemUA+KJmEA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.groupby": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.1.tgz", + "integrity": "sha512-HqaQtqLnp/8Bn4GL16cj+CUYbnpe1bh0TtEaWvybszDG4tgxCJuRpV8VGuvNaI1fAnI4lUJzDG55MXcOH4JZcQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "get-intrinsic": "^1.2.1" + } + }, + "node_modules/object.hasown": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.3.tgz", + "integrity": "sha512-fFI4VcYpRHvSLXxP7yiZOMAd331cPfd2p7PFDVbgUsYOfCT3tICVqXWngbjr4m49OvsBwUBQ6O2uQoJvy3RexA==", + "dev": true, + "dependencies": { + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.values": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.7.tgz", + "integrity": "sha512-aU6xnDFYT3x17e/f0IiiwlGPTy2jzMySGfUB4fq6z7CV8l85CWHDk5ErhyhpfDHhrOMwGFhSQkhMGHaIotA6Ng==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/optionator": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", + "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", + "dev": true, + "dependencies": { + "@aashutoshrathi/word-wrap": "^1.2.3", + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + }, + "node_modules/path-scurry": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz", + "integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==", + "dependencies": { + "lru-cache": "^9.1.1 || ^10.0.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.1.0.tgz", + "integrity": "sha512-/1clY/ui8CzjKFyjdvwPWJUYKiFVXG2I2cY0ssG7h4+hwk+XOIX7ZSG9Q7TW8TW3Kp3BUSqgFWBLgL4PJ+Blag==", + "engines": { + "node": "14 || >=16.14" + } + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pirates": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", + "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/postcss": { + "version": "8.4.32", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.32.tgz", + "integrity": "sha512-D/kj5JNu6oo2EIy+XL/26JEDTlIbB8hw85G8StOE6L74RQAVVP5rej6wxCNqyMbR4RkPfqvezVbPw81Ngd6Kcw==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "nanoid": "^3.3.7", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-import": { + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz", + "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==", + "dependencies": { + "postcss-value-parser": "^4.0.0", + "read-cache": "^1.0.0", + "resolve": "^1.1.7" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "postcss": "^8.0.0" + } + }, + "node_modules/postcss-js": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz", + "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==", + "dependencies": { + "camelcase-css": "^2.0.1" + }, + "engines": { + "node": "^12 || ^14 || >= 16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.4.21" + } + }, + "node_modules/postcss-load-config": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.2.tgz", + "integrity": "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "lilconfig": "^3.0.0", + "yaml": "^2.3.4" + }, + "engines": { + "node": ">= 14" + }, + "peerDependencies": { + "postcss": ">=8.0.9", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "postcss": { + "optional": true + }, + "ts-node": { + "optional": true + } + } + }, + "node_modules/postcss-load-config/node_modules/lilconfig": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.0.0.tgz", + "integrity": "sha512-K2U4W2Ff5ibV7j7ydLr+zLAkIg5JJ4lPn1Ltsdt+Tz/IjQ8buJ55pZAxoP34lqIiwtF9iAvtLv3JGv7CAyAg+g==", + "engines": { + "node": ">=14" + } + }, + "node_modules/postcss-nested": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.0.1.tgz", + "integrity": "sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ==", + "dependencies": { + "postcss-selector-parser": "^6.0.11" + }, + "engines": { + "node": ">=12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.2.14" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.0.15", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.15.tgz", + "integrity": "sha512-rEYkQOMUCEMhsKbK66tbEU9QVIxbhN18YiniAwA7XQYTVBqrBy+P2p5JcdqsHgKM2zWylp8d7J6eszocfds5Sw==", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==" + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "dev": true, + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/react": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", + "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==", + "dependencies": { + "loose-envify": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", + "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==", + "dependencies": { + "loose-envify": "^1.1.0", + "scheduler": "^0.23.0" + }, + "peerDependencies": { + "react": "^18.2.0" + } + }, + "node_modules/react-icons": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-4.12.0.tgz", + "integrity": "sha512-IBaDuHiShdZqmfc/TwHu6+d6k2ltNCf3AszxNmjJc1KUfXdEeRJOKyNvLmAHaarhzGmTSVygNdyu8/opXv2gaw==", + "peerDependencies": { + "react": "*" + } + }, + "node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "dev": true + }, + "node_modules/react-toastify": { + "version": "9.1.3", + "resolved": "https://registry.npmjs.org/react-toastify/-/react-toastify-9.1.3.tgz", + "integrity": "sha512-fPfb8ghtn/XMxw3LkxQBk3IyagNpF/LIKjOBflbexr2AWxAH1MJgvnESwEwBn9liLFXgTKWgBSdZpw9m4OTHTg==", + "dependencies": { + "clsx": "^1.1.1" + }, + "peerDependencies": { + "react": ">=16", + "react-dom": ">=16" + } + }, + "node_modules/react-toastify/node_modules/clsx": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz", + "integrity": "sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/read-cache": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", + "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", + "dependencies": { + "pify": "^2.3.0" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/reflect.getprototypeof": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.4.tgz", + "integrity": "sha512-ECkTw8TmJwW60lOTR+ZkODISW6RQ8+2CL3COqtiJKLd6MmB45hN51HprHFziKLGkAuTGQhBb91V8cy+KHlaCjw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "get-intrinsic": "^1.2.1", + "globalthis": "^1.0.3", + "which-builtin-type": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" + }, + "node_modules/regexp.prototype.flags": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.1.tgz", + "integrity": "sha512-sy6TXMN+hnP/wMy+ISxg3krXx7BAtWVO4UouuCN/ziM9UEne0euamVNafDfvC83bRNr95y0V5iijeDQFUNpvrg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "set-function-name": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "dev": true, + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-array-concat": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.0.1.tgz", + "integrity": "sha512-6XbUAseYE2KtOuGueyeobCySj9L4+66Tn6KQMOPQJrAJEowYKW/YR/MGJZl7FdydUdaFu4LYyDZjxf4/Nmo23Q==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.1", + "has-symbols": "^1.0.3", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-regex-test": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", + "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.3", + "is-regex": "^1.1.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/scheduler": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz", + "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==", + "dependencies": { + "loose-envify": "^1.1.0" + } + }, + "node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/set-function-length": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.1.1.tgz", + "integrity": "sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==", + "dev": true, + "dependencies": { + "define-data-property": "^1.1.1", + "get-intrinsic": "^1.2.1", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-function-name": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.1.tgz", + "integrity": "sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA==", + "dev": true, + "dependencies": { + "define-data-property": "^1.0.1", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "engines": { + "node": ">=8" + } + }, + "node_modules/side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/source-map-js": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", + "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/streamsearch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", + "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "node_modules/string-width/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/string-width/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/string.prototype.matchall": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.10.tgz", + "integrity": "sha512-rGXbGmOEosIQi6Qva94HUjgPs9vKW+dkG7Y8Q5O2OYkWL6wFaTRZO8zM4mhP94uX55wgyrXzfS2aGtGzUL7EJQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "get-intrinsic": "^1.2.1", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.5", + "regexp.prototype.flags": "^1.5.0", + "set-function-name": "^2.0.0", + "side-channel": "^1.0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trim": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.8.tgz", + "integrity": "sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.7.tgz", + "integrity": "sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.7.tgz", + "integrity": "sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/styled-jsx": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.1.tgz", + "integrity": "sha512-pW7uC1l4mBZ8ugbiZrcIsiIvVx1UmTfw7UkC3Um2tmfUq9Bhk8IiyEIPl6F8agHgjzku6j0xQEZbfA5uSgSaCw==", + "dependencies": { + "client-only": "0.0.1" + }, + "engines": { + "node": ">= 12.0.0" + }, + "peerDependencies": { + "react": ">= 16.8.0 || 17.x.x || ^18.0.0-0" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "babel-plugin-macros": { + "optional": true + } + } + }, + "node_modules/sucrase": { + "version": "3.35.0", + "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz", + "integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.2", + "commander": "^4.0.0", + "glob": "^10.3.10", + "lines-and-columns": "^1.1.6", + "mz": "^2.7.0", + "pirates": "^4.0.1", + "ts-interface-checker": "^0.1.9" + }, + "bin": { + "sucrase": "bin/sucrase", + "sucrase-node": "bin/sucrase-node" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/sucrase/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/sucrase/node_modules/glob": { + "version": "10.3.10", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz", + "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^2.3.5", + "minimatch": "^9.0.1", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", + "path-scurry": "^1.10.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/sucrase/node_modules/minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/tailwind-merge": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-2.2.0.tgz", + "integrity": "sha512-SqqhhaL0T06SW59+JVNfAqKdqLs0497esifRrZ7jOaefP3o64fdFNDMrAQWZFMxTLJPiHVjRLUywT8uFz1xNWQ==", + "dependencies": { + "@babel/runtime": "^7.23.5" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/dcastil" + } + }, + "node_modules/tailwindcss": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.0.tgz", + "integrity": "sha512-VigzymniH77knD1dryXbyxR+ePHihHociZbXnLZHUyzf2MMs2ZVqlUrZ3FvpXP8pno9JzmILt1sZPD19M3IxtA==", + "dependencies": { + "@alloc/quick-lru": "^5.2.0", + "arg": "^5.0.2", + "chokidar": "^3.5.3", + "didyoumean": "^1.2.2", + "dlv": "^1.1.3", + "fast-glob": "^3.3.0", + "glob-parent": "^6.0.2", + "is-glob": "^4.0.3", + "jiti": "^1.19.1", + "lilconfig": "^2.1.0", + "micromatch": "^4.0.5", + "normalize-path": "^3.0.0", + "object-hash": "^3.0.0", + "picocolors": "^1.0.0", + "postcss": "^8.4.23", + "postcss-import": "^15.1.0", + "postcss-js": "^4.0.1", + "postcss-load-config": "^4.0.1", + "postcss-nested": "^6.0.1", + "postcss-selector-parser": "^6.0.11", + "resolve": "^1.22.2", + "sucrase": "^3.32.0" + }, + "bin": { + "tailwind": "lib/cli.js", + "tailwindcss": "lib/cli.js" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tailwindcss-animate": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/tailwindcss-animate/-/tailwindcss-animate-1.0.7.tgz", + "integrity": "sha512-bl6mpH3T7I3UFxuvDEXLxy/VuFxBk5bbzplh7tXI68mwMokNYd1t9qPBHlnyTwfa4JGC4zP516I1hYYtQ/vspA==", + "peerDependencies": { + "tailwindcss": ">=3.0.0 || insiders" + } + }, + "node_modules/tapable": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true + }, + "node_modules/thenify": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", + "dependencies": { + "any-promise": "^1.0.0" + } + }, + "node_modules/thenify-all": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", + "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", + "dependencies": { + "thenify": ">= 3.1.0 < 4" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/ts-api-utils": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.3.tgz", + "integrity": "sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg==", + "dev": true, + "engines": { + "node": ">=16.13.0" + }, + "peerDependencies": { + "typescript": ">=4.2.0" + } + }, + "node_modules/ts-interface-checker": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", + "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==" + }, + "node_modules/tsconfig-paths": { + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", + "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", + "dev": true, + "dependencies": { + "@types/json5": "^0.0.29", + "json5": "^1.0.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + } + }, + "node_modules/tslib": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz", + "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==" + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typed-array-buffer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz", + "integrity": "sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.1", + "is-typed-array": "^1.1.10" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typed-array-byte-length": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz", + "integrity": "sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "has-proto": "^1.0.1", + "is-typed-array": "^1.1.10" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-byte-offset": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz", + "integrity": "sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "has-proto": "^1.0.1", + "is-typed-array": "^1.1.10" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-length": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz", + "integrity": "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "is-typed-array": "^1.1.9" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typescript": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", + "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/unbox-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", + "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-bigints": "^1.0.2", + "has-symbols": "^1.0.3", + "which-boxed-primitive": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true + }, + "node_modules/update-browserslist-db": { + "version": "1.0.13", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", + "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dev": true, + "dependencies": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-builtin-type": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.1.3.tgz", + "integrity": "sha512-YmjsSMDBYsM1CaFiayOVT06+KJeXf0o5M/CAd4o1lTadFAtacTUM49zoYxr/oroopFDfhvN6iEcBxUyc3gvKmw==", + "dev": true, + "dependencies": { + "function.prototype.name": "^1.1.5", + "has-tostringtag": "^1.0.0", + "is-async-function": "^2.0.0", + "is-date-object": "^1.0.5", + "is-finalizationregistry": "^1.0.2", + "is-generator-function": "^1.0.10", + "is-regex": "^1.1.4", + "is-weakref": "^1.0.2", + "isarray": "^2.0.5", + "which-boxed-primitive": "^1.0.2", + "which-collection": "^1.0.1", + "which-typed-array": "^1.1.9" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-collection": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.1.tgz", + "integrity": "sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A==", + "dev": true, + "dependencies": { + "is-map": "^2.0.1", + "is-set": "^2.0.1", + "is-weakmap": "^2.0.1", + "is-weakset": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.13.tgz", + "integrity": "sha512-P5Nra0qjSncduVPEAr7xhoF5guty49ArDTwzJ/yNuPIbZppyRxFQsRCWrocxIY+CnMVG+qfbU2FmDKyvSGClow==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.4", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/yaml": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.4.tgz", + "integrity": "sha512-8aAvwVUSHpfEqTQ4w/KMlf3HcRdt50E5ODIQJBw1fQ5RL34xabzxtUlzTXVqc4rkZsPbvrXKWnABCD7kWSmocA==", + "engines": { + "node": ">= 14" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/projects/Gen-AI-Quiz-Application/package.json b/projects/Gen-AI-Quiz-Application/package.json new file mode 100644 index 000000000..8f4228d77 --- /dev/null +++ b/projects/Gen-AI-Quiz-Application/package.json @@ -0,0 +1,36 @@ +{ + "name": "quiz", + "version": "0.1.0", + "private": true, + "scripts": { + "dev": "next dev", + "build": "next build", + "start": "next start", + "lint": "next lint" + }, + "dependencies": { + "@google/generative-ai": "^0.1.3", + "@radix-ui/react-slot": "^1.0.2", + "class-variance-authority": "^0.7.0", + "clsx": "^2.1.0", + "lucide-react": "^0.303.0", + "next": "14.2.10", + "react": "^18", + "react-dom": "^18", + "react-icons": "^4.12.0", + "react-toastify": "^9.1.3", + "tailwind-merge": "^2.2.0", + "tailwindcss-animate": "^1.0.7" + }, + "devDependencies": { + "@types/node": "^20", + "@types/react": "^18", + "@types/react-dom": "^18", + "autoprefixer": "^10.0.1", + "eslint": "^8", + "eslint-config-next": "14.0.4", + "postcss": "^8", + "tailwindcss": "^3.3.0", + "typescript": "^5" + } +} diff --git a/projects/Gen-AI-Quiz-Application/postcss.config.js b/projects/Gen-AI-Quiz-Application/postcss.config.js new file mode 100644 index 000000000..33ad091d2 --- /dev/null +++ b/projects/Gen-AI-Quiz-Application/postcss.config.js @@ -0,0 +1,6 @@ +module.exports = { + plugins: { + tailwindcss: {}, + autoprefixer: {}, + }, +} diff --git a/projects/Gen-AI-Quiz-Application/public/logo.ico b/projects/Gen-AI-Quiz-Application/public/logo.ico new file mode 100644 index 000000000..9d23c31a5 Binary files /dev/null and b/projects/Gen-AI-Quiz-Application/public/logo.ico differ diff --git a/projects/Gen-AI-Quiz-Application/public/next.svg b/projects/Gen-AI-Quiz-Application/public/next.svg new file mode 100644 index 000000000..5174b28c5 --- /dev/null +++ b/projects/Gen-AI-Quiz-Application/public/next.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/projects/Gen-AI-Quiz-Application/public/vercel.svg b/projects/Gen-AI-Quiz-Application/public/vercel.svg new file mode 100644 index 000000000..d2f842227 --- /dev/null +++ b/projects/Gen-AI-Quiz-Application/public/vercel.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/projects/Gen-AI-Quiz-Application/src/app/favicon.ico b/projects/Gen-AI-Quiz-Application/src/app/favicon.ico new file mode 100644 index 000000000..9d23c31a5 Binary files /dev/null and b/projects/Gen-AI-Quiz-Application/src/app/favicon.ico differ diff --git a/projects/Gen-AI-Quiz-Application/src/app/globals.css b/projects/Gen-AI-Quiz-Application/src/app/globals.css new file mode 100644 index 000000000..b6355f139 --- /dev/null +++ b/projects/Gen-AI-Quiz-Application/src/app/globals.css @@ -0,0 +1,327 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; + +@layer base { + :root { + --background: 0 0% 100%; + --foreground: 222.2 84% 4.9%; + + --card: 0 0% 100%; + --card-foreground: 222.2 84% 4.9%; + + --popover: 0 0% 100%; + --popover-foreground: 222.2 84% 4.9%; + + --primary: 222.2 47.4% 11.2%; + --primary-foreground: 210 40% 98%; + + --secondary: 210 40% 96.1%; + --secondary-foreground: 222.2 47.4% 11.2%; + + --muted: 210 40% 96.1%; + --muted-foreground: 215.4 16.3% 46.9%; + + --accent: 210 40% 96.1%; + --accent-foreground: 222.2 47.4% 11.2%; + + --destructive: 0 84.2% 60.2%; + --destructive-foreground: 210 40% 98%; + + --border: 214.3 31.8% 91.4%; + --input: 214.3 31.8% 91.4%; + --ring: 222.2 84% 4.9%; + + --radius: 0.5rem; + } + + .dark { + --background: 222.2 84% 4.9%; + --foreground: 210 40% 98%; + + --card: 222.2 84% 4.9%; + --card-foreground: 210 40% 98%; + + --popover: 222.2 84% 4.9%; + --popover-foreground: 210 40% 98%; + + --primary: 210 40% 98%; + --primary-foreground: 222.2 47.4% 11.2%; + + --secondary: 217.2 32.6% 17.5%; + --secondary-foreground: 210 40% 98%; + + --muted: 217.2 32.6% 17.5%; + --muted-foreground: 215 20.2% 65.1%; + + --accent: 217.2 32.6% 17.5%; + --accent-foreground: 210 40% 98%; + + --destructive: 0 62.8% 30.6%; + --destructive-foreground: 210 40% 98%; + + --border: 217.2 32.6% 17.5%; + --input: 217.2 32.6% 17.5%; + --ring: 212.7 26.8% 83.9%; + } +} + +@layer base { + * { + @apply border-border; + } + body { + @apply bg-background text-foreground; + } +} + +@import url("https://fonts.googleapis.com/css2?family=Fira+Sans:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap"); +* { + margin: 0; + padding: 0; + box-sizing: border-box; + font-family: "Fira Sans", sans-serif; + font-family: "Poppins", sans-serif; +} + +:root { + --textColor: #6b4c4c; + --primaryColor: #e19f9f; +} +/* Firefox */ +* { + scrollbar-width: thin; + scrollbar-color: #6b4c4c #ffffff; +} + +/* Chrome, Edge and Safari */ +*::-webkit-scrollbar { + height: 7px; + width: 0px; +} +*::-webkit-scrollbar-track { + border-radius: 7px; + background-color: #e19f9f; +} + +*::-webkit-scrollbar-track:hover { + background-color: #ff7676; +} + +*::-webkit-scrollbar-track:active { + background-color: #e19f9f; +} + +*::-webkit-scrollbar-thumb { + border-radius: 6px; + background-color: #6b4c4c; +} + +*::-webkit-scrollbar-thumb:hover { + background-color: #6b4c4c; +} + +*::-webkit-scrollbar-thumb:active { + background-color: #6b4c4c; +} + +body { + width: 100%; + display: flex; + height: 100vh; + align-items: center; + background: var(--primaryColor); + justify-content: center; +} + +.quizAppWrapper { + width: 100%; + height: 80vh; + background: #fff; + border-radius: 2rem; + @apply max-w-[90vw] md:max-w-[70vw] overflow-y-auto overflow-x-hidden relative +} + +.title { + margin-top: 2rem; + color: var(--textColor); + text-align: center; + font-weight: 700; + font-size: clamp(1.5rem, 5vw, 3rem); +} + +.categories { + margin-left: 1.3rem; + margin-top: 0.5rem; + color: var(--textColor); + font-size: clamp(1rem, 5vw, 1.5rem); +} + +.searchWraper { + display: flex; + align-items: center; + justify-content: space-between; +} + +.search-box { + width: fit-content; + height: fit-content; + position: relative; + margin-right: 1.3rem; +} +.input-search { + height: 50px; + width: 50px; + border-style: none; + padding: 10px; + font-size: 18px; + letter-spacing: 2px; + outline: none; + border-radius: 25px; + transition: all 0.5s ease-in-out; + background-color: var(--primaryColor); + padding-right: 40px; + color: var(--textColor); +} +.input-search::placeholder { + color: var(--textColor); + font-size: 18px; + letter-spacing: 1px; + font-weight: 400; +} +.btn-search { + width: 50px; + height: 50px; + border-style: none; + font-size: 20px; + font-weight: bold; + outline: none; + cursor: pointer; + border-radius: 50%; + position: absolute; + right: 0px; + color: var(--textColor); + background-color: transparent; + pointer-events: painted; + @apply flex items-center justify-center +} +.btn-search:focus ~ .input-search { + width: 300px; + border-radius: 0px; + background-color: transparent; + border-bottom: 1px solid var(--primaryColor); + transition: all 500ms cubic-bezier(0, 0.11, 0.35, 2); +} +.input-search:focus { + width: 300px; + border-radius: 0px; + background-color: transparent; + border-bottom: 1px solid var(--primaryColor); + transition: all 500ms cubic-bezier(0, 0.11, 0.35, 2); +} + +.quizCategories { + margin-top: 2rem; + place-items: center; + height: auto; + overflow-y: auto; + @apply mb-8 +} + +figure { + display: grid; + border-radius: 1rem; + overflow: hidden; + cursor: pointer; + height: 10rem !important; + @apply md:w-[16rem] w-full +} +figure > * { + grid-area: 1/1; + transition: 0.4s; + height: 10rem !important; + object-fit: cover; + @apply md:w-[16rem] w-full +} +figure figcaption { + display: grid; + align-items: end; + font-family: sans-serif; + font-size: 2rem; + font-weight: bold; + color: #fff; + padding: 0.75rem; + background: rgba(0, 0, 0, 90%); + clip-path: inset(0 var(--_i, 100%) 0 0); + -webkit-mask: linear-gradient(#000 0 0), linear-gradient(#000 0 0); + -webkit-mask-composite: xor; + -webkit-mask-clip: text, padding-box; + margin: -1px; +} +figure:hover figcaption { + --_i: 0%; +} +figure:hover img { + transform: scale(1.2); +} +@supports not (-webkit-mask-clip: text) { + figure figcaption { + -webkit-mask: none; + color: #fff; + } +} + +.notFound{ + @apply w-full text-center flex justify-center items-center flex-col +} + +.quizDailog{ + @apply h-full w-full left-0 top-0 bg-white fixed +} + +.quizDailog header{ + @apply py-4 shadow-md flex justify-between items-center px-5 flex-wrap +} + +.quizDailog header h5{ + @apply text-[2rem] tracking-wider font-semibold text-[#ff7676] +} + +.quizDailog footer{ + @apply absolute bottom-0 left-0 flex justify-between items-center h-[5rem] border-t w-full px-4 +} + +.quizDailog footer .left{ + @apply text-[#ff7676] +} + +.quizDailog footer .left span{ + @apply font-bold text-[##ff7676] +} + +.quizDailog main{ + @apply px-6 +} +.quizDailog main h1{ + @apply text-[1.5rem] md:text-[1.8rem] mt-3 text-[#49286c] +} + +.optionsBox{ + @apply h-full w-full mt-4 +} + +.optionsBox .option{ + @apply w-full bg-[#ff7676]/30 border-[#ff7676] border-2 cursor-pointer flex items-center mb-4 rounded-md py-2.5 px-4 text-[1.2rem] +} + +.correct{ + @apply !bg-emerald-400/50 !border-emerald-600 +} + +.wrong{ + @apply !bg-red-400/50 !border-red-600 +} + +.result{ + @apply fixed h-full w-full top-0 left-0 bg-white justify-center items-center flex-col text-[1.5rem] font-semibold text-[#ff7676] +} \ No newline at end of file diff --git a/projects/Gen-AI-Quiz-Application/src/app/layout.tsx b/projects/Gen-AI-Quiz-Application/src/app/layout.tsx new file mode 100644 index 000000000..08b34a3f2 --- /dev/null +++ b/projects/Gen-AI-Quiz-Application/src/app/layout.tsx @@ -0,0 +1,38 @@ +import type { Metadata } from "next"; +import { Inter } from "next/font/google"; +import "./globals.css"; +import { ToastContainer } from "react-toastify"; +import "react-toastify/ReactToastify.min.css"; + +const inter = Inter({ subsets: ["latin"] }); + +export const metadata: Metadata = { + title: "AI QUIZ APP", + description: "This is a quiz application created by SVM.", +}; + +export default function RootLayout({ + children, +}: { + children: React.ReactNode; +}) { + return ( + + + {children} + + + + ); +} diff --git a/projects/Gen-AI-Quiz-Application/src/app/page.tsx b/projects/Gen-AI-Quiz-Application/src/app/page.tsx new file mode 100644 index 000000000..af3674467 --- /dev/null +++ b/projects/Gen-AI-Quiz-Application/src/app/page.tsx @@ -0,0 +1,375 @@ +"use client"; +import { categories } from "@/categories"; +import { Button } from "@/components/ui/button"; +import { createPrompt, generateQuestion } from "@/lib/ai"; +import { string_between_strings } from "@/lib/common"; +import { Crown, Frown, RotateCcw, Search } from "lucide-react"; +import { useEffect, useState } from "react"; +import { toast } from "react-toastify"; +export default function Home() { + const [categoriesData, setCategoriesData] = useState(categories); + const [search, setSearch] = useState(""); + const [hasError, setHasError] = useState(false); + const [isOpen, setIsOpen] = useState(false); + const [isLoading, setIsLoading] = useState(true); + const [correctAns, setCorrectAns] = useState(false); + const [result, setResult] = useState(false); + const [currentCate, setCurrentCate] = useState(""); + const [selectedOption, setSelectedOption] = useState(""); + const [currentQuestion, setCurrentQuestion] = useState(1); + const [time, setTime] = useState(10); + const [quizData, setQuizData] = useState({ + question: "", + options: { + a: "", + b: "", + c: "", + d: "", + }, + correctAnswer: "", + currentQuestion: 1, + totalCorrectAnswers: 0, + }); + + const searchCategory = () => { + let searchedCate = categories.filter((cate) => { + return cate.name.toLowerCase().includes(search.toLowerCase()); + }); + setCategoriesData(searchedCate); + searchedCate.length == 0 ? setHasError(true) : setHasError(false); + }; + + const startTimer = () => { + if (time > 0) { + setTime(time - 1); + } + } + + useEffect(() => { + setTimeout(() => { + startTimer() + }, 1000) + }, [time]) + + const createQuiz = async (title: string, currentQuestion: number) => { + setSelectedOption(""); + setIsLoading(true); + setCurrentCate(title); + setIsOpen(true); + setCorrectAns(false); + setCurrentQuestion(currentQuestion); + let res: any = await createQuestion(title); + let question = string_between_strings("[[", "]]", res); + let opt1 = string_between_strings("$$", "$$", res); + let opt2 = string_between_strings("@@", "@@", res); + let opt3 = string_between_strings("##", "##", res); + let opt4 = string_between_strings("&&", "&&", res); + let correctAns = string_between_strings("~~~", "~~~", res); + + setQuizData({ + ...quizData, + question, + options: { a: opt1, b: opt2, c: opt3, d: opt4 }, + correctAnswer: correctAns, + currentQuestion: currentQuestion, + }); + setIsLoading(false); + setTime(10) + startTimer(); + }; + + const createQuestion = async (title: string) => { + let prompt: any = await createPrompt(title); + if (prompt.status) { + let exactPrompt = string_between_strings( + "[[", + "]]", + prompt.generatedPrompt + ); + let res = await generateQuestion(exactPrompt); + if (res.status) { + return res.question; + } else { + toast.error( + "Question Can't be generated. Something went wrong." + ); + } + } else { + toast.error("Question Can't be generated. Something went wrong."); + } + }; + + const checkAnswer = (ans: string, option: string) => { + if (ans == quizData.correctAnswer) { + setQuizData({ + ...quizData, + totalCorrectAnswers: quizData.totalCorrectAnswers + 1, + }); + setSelectedOption(option); + if (quizData.currentQuestion == 10) { + setResult(true); + } + } else { + document.querySelectorAll(".optionsBox .option").forEach((opt) => { + if (!opt.classList.contains("correct")) { + opt.classList.add("wrong"); + } + }); + setCorrectAns(true); + if (quizData.currentQuestion == 10) { + setResult(true); + } + } + }; + + return ( + <> +
+
+

AI Powered Quiz App

+
+
+ +
+

Quiz Application

+
+

Categories:

+
+ + { + setSearch(e.target.value); + }} + onKeyUp={(e) => { + searchCategory(); + }} + /> +
+
+ + {hasError ? ( + <> +
+ +
+ Category Not Found +
+
+ + ) : ( +
+ {categoriesData.map((cate, i) => { + return ( + <> +
{ + createQuiz(cate.name, 1); + }} + > + {`${cate.name}`} +
+ Category: {cate.name} +
+
+ + ); + })} +
+ )} + +
+
+
GenQuiz
+
+ {/* */} + +
+
+
+ {isLoading ? ( + <> +
+
+
+
+
+
+
+ + ) : ( + <> +

+ Question: {quizData.question} +

+ +
+
+ checkAnswer(quizData.options.a, "a") + } + > + A)  {quizData.options.a} +
+
+ checkAnswer(quizData.options.b, "b") + } + > + B)  {quizData.options.b} +
+
+ checkAnswer(quizData.options.c, "c") + } + > + C)  {quizData.options.c} +
+
+ checkAnswer(quizData.options.d, "d") + } + > + D)  {quizData.options.d} +
+
+
+ Correct Answer: + {quizData.correctAnswer} +
+ + )} +
+
+
+

+ {quizData.currentQuestion} out of{" "} + 10 +

+
+
+ + +
+
+
+ +
+ +

+ Congrats! +
You have answered { + quizData.totalCorrectAnswers + }{" "} + / 10 right! +

+ +
+
+ + ); +} diff --git a/projects/Gen-AI-Quiz-Application/src/categories.ts b/projects/Gen-AI-Quiz-Application/src/categories.ts new file mode 100644 index 000000000..302d7ef88 --- /dev/null +++ b/projects/Gen-AI-Quiz-Application/src/categories.ts @@ -0,0 +1,38 @@ +export let categories = [ + { + name: "Privacy Regulations Compliance", + imageURL: "https://img.freepik.com/premium-vector/quiz-logo-with-speech-bubble-icon_149152-811.jpg", + }, + { + name: "Ethical Data Usage", + imageURL: "https://img.freepik.com/premium-vector/quiz-logo-with-speech-bubble-icon_149152-811.jpg", + }, + { + name: "Digital Forensics", + imageURL: "https://img.freepik.com/premium-vector/quiz-logo-with-speech-bubble-icon_149152-811.jpg", + }, + { + name: "Data Protection Laws", + imageURL: "https://img.freepik.com/premium-vector/quiz-logo-with-speech-bubble-icon_149152-811.jpg", + }, + { + name: "GDPR Compliance", + imageURL: "https://img.freepik.com/premium-vector/quiz-logo-with-speech-bubble-icon_149152-811.jpg", + }, + { + name: "Cybersecurity Ethics", + imageURL: "https://img.freepik.com/premium-vector/quiz-logo-with-speech-bubble-icon_149152-811.jpg", + }, + { + name: "Information Security Policies", + imageURL: "https://img.freepik.com/premium-vector/quiz-logo-with-speech-bubble-icon_149152-811.jpg", + }, + { + name: "Data Privacy Best Practices", + imageURL: "https://img.freepik.com/premium-vector/quiz-logo-with-speech-bubble-icon_149152-811.jpg", + }, + { + name: "Digital Rights Management", + imageURL: "https://img.freepik.com/premium-vector/quiz-logo-with-speech-bubble-icon_149152-811.jpg", + } +]; diff --git a/projects/Gen-AI-Quiz-Application/src/components/ui/button.tsx b/projects/Gen-AI-Quiz-Application/src/components/ui/button.tsx new file mode 100644 index 000000000..0ba427735 --- /dev/null +++ b/projects/Gen-AI-Quiz-Application/src/components/ui/button.tsx @@ -0,0 +1,56 @@ +import * as React from "react" +import { Slot } from "@radix-ui/react-slot" +import { cva, type VariantProps } from "class-variance-authority" + +import { cn } from "@/lib/utils" + +const buttonVariants = cva( + "inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50", + { + variants: { + variant: { + default: "bg-primary text-primary-foreground hover:bg-primary/90", + destructive: + "bg-destructive text-destructive-foreground hover:bg-destructive/90", + outline: + "border border-input bg-background hover:bg-accent hover:text-accent-foreground", + secondary: + "bg-secondary text-secondary-foreground hover:bg-secondary/80", + ghost: "hover:bg-accent hover:text-accent-foreground", + link: "text-primary underline-offset-4 hover:underline", + }, + size: { + default: "h-10 px-4 py-2", + sm: "h-9 rounded-md px-3", + lg: "h-11 rounded-md px-8", + icon: "h-10 w-10", + }, + }, + defaultVariants: { + variant: "default", + size: "default", + }, + } +) + +export interface ButtonProps + extends React.ButtonHTMLAttributes, + VariantProps { + asChild?: boolean +} + +const Button = React.forwardRef( + ({ className, variant, size, asChild = false, ...props }, ref) => { + const Comp = asChild ? Slot : "button" + return ( + + ) + } +) +Button.displayName = "Button" + +export { Button, buttonVariants } diff --git a/projects/Gen-AI-Quiz-Application/src/lib/ai.ts b/projects/Gen-AI-Quiz-Application/src/lib/ai.ts new file mode 100644 index 000000000..d575e0f06 --- /dev/null +++ b/projects/Gen-AI-Quiz-Application/src/lib/ai.ts @@ -0,0 +1,40 @@ +import { GoogleGenerativeAI } from "@google/generative-ai"; + +const genAI = new GoogleGenerativeAI(""); +const model = genAI.getGenerativeModel({ model: "gemini-pro" }); + +export const createPrompt = async (title: string) => { + try { + const prompt = `Generate only one prompt not question for creating quiz question topic is ${title} and start prompt just after [[ and end the prompt with ]]`; + const result = await model.generateContent(prompt); + const response = await result.response; + const generatedPrompt = response.text(); + return { + status: true, + generatedPrompt, + } + } catch (error: any) { + return { + status: false, + message: error.message + } + } +}; + +export const generateQuestion = async (generatedPrompt: string) => { + try { + const prompt = `I want only one question. ${generatedPrompt} and start question just after [[ and end the question with ]]. And also give me the 4 options and answer. Answer should be one of the option without any special symbol. 1st option starts with $$ and end with $$. 2nd option starts with @@ and end with @@. 3rd option starts with ## and end with ##. 4th option starts with && and end with &&. Correct Answer starts with ~~~ and end with ~~~`; + const result = await model.generateContent(prompt); + const response = await result.response; + const question = response.text(); + return { + status: true, + question, + } + } catch (error: any) { + return { + status: false, + message: error.message + } + } +}; diff --git a/projects/Gen-AI-Quiz-Application/src/lib/common.ts b/projects/Gen-AI-Quiz-Application/src/lib/common.ts new file mode 100644 index 000000000..d4f789dd6 --- /dev/null +++ b/projects/Gen-AI-Quiz-Application/src/lib/common.ts @@ -0,0 +1,4 @@ +export function string_between_strings(startStr:string, endStr:string, str:string) { + let pos = str.indexOf(startStr) + startStr.length; + return str.substring(pos, str.indexOf(endStr, pos)); +} \ No newline at end of file diff --git a/projects/Gen-AI-Quiz-Application/src/lib/utils.ts b/projects/Gen-AI-Quiz-Application/src/lib/utils.ts new file mode 100644 index 000000000..d084ccade --- /dev/null +++ b/projects/Gen-AI-Quiz-Application/src/lib/utils.ts @@ -0,0 +1,6 @@ +import { type ClassValue, clsx } from "clsx" +import { twMerge } from "tailwind-merge" + +export function cn(...inputs: ClassValue[]) { + return twMerge(clsx(inputs)) +} diff --git a/projects/Gen-AI-Quiz-Application/tailwind.config.js b/projects/Gen-AI-Quiz-Application/tailwind.config.js new file mode 100644 index 000000000..7cb7e37ab --- /dev/null +++ b/projects/Gen-AI-Quiz-Application/tailwind.config.js @@ -0,0 +1,77 @@ +/** @type {import('tailwindcss').Config} */ +module.exports = { + darkMode: ["class"], + content: [ + './pages/**/*.{ts,tsx}', + './components/**/*.{ts,tsx}', + './app/**/*.{ts,tsx}', + './src/**/*.{ts,tsx}', + ], + prefix: "", + theme: { + container: { + center: true, + padding: "2rem", + screens: { + "2xl": "1400px", + }, + }, + extend: { + colors: { + border: "hsl(var(--border))", + input: "hsl(var(--input))", + ring: "hsl(var(--ring))", + background: "hsl(var(--background))", + foreground: "hsl(var(--foreground))", + primary: { + DEFAULT: "hsl(var(--primary))", + foreground: "hsl(var(--primary-foreground))", + }, + secondary: { + DEFAULT: "hsl(var(--secondary))", + foreground: "hsl(var(--secondary-foreground))", + }, + destructive: { + DEFAULT: "hsl(var(--destructive))", + foreground: "hsl(var(--destructive-foreground))", + }, + muted: { + DEFAULT: "hsl(var(--muted))", + foreground: "hsl(var(--muted-foreground))", + }, + accent: { + DEFAULT: "hsl(var(--accent))", + foreground: "hsl(var(--accent-foreground))", + }, + popover: { + DEFAULT: "hsl(var(--popover))", + foreground: "hsl(var(--popover-foreground))", + }, + card: { + DEFAULT: "hsl(var(--card))", + foreground: "hsl(var(--card-foreground))", + }, + }, + borderRadius: { + lg: "var(--radius)", + md: "calc(var(--radius) - 2px)", + sm: "calc(var(--radius) - 4px)", + }, + keyframes: { + "accordion-down": { + from: { height: "0" }, + to: { height: "var(--radix-accordion-content-height)" }, + }, + "accordion-up": { + from: { height: "var(--radix-accordion-content-height)" }, + to: { height: "0" }, + }, + }, + animation: { + "accordion-down": "accordion-down 0.2s ease-out", + "accordion-up": "accordion-up 0.2s ease-out", + }, + }, + }, + plugins: [require("tailwindcss-animate")], +} \ No newline at end of file diff --git a/projects/Gen-AI-Quiz-Application/tailwind.config.ts b/projects/Gen-AI-Quiz-Application/tailwind.config.ts new file mode 100644 index 000000000..1af3b8f01 --- /dev/null +++ b/projects/Gen-AI-Quiz-Application/tailwind.config.ts @@ -0,0 +1,20 @@ +import type { Config } from 'tailwindcss' + +const config: Config = { + content: [ + './src/pages/**/*.{js,ts,jsx,tsx,mdx}', + './src/components/**/*.{js,ts,jsx,tsx,mdx}', + './src/app/**/*.{js,ts,jsx,tsx,mdx}', + ], + theme: { + extend: { + backgroundImage: { + 'gradient-radial': 'radial-gradient(var(--tw-gradient-stops))', + 'gradient-conic': + 'conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))', + }, + }, + }, + plugins: [], +} +export default config diff --git a/projects/Gen-AI-Quiz-Application/tsconfig.json b/projects/Gen-AI-Quiz-Application/tsconfig.json new file mode 100644 index 000000000..e59724b28 --- /dev/null +++ b/projects/Gen-AI-Quiz-Application/tsconfig.json @@ -0,0 +1,27 @@ +{ + "compilerOptions": { + "target": "es5", + "lib": ["dom", "dom.iterable", "esnext"], + "allowJs": true, + "skipLibCheck": true, + "strict": true, + "noEmit": true, + "esModuleInterop": true, + "module": "esnext", + "moduleResolution": "bundler", + "resolveJsonModule": true, + "isolatedModules": true, + "jsx": "preserve", + "incremental": true, + "plugins": [ + { + "name": "next" + } + ], + "paths": { + "@/*": ["./src/*"] + } + }, + "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], + "exclude": ["node_modules"] +} diff --git a/projects/Last War Game/index.html b/projects/Last War Game/index.html new file mode 100644 index 000000000..e44c0d4a4 --- /dev/null +++ b/projects/Last War Game/index.html @@ -0,0 +1,30 @@ + + + + + + + Last War + + +
+
+

WE NEED YOU!

+

Click on each square to plant a tree. You must hurry or the factories will colonize us!

+

START GAME

+
+
+
+
+

YOU WON!

+

save the World again

+
+
+ + +
+
+
+ + + \ No newline at end of file diff --git a/projects/Last War Game/script.js b/projects/Last War Game/script.js new file mode 100644 index 000000000..901e15041 --- /dev/null +++ b/projects/Last War Game/script.js @@ -0,0 +1,124 @@ +const game = document.querySelector('.game'); +var arrFactory = []; +var arrTree = []; +var newFactory; +var interval = 800; +//var counter = 1; + +function createGame() { + for (let i = 0; i < 30; i++) { + let a = document.querySelector('.game'); + let b = document.createElement('div'); + b.classList.add('box'); + b.setAttribute('data-value', i); + a.appendChild(b); + } + +} + +function replay() { + var replay = document.querySelector('.replay'); + replay.addEventListener('click', function() { + box.forEach(function(box) { + box.classList.remove('green'); + box.classList.remove('tree'); + + }); + //counter += 1; + //document.querySelector('.counter').innerHTML = 'Level: ' + counter; + document.querySelector('.hidden').classList.add('levelUp') + let bang = document.querySelector('.won'); + newFactory = setInterval(randomFactory, 600); + bang.style.animation = 'start .6s ease-in-out'; + bang.style.top = '100%'; + }); +} + +function addTree(e) { + let c = e.target; + + if(arrTree.indexOf(c.dataset.value) == -1) { + arrTree.push(c.dataset.value); + if(arrTree.length == 30) { + clearInterval(newFactory); + + document.querySelector('.hidden').classList.remove('levelUp'); + let bang = document.querySelector('.won'); + bang.style.animation = 'won .6s ease-in-out'; + bang.style.top = '30%'; + replay(); + } + } + + + if(arrFactory.indexOf(c.dataset.value) != -1) { + arrFactory.splice(arrFactory.indexOf(c.dataset.value) ,1); + } + c.classList.remove('red'); + c.classList.remove('factory'); + c.classList.add('green'); + c.classList.add('tree'); + console.log(arrTree); +} + +function randomFactory() { + let e = Math.random() * 30; + let g = Math.floor(e); + + if(arrFactory.indexOf(box[g].dataset.value) == -1) { + arrFactory.push(box[g].dataset.value); + box[g].classList.add('red'); + box[g].classList.remove('green'); + box[g].classList.add('factory'); + if(arrFactory.length == 30) { + clearInterval(newFactory); + } + } + + if(arrTree.indexOf(box[g].dataset.value) != -1) { + arrTree.splice(arrTree.indexOf(box[g].dataset.value), 1); + } + console.log(arrFactory); +} + +var yol = document.querySelector('.yolo'); + +createGame(); + +var box = document.querySelectorAll('.box'); +// console.log(box); +var start = document.querySelector('.floating'); +start.addEventListener('click', function() { + let init = document.querySelector('.init'); + init.style.animation = 'start .5s ease-in'; + init.style.top = '100%'; + newFactory = setInterval(randomFactory, interval); +}); + +box.forEach(function(box) { + box.addEventListener('click', addTree, false); +}, false); + +function fire(e) { + console.log(e.target); + let trg = e.target; + + const itemDim = this.getBoundingClientRect(), + itemSize = { + x: itemDim.right - itemDim.left, + y: itemDim.bottom - itemDim.top, + }; + + let burst = new mojs.Burst({ + left: itemDim.left + (itemSize.x/2), + top: itemDim.top + (itemSize.y/1.7), + count: 9, + radius: {50 : 90}, + }); + burst.play(); +}; + + +box.forEach(function(box) { + box.addEventListener('click', fire); +}); \ No newline at end of file diff --git a/projects/Last War Game/style.css b/projects/Last War Game/style.css new file mode 100644 index 000000000..a213269d4 --- /dev/null +++ b/projects/Last War Game/style.css @@ -0,0 +1,220 @@ +/* { + border: 1px solid #888; +}*/ + +@import url('https://fonts.googleapis.com/css?family=Roboto'); + +:root { + --green: #9ff1a5; + --red: #ff9292; + --dim: 62px; +} + +body { + margin: 0; + padding: 0; + height: 100vh; + background-color: #f8f994; +} + +h1, h2 { + font-family: 'Roboto', sans-serif; + font-weight: bold; + color: #333; + margin: 10px; +} + +h1 { + font-size: 60px; +} + +h2 { + font-size: 37px; +} + +p { + font-family: 'Roboto', sans-serif; + font-size: 23px; + font-weight: 100; + color: #333; + margin: 10px; +} + +.bold { + font-weight: 900; +} + +.center { + position: relative; + top: 20%; + margin: 0; +} + +.center1 { + position: relative; + margin: 30px; +} + +.container { + height: 100%; + position: relative; +} + +.game { + position: absolute; + left: 0; + right: 0; + top: 0; + bottom: 0; + margin: auto; + width: 540px; + height: 650px; + border-radius: 9px; + background-color: #333; + padding: 5px; + +} + +.box { + height: 100px; + width: 100px; + float: left; + margin: 0; + padding: 0px; + text-align: center; + border-radius: 9px; + border: 4px solid #333; + background-color: #f1c97c; + + background-position: center; + background-size: 70%; + background-repeat: no-repeat; + +} + +.green { + background-color: var(--green); + animation-name: getIn; + animation-duration: .3s; + animation-timing-function: cubic-bezier(0.68, -0.55, 0.265, 1.55); +} + +.tree { + background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/Pg0KPCEtLSBHZW5lcmF0b3I6IEFkb2JlIElsbHVzdHJhdG9yIDE5LjAuMCwgU1ZHIEV4cG9ydCBQbHVnLUluIC4gU1ZHIFZlcnNpb246IDYuMDAgQnVpbGQgMCkgIC0tPg0KPHN2ZyB2ZXJzaW9uPSIxLjEiIGlkPSJDYXBhXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4Ig0KCSB2aWV3Qm94PSIwIDAgNDM1LjYzNyA0MzUuNjM3IiBzdHlsZT0iZW5hYmxlLWJhY2tncm91bmQ6bmV3IDAgMCA0MzUuNjM3IDQzNS42Mzc7IiB4bWw6c3BhY2U9InByZXNlcnZlIj4NCjxyZWN0IHg9IjIwMS44NzQiIHk9IjM1NC4wMzciIHN0eWxlPSJmaWxsOiNFREFFNzg7IiB3aWR0aD0iMzQuNCIgaGVpZ2h0PSI3NC40Ii8+DQo8cmVjdCB4PSIyMDEuODc0IiB5PSIzNTQuMDM3IiBzdHlsZT0iZmlsbDojRjlDMDk1OyIgd2lkdGg9IjEyLjgiIGhlaWdodD0iNzQuNCIvPg0KPHJlY3QgeD0iMjIxLjg3NCIgeT0iMzU0LjAzNyIgc3R5bGU9ImZpbGw6I0Q2OTM2NTsiIHdpZHRoPSIxMy42IiBoZWlnaHQ9Ijc0LjQiLz4NCjxwb2x5Z29uIHN0eWxlPSJmaWxsOiMyNEJBNzM7IiBwb2ludHM9IjcwLjY3NCwzNTQuMDM3IDEzMy4wNzQsMjc2LjQzNyA4OC4yNzQsMjc2LjQzNyAxNTguNjc0LDE3OS42MzcgMTEzLjg3NCwxNzkuNjM3IA0KCTE3OS40NzQsOTkuNjM3IDEzOS40NzQsOTkuNjM3IDIxOC42NzQsNy42MzcgMjk3Ljg3NCw5OS42MzcgMjU3Ljg3NCw5OS42MzcgMzIzLjQ3NCwxNzkuNjM3IDI3OC42NzQsMTc5LjYzNyAzNDkuMDc0LDI3Ni40MzcgDQoJMzA0LjI3NCwyNzYuNDM3IDM2Ni42NzQsMzU0LjAzNyAiLz4NCjxnPg0KCTxwb2x5Z29uIHN0eWxlPSJmaWxsOiMxQ0EzNUY7IiBwb2ludHM9Ijg4LjI3NCwyNzYuNDM3IDg4LjI3NCwyNzYuNDM3IDkzLjA3NCwyNzYuNDM3IDkzLjA3NCwyNzYuNDM3IAkiLz4NCgk8cG9seWdvbiBzdHlsZT0iZmlsbDojMUNBMzVGOyIgcG9pbnRzPSIyNTcuODc0LDk5LjYzNyAyMTcuODc0LDk5LjYzNyAyODMuNDc0LDE3OS42MzcgMzIzLjQ3NCwxNzkuNjM3IDI1Ny44NzQsOTkuNjM3IA0KCQkyOTcuODc0LDk5LjYzNyAyMTguNjc0LDcuNjM3IDE5OC42NzQsMzAuODM3IAkiLz4NCgk8cG9seWdvbiBzdHlsZT0iZmlsbDojMUNBMzVGOyIgcG9pbnRzPSIzMDQuMjc0LDI3Ni40MzcgMjY0LjI3NCwyNzYuNDM3IDMyNi42NzQsMzU0LjAzNyAzNjYuNjc0LDM1NC4wMzcgCSIvPg0KCTxwb2x5Z29uIHN0eWxlPSJmaWxsOiMxQ0EzNUY7IiBwb2ludHM9IjIzOC42NzQsMTc5LjYzNyAzMDkuMDc0LDI3Ni40MzcgMzQ5LjA3NCwyNzYuNDM3IDI3OC42NzQsMTc5LjYzNyAJIi8+DQo8L2c+DQo8Zz4NCgk8cG9seWdvbiBzdHlsZT0iZmlsbDojMzZDRTgyOyIgcG9pbnRzPSIyMzMuMDc0LDI0LjQzNyAyMTguNjc0LDcuNjM3IDEzOS40NzQsOTkuNjM3IDE2Ny40NzQsOTkuNjM3IAkiLz4NCgk8cG9seWdvbiBzdHlsZT0iZmlsbDojMzZDRTgyOyIgcG9pbnRzPSIxMzMuMDc0LDI3Ni40MzcgNzAuNjc0LDM1NC4wMzcgOTguNjc0LDM1NC4wMzcgMTYxLjA3NCwyNzYuNDM3IAkiLz4NCgk8cG9seWdvbiBzdHlsZT0iZmlsbDojMzZDRTgyOyIgcG9pbnRzPSIxMTYuMjc0LDI3Ni40MzcgMTg2LjY3NCwxNzkuNjM3IDE0MS44NzQsMTc5LjYzNyAyMDcuNDc0LDk5LjYzNyAxNzkuNDc0LDk5LjYzNyANCgkJMTEzLjg3NCwxNzkuNjM3IDE1OC42NzQsMTc5LjYzNyA4OC4yNzQsMjc2LjQzNyAJIi8+DQo8L2c+DQo8cGF0aCBzdHlsZT0iZmlsbDojM0EyNzFFOyIgZD0iTTMyMS4wNzQsMjg0LjQzN2gyOGM0LjgsMCw4LTMuMiw4LThjMC0yLjQtMC44LTQtMi40LTUuNmwtNjAtODIuNGgyOC44YzQuOCwwLDgtMy4yLDgtOA0KCWMwLTIuNC0wLjgtNC44LTIuNC02LjRsLTU0LjQtNjYuNGgyMy4yYzQuOCwwLDgtMy4yLDgtOGMwLTIuNC0wLjgtNC44LTMuMi02LjRsLTc3LjYtOTAuNGMtMy4yLTMuMi04LTQtMTEuMi0wLjhsLTAuOCwwLjgNCglsLTc5LjIsOTEuMmMtMy4yLDMuMi0yLjQsOC44LDAuOCwxMS4yYzEuNiwxLjYsMy4yLDEuNiw1LjYsMS42aDIyLjRsLTU0LjQsNjcuMmMtMi40LDMuMi0yLjQsOC44LDAuOCwxMS4yYzEuNiwwLjgsMy4yLDEuNiw0LjgsMS42DQoJaDI4LjhsLTYxLjYsODRjLTIuNCwzLjItMS42LDguOCwxLjYsMTEuMmMxLjYsMC44LDMuMiwxLjYsNC44LDEuNmgyOGwtNTIsNjQuOGMtMi40LDMuMi0yLjQsOC44LDAuOCwxMS4yYzEuNiwwLjgsMy4yLDEuNiw0LjgsMS42DQoJaDEyMy4ydjY2LjRjMCw0LjgsMy4yLDgsOCw4aDM0LjRjNC44LDAsOC0zLjIsOC04di02NS42aDEyMy4yYzQuOCwwLDgtMy4yLDgtOGMwLTEuNi0wLjgtNC0xLjYtNC44TDMyMS4wNzQsMjg0LjQzN3oNCgkgTTIyNy40NzQsNDIwLjQzN2gtMTguNHYtNTguNGgxOC40VjQyMC40Mzd6IE0yMzUuNDc0LDM0Ni4wMzdoLTE0OGw1Mi02NC44YzIuNC0zLjIsMi40LTguOC0wLjgtMTEuMmMtMS42LTAuOC0zLjItMS42LTQuOC0xLjYNCgloLTI4LjhsNjAuOC04NGMyLjQtMy4yLDEuNi04LjgtMS42LTExLjJjLTEuNi0wLjgtMy4yLTEuNi00LjgtMS42aC0yOC44bDU0LjQtNjcuMmMyLjQtMy4yLDIuNC04LjgtMC44LTExLjINCgljLTEuNi0wLjgtMy4yLTEuNi00LjgtMS42aC0yMS42bDYwLjgtNzEuMmw2MS42LDcxLjJoLTIyLjRjLTQuOCwwLTgsMy4yLTgsOGMwLDEuNiwwLjgsNCwxLjYsNC44bDU0LjQsNjcuMmgtMjhjLTQuOCwwLTgsMy4yLTgsOA0KCWMwLDEuNiwwLjgsMy4yLDEuNiw0LjhsNjAuOCw4NGgtMjkuNmMtNC44LDAtOCwzLjItOCw4YzAsMS42LDAuOCw0LDEuNiw0LjhsNTIsNjQuOEgyMzUuNDc0eiIvPg0KPGc+DQo8L2c+DQo8Zz4NCjwvZz4NCjxnPg0KPC9nPg0KPGc+DQo8L2c+DQo8Zz4NCjwvZz4NCjxnPg0KPC9nPg0KPGc+DQo8L2c+DQo8Zz4NCjwvZz4NCjxnPg0KPC9nPg0KPGc+DQo8L2c+DQo8Zz4NCjwvZz4NCjxnPg0KPC9nPg0KPGc+DQo8L2c+DQo8Zz4NCjwvZz4NCjxnPg0KPC9nPg0KPC9zdmc+DQo='); +} + +.red { + background-color: var(--red); + animation-name: getIn1; + animation-duration: .3s; + animation-timing-function: cubic-bezier(0.68, -0.55, 0.265, 1.55); +} + +.factory { + background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/Pg0KPCEtLSBHZW5lcmF0b3I6IEFkb2JlIElsbHVzdHJhdG9yIDE5LjAuMCwgU1ZHIEV4cG9ydCBQbHVnLUluIC4gU1ZHIFZlcnNpb246IDYuMDAgQnVpbGQgMCkgIC0tPg0KPHN2ZyB2ZXJzaW9uPSIxLjEiIGlkPSJDYXBhXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4Ig0KCSB2aWV3Qm94PSIwIDAgNTEyLjAwMSA1MTIuMDAxIiBzdHlsZT0iZW5hYmxlLWJhY2tncm91bmQ6bmV3IDAgMCA1MTIuMDAxIDUxMi4wMDE7IiB4bWw6c3BhY2U9InByZXNlcnZlIj4NCjxwYXRoIHN0eWxlPSJmaWxsOiNFM0UzRTM7IiBkPSJNMzc5LjAwMSwzMzguODc2di04MC4xMmwtMTIzLDgwdi04MGwtMTE2LjUsNzUuNjhsLTkuNTYtMTE4LjU2aC05Ni42MWwtMC4yNi0wLjAybC0xOS44NCwyNDYuMDENCgljMC4wOTcsMC4wMSwwLjEsMC4wMSwwLjEsMC4wMWwtMC4xLTAuMDFsLTMuMjMsNDAuMDFoMTQzaDM0OXYtMjQzTDM3OS4wMDEsMzM4Ljg3NnogTTE0OS42NzEsNDYxLjg3NkwxNDkuNjcxLDQ2MS44NzZsMC4xLTAuMDENCglMMTQ5LjY3MSw0NjEuODc2eiIvPg0KPGc+DQoJPHJlY3QgeD0iMzk5LjAwMSIgeT0iMzc4Ljg3MSIgc3R5bGU9ImZpbGw6IzREQkJFQjsiIHdpZHRoPSI2MyIgaGVpZ2h0PSI0MCIvPg0KCTxyZWN0IHg9IjI5Ni4wMDEiIHk9IjM3OC44NzEiIHN0eWxlPSJmaWxsOiM0REJCRUI7IiB3aWR0aD0iNjMiIGhlaWdodD0iNDAiLz4NCgk8cmVjdCB4PSIxOTYuMDAxIiB5PSIzNzguODcxIiBzdHlsZT0iZmlsbDojNERCQkVCOyIgd2lkdGg9IjYwIiBoZWlnaHQ9IjQwIi8+DQo8L2c+DQo8Zz4NCgk8cGF0aCBzdHlsZT0iZmlsbDojRkQ2MjQ0OyIgZD0iTTE0OS43NzEsNDYxLjg2NmwzLjIzLDQwLjAxaC0xNDNsMy4yMy00MC4wMWMwLjE1MiwwLjAxNSwxMzYuMjg3LDAuMDEsMTM2LjQ0LDAuMDFMMTQ5Ljc3MSw0NjEuODY2DQoJCXoiLz4NCgk8cG9seWdvbiBzdHlsZT0iZmlsbDojRkQ2MjQ0OyIgcG9pbnRzPSIxMjYuNDcxLDE3Mi44NjYgMTI5Ljk0MSwyMTUuODc2IDMzLjMzMSwyMTUuODc2IDMzLjA3MSwyMTUuODU2IDM2LjUzMSwxNzIuODY2IA0KCQkzNi42NzEsMTcyLjg3NiAxMjYuMzMxLDE3Mi44NzYgCSIvPg0KPC9nPg0KPHBvbHlnb24gc3R5bGU9ImZpbGw6I0UzRTNFMzsiIHBvaW50cz0iMTIzLjAwMSwxMjkuODc2IDEyNi40NzEsMTcyLjg2NiAxMjYuMzMxLDE3Mi44NzYgMzYuNjcxLDE3Mi44NzYgMzYuNTMxLDE3Mi44NjYgDQoJNDAuMDAxLDEyOS44NzYgIi8+DQo8cGF0aCBkPSJNMTk2LjAwMSw0NTEuODc2Yy01LjUyLDAtMTAsNC40OC0xMCwxMHM0LjQ4LDEwLDEwLDEwczEwLTQuNDgsMTAtMTBTMjAxLjUyMSw0NTEuODc2LDE5Ni4wMDEsNDUxLjg3NnoiLz4NCjxwYXRoIGQ9Ik01MDYuNzcsMjUwLjA4NmMtMy4yMjYtMS43NDktNy4xNDctMS41OTItMTAuMjIxLDAuNDA3bC0xMDcuNTQ4LDY5Ljk1di02MS42ODdjMC0zLjY2Ny0yLjAwOC03LjA0MS01LjIzMS04Ljc5DQoJYy0zLjIyNS0xLjc0OC03LjE0Ni0xLjU5Mi0xMC4yMjEsMC40MDdsLTEwNy41NDgsNjkuOTV2LTYxLjU2N2MwLTMuNjY2LTIuMDA3LTcuMDM5LTUuMjI5LTguNzg5DQoJYy0zLjIyMi0xLjc0OS03LjE0NC0xLjU5Ni0xMC4yMTgsMC40MDNsLTEwMi40MzYsNjYuNTQ0Yy0wLjU3OC03LjE3Mi0xNS4wMDktMTg2LjEwOC0xNS4xNDktMTg3Ljg0Mw0KCWMtMC40MTktNS4xOTQtNC43NTctOS4xOTUtOS45NjgtOS4xOTVoLTgzYy01LjIxMSwwLTkuNTQ5LDQuMDAxLTkuOTY4LDkuMTk1bC0zMCwzNzJjLTAuMjI1LDIuNzgzLDAuNzI1LDUuNTMzLDIuNjE4LDcuNTg1DQoJczQuNTU4LDMuMjE5LDcuMzUsMy4yMTljNi40NzksMCw0NjEuMTQ4LDAsNDkyLDBjNS41MjIsMCwxMC00LjQ3NywxMC0xMHYtMjQzQzUxMi4wMDEsMjU1LjIwOSw1MDkuOTkzLDI1MS44MzUsNTA2Ljc3LDI1MC4wODZ6DQoJIE0xMTkuMDk4LDIwNS44NzZINDMuOTA1bDEuODU1LTIzaDcxLjQ4NEwxMTkuMDk4LDIwNS44NzZ6IE00Mi4yOTIsMjI1Ljg3Nmg3OC40MTljMC42OTEsOC41NjMsMTcuMjUxLDIxMy45MjIsMTguMjI1LDIyNkgyNC4wNjcNCglMNDIuMjkyLDIyNS44NzZ6IE0xMTMuNzc2LDEzOS44NzZsMS44NTUsMjNINDcuMzcybDEuODU1LTIzSDExMy43NzZ6IE0yMC44NDEsNDkxLjg3NmwxLjYxMy0yMGgxMTguMDk1bDEuNjEzLDIwSDIwLjg0MXoNCgkgTTQ5Mi4wMDEsNDkxLjg3NkgxNjIuMjI3bC0xMi4yODItMTUyLjNsOTYuMDU2LTYyLjM5OXY2MS41NzljMCwzLjY2NywyLjAwOCw3LjA0MSw1LjIzMSw4Ljc5DQoJYzMuMjI2LDEuNzQ5LDcuMTQ3LDEuNTkzLDEwLjIyMS0wLjQwN2wxMDcuNTQ4LTY5Ljk1djYxLjY4N2MwLDMuNjY3LDIuMDA4LDcuMDQxLDUuMjMxLDguNzljMy4yMjMsMS43NDcsNy4xNDYsMS41OTMsMTAuMjIxLTAuNDA3DQoJbDEwNy41NDgtNjkuOTVWNDkxLjg3NnoiLz4NCjxwYXRoIGQ9Ik0xOTYuMDAxLDQyOC44NzZoNjBjNS41MjIsMCwxMC00LjQ3NywxMC0xMHYtNDBjMC01LjUyMy00LjQ3OC0xMC0xMC0xMGgtNjBjLTUuNTIyLDAtMTAsNC40NzctMTAsMTB2NDANCglDMTg2LjAwMSw0MjQuMzk5LDE5MC40NzksNDI4Ljg3NiwxOTYuMDAxLDQyOC44NzZ6IE0yMDYuMDAxLDM4OC44NzZoNDB2MjBoLTQwVjM4OC44NzZ6Ii8+DQo8cGF0aCBkPSJNMjk2LjAwMSw0MjguODc2aDYzYzUuNTIyLDAsMTAtNC40NzcsMTAtMTB2LTQwYzAtNS41MjMtNC40NzgtMTAtMTAtMTBoLTYzYy01LjUyMiwwLTEwLDQuNDc3LTEwLDEwdjQwDQoJQzI4Ni4wMDEsNDI0LjM5OSwyOTAuNDc5LDQyOC44NzYsMjk2LjAwMSw0MjguODc2eiBNMzA2LjAwMSwzODguODc2aDQzdjIwaC00M1YzODguODc2eiIvPg0KPHBhdGggZD0iTTM5OS4wMDEsNDI4Ljg3Nmg2M2M1LjUyMiwwLDEwLTQuNDc3LDEwLTEwdi00MGMwLTUuNTIzLTQuNDc4LTEwLTEwLTEwaC02M2MtNS41MjIsMC0xMCw0LjQ3Ny0xMCwxMHY0MA0KCUMzODkuMDAxLDQyNC4zOTksMzkzLjQ3OSw0MjguODc2LDM5OS4wMDEsNDI4Ljg3NnogTTQwOS4wMDEsMzg4Ljg3Nmg0M3YyMGgtNDNWMzg4Ljg3NnoiLz4NCjxwYXRoIGQ9Ik01NC4wMDEsNzkuODc2YzUuNTIyLDAsMTAtNC40NzcsMTAtMTBjMC0xNi41NDIsMTMuNDU4LTMwLDMwLTMwaDEyMmM4LjAzMiwwLDE1Ljg3Mi0zLjI3MSwyMS41MDktOC45NzUNCgljNS41NjgtNS42MzUsOC41ODMtMTMuMDU1LDguNDktMjAuODk0Yy0wLjA2NC01LjQ4Mi00LjUyOC05Ljg4MS05Ljk5Ny05Ljg4MWMtMC4wMzksMC0wLjA4LDAtMC4xMiwwDQoJYy01LjUyMiwwLjA2Ni05Ljk0Niw0LjU5Ni05Ljg4MSwxMC4xMThjMC4wMjksMi40NTItMC45MzcsNC43OTUtMi43MTksNi41OThjLTEuOTA0LDEuOTI4LTQuNTU5LDMuMDMzLTcuMjgyLDMuMDMzaC0xMjINCgljLTI3LjU3LDAtNTAsMjIuNDMtNTAsNTBDNDQuMDAxLDc1LjM5OSw0OC40NzksNzkuODc2LDU0LjAwMSw3OS44NzZ6Ii8+DQo8cGF0aCBkPSJNMjM1Ljk5LDU5Ljc1NmwtMTExLjk4OSwwLjEyYy0xNi41NDIsMC0zMCwxMy40NTgtMzAsMzBjMCw1LjUyMyw0LjQ3OCwxMCwxMCwxMHMxMC00LjQ3NywxMC0xMGMwLTUuNTE0LDQuNDg2LTEwLDEwLjAxMS0xMA0KCWwxMTEuOTg5LTAuMTJjMTYuNTQyLDAsMzAtMTMuMjQzLDMwLTI5LjUydi0wLjIzYzAtNS41MjMtNC40NzgtMTAtMTAtMTBzLTEwLDQuNDc3LTEwLDEwdjAuMjMNCglDMjQ2LjAwMSw1NS40ODUsMjQxLjUxNSw1OS43NTYsMjM1Ljk5LDU5Ljc1NnoiLz4NCjxwYXRoIGQ9Ik00NjIuMDAxLDQ1MS44NzZoLTIyNmMtNS41MjIsMC0xMCw0LjQ3Ny0xMCwxMHM0LjQ3OCwxMCwxMCwxMGgyMjZjNS41MjIsMCwxMC00LjQ3NywxMC0xMFM0NjcuNTI0LDQ1MS44NzYsNDYyLjAwMSw0NTEuODc2DQoJeiIvPg0KPHBhdGggZD0iTTcwLjAwMSwyODguODc2aDIzYzUuNTIyLDAsMTAtNC40NzcsMTAtMTBzLTQuNDc4LTEwLTEwLTEwaC0yM2MtNS41MjIsMC0xMCw0LjQ3Ny0xMCwxMFM2NC40NzksMjg4Ljg3Niw3MC4wMDEsMjg4Ljg3NnoiLz4NCjxwYXRoIGQ9Ik03MC4wMDEsMzI4Ljg3NmgyM2M1LjUyMiwwLDEwLTQuNDc3LDEwLTEwcy00LjQ3OC0xMC0xMC0xMGgtMjNjLTUuNTIyLDAtMTAsNC40NzctMTAsMTBTNjQuNDc5LDMyOC44NzYsNzAuMDAxLDMyOC44NzZ6Ii8+DQo8cGF0aCBkPSJNNzAuMDAxLDM2OC44NzZoMjNjNS41MjIsMCwxMC00LjQ3NywxMC0xMHMtNC40NzgtMTAtMTAtMTBoLTIzYy01LjUyMiwwLTEwLDQuNDc3LTEwLDEwUzY0LjQ3OSwzNjguODc2LDcwLjAwMSwzNjguODc2eiIvPg0KPHBhdGggZD0iTTkzLjAwMSwzODguODc2aC0yM2MtNS41MjIsMC0xMCw0LjQ3Ny0xMCwxMHM0LjQ3OCwxMCwxMCwxMGgyM2M1LjUyMiwwLDEwLTQuNDc3LDEwLTEwUzk4LjUyNCwzODguODc2LDkzLjAwMSwzODguODc2eiIvPg0KPGc+DQo8L2c+DQo8Zz4NCjwvZz4NCjxnPg0KPC9nPg0KPGc+DQo8L2c+DQo8Zz4NCjwvZz4NCjxnPg0KPC9nPg0KPGc+DQo8L2c+DQo8Zz4NCjwvZz4NCjxnPg0KPC9nPg0KPGc+DQo8L2c+DQo8Zz4NCjwvZz4NCjxnPg0KPC9nPg0KPGc+DQo8L2c+DQo8Zz4NCjwvZz4NCjxnPg0KPC9nPg0KPC9zdmc+DQo='); +} + +.won, .init { + z-index: 999; + position: fixed; + left: 0; + right: 0; + margin: auto; + text-align: center; + border: 8px solid #333; + border-radius: 7px; +} + +.won { + background-color: var(--green); + top: 100%; + width: 600px; + height: 300px; +} + +.init { + background-color: var(--red); + top: 30%; + width: 600px; + height: 300px; +} + +.floating { + position: relative; + animation-name: floating; + animation-iteration-count: infinite; + animation-duration: 1.5s; + animation-timing-function: ease-in-out; + cursor: pointer; + text-decoration: underline; + text-decoration-color: #333; + margin-top: 30px; +} + +.levelUp { + animation: levelUp 2.5s ease-in-out; + animation-delay: 2s; +} + +.hidden { + visibility: hidden; +} + +@keyframes won { + from {top: 100%; transform: rotate(180deg);} + to {top: 30%; transform: rotate(0deg);} +} + +@keyframes start { + from {top: 30%; transform: rotate(0deg);} + to {top: 100%; transform: rotate(180deg);} +} + +@keyframes floating { + 0% {top: 0px; transform: rotate(0deg);} + 25% {top: 5px; transform: rotate(3deg);} + 50% {top: -5px; transform: rotate(-3deg);} + 100% {top: 0px; transform: rotate(0deg);} +} + +@keyframes getIn { + from {background-size: 0%;} + to {background-size: 70%;} +} + +@keyframes getIn1 { + from {background-size: 0%;} + to {background-size: 70%;} +} + +@keyframes levelUp { + 0% {opacity: 0; visibility: visible;} + 50% {opacity: 1;} + 100% {opacity: 0; visibility: hidden;} +} + +@media (max-width: 500px) { + h1 { + font-size: 37px; + } + + .game { + width: 331px; + height: 396px; + } + + .box { + width: var(--dim); + height: var(--dim); + border: 2.1px solid #333; + } + + .won, .init { + width: 300px; + height: 400px; + } + + .init { + top: 10%; + } +} \ No newline at end of file diff --git a/projects/QR Generator/index.html b/projects/QR Generator/index.html new file mode 100644 index 000000000..55f09c42c --- /dev/null +++ b/projects/QR Generator/index.html @@ -0,0 +1,30 @@ + + + + + + + + + + +
+
+

+ QR Code Generator +

+
+
+
+ +
+
+ + + + diff --git a/projects/QR Generator/script.js b/projects/QR Generator/script.js new file mode 100644 index 000000000..b02fc9239 --- /dev/null +++ b/projects/QR Generator/script.js @@ -0,0 +1,19 @@ +let qrcode = new QRCode( + document.querySelector(".qrcode") +); +qrcode.makeCode("Why did you scan me?"); +function generateQr() { + if ( + document.querySelector("input") + .value === "" || + document.querySelector("input") + .value === " ") { + alert( + "Input Field Can not be blank!" + );} + else { + qrcode.makeCode( + document.querySelector( + "input" + ).value); +}} diff --git a/projects/QR Generator/style.css b/projects/QR Generator/style.css new file mode 100644 index 000000000..9b0b2ef2e --- /dev/null +++ b/projects/QR Generator/style.css @@ -0,0 +1,56 @@ +body { + font-family: "Ubuntu", sans-serif; + background-color: #f0f0f0; + margin: 0; + padding: 0; + display: flex; + justify-content: center; + align-items: center; + height: 100vh; +} +.container { + background-color: #fff; + box-shadow: 0px 0px 10px + rgba(0, 0, 0, 0.1); + border-radius: 5px; + padding: 20px; + text-align: center; +} +.header { + text-align: center; +} +h1 { + font-size: 28px; + margin-bottom: 10px; + color: #333; +} +hr { + border: 1px solid #ddd; + margin: 20px 0; +} +input[type="text"] { + width: 100%; + padding: 10px; + font-size: 16px; + border: 1px solid #ccc; + border-radius: 5px; + outline: none; +} +.qrcode { + margin: 20px 0; +} +button { + background-color: #007bff; + color: #fff; + padding: 10px 20px; + font-size: 16px; + border: none; + border-radius: 5px; + cursor: pointer; + outline: none; +} + +/* Hover effect for the button */ +button:hover { + background-color: #0056b3; +} diff --git a/projects/Rock Paper Scissors/Styles.css b/projects/Rock Paper Scissors/Styles.css index 940eff4a7..132bae12a 100644 --- a/projects/Rock Paper Scissors/Styles.css +++ b/projects/Rock Paper Scissors/Styles.css @@ -18,11 +18,14 @@ p { margin-bottom: 0.5rem; } -.buttons { +.buttons{ + display: flex; + justify-content: center; +} +.computer-buttons{ display: flex; justify-content: center; } - button { border: none; font-size: 3rem; @@ -34,7 +37,8 @@ button { } button:hover { - opacity: 0.7; + /* opacity: 0.7; */ + border: 3px solid black; } #rock { @@ -55,4 +59,4 @@ button:hover { #computer-score { color: #ff0000; -} +} \ No newline at end of file diff --git a/projects/Rock Paper Scissors/index.html b/projects/Rock Paper Scissors/index.html index f06a4e8f4..d5471a282 100644 --- a/projects/Rock Paper Scissors/index.html +++ b/projects/Rock Paper Scissors/index.html @@ -15,6 +15,13 @@

Rock Paper Scissors Game

+
+

Computer's move:

+
+ + + +

Your score: 0 diff --git a/projects/Rock Paper Scissors/script.js b/projects/Rock Paper Scissors/script.js index 0d27c11db..7da4ded2d 100644 --- a/projects/Rock Paper Scissors/script.js +++ b/projects/Rock Paper Scissors/script.js @@ -11,7 +11,8 @@ let computerScore = 0; buttons.forEach((button) => { button.addEventListener("click", () => { - const result = playRound(button.id, computerPlay()); + const computerSelection = computerPlay(); + const result = playRound(button.id, computerSelection); resultEl.textContent = result; }); @@ -20,7 +21,16 @@ buttons.forEach((button) => { function computerPlay() { const choices = ["rock", "paper", "scissors"]; const randomChoice = Math.floor(Math.random() * choices.length); - return choices[randomChoice]; + const computerChoice = choices[randomChoice]; + const computerbuttons = document.querySelector('.computer-buttons'); + const selectedButton = computerbuttons.querySelector(`#${choices[randomChoice]}`); + const allChildren = computerbuttons.querySelectorAll(':scope > *'); + const otherButtons = Array.from(allChildren).filter(child => child.id !== `${choices[randomChoice]}`); + selectedButton.style.border = '3px solid black'; + otherButtons.map((button)=>{ + button.style.border = '0px'; + }) + return computerChoice; } function playRound(playerSelection, computerSelection) { diff --git a/projects/Space Collision Game/img/bomb-icon-symbol-video-game.png b/projects/Space Collision Game/img/bomb-icon-symbol-video-game.png new file mode 100644 index 000000000..a20af89b6 Binary files /dev/null and b/projects/Space Collision Game/img/bomb-icon-symbol-video-game.png differ diff --git a/projects/Space Collision Game/img/pixel-art-coin-money-icon-game.png b/projects/Space Collision Game/img/pixel-art-coin-money-icon-game.png new file mode 100644 index 000000000..2f93c8508 Binary files /dev/null and b/projects/Space Collision Game/img/pixel-art-coin-money-icon-game.png differ diff --git a/projects/Space Collision Game/index.html b/projects/Space Collision Game/index.html new file mode 100644 index 000000000..91ffd88fa --- /dev/null +++ b/projects/Space Collision Game/index.html @@ -0,0 +1,23 @@ + + + + + + + Space Collision Game + + + + +

00
+ + Game Over
+ Score:

+ +
+ + + + + + \ No newline at end of file diff --git a/projects/Space Collision Game/script.js b/projects/Space Collision Game/script.js new file mode 100644 index 000000000..63bd8350c --- /dev/null +++ b/projects/Space Collision Game/script.js @@ -0,0 +1,236 @@ +const popup = document.getElementById("game-over"); +const canvas = document.querySelector('#canvas') +const c = canvas.getContext('2d') +canvas.width = innerWidth +canvas.height = innerHeight +let animation; + +// const coinImage = document.getElementById("coin"); +const coinImage = new Image(); +coinImage.src = "./img/pixel-art-coin-money-icon-game.png"; +coinImage.width = 20; + +// const bombImage = document.getElementById("bomb"); +const bombImage = new Image(); +bombImage.src = "./img/bomb-icon-symbol-video-game.png"; +bombImage.width = 5; + +let score = 0 +let strikes = 0 +document.getElementById("close-btn").onclick = () => { + document.getElementById("strikes").textContent = ''; + animate() + popup.close() +} + +const mouse = { + x: -100, + y: -100 +}; + +addEventListener("load", () => { + alert("WELCOME TO THE GAME!!! CATCH THE COIN!!") +}) + +// Event Listeners +addEventListener('mousemove', (event) => { + mouse.x = event.clientX + mouse.y = event.clientY +}) + +// addEventListener('resize', () => { +// canvas.width = innerWidth +// canvas.height = innerHeight +// init() +// animate() +// }) + +// Objects +class Particle { + constructor(x, y, radius, color, strokeColor, image) { + this.x = x + this.y = y + this.radius = radius + this.color = color + this.strokeColor = '#222222' + this.mass = 1 + this.velocity = { + x: (Math.random() - 0.5) * 2, + y: (Math.random() - 0.5) * 2 + } + this.image = coinImage + } + + draw() { + if (this.color == "red") { + c.beginPath() + c.arc(this.x, this.y, this.radius, 0, Math.PI * 2, false) + c.fillStyle = this.color + c.fill() + c.strokeStyle = this.strokeColor + c.stroke() + c.closePath() + } else { + c.drawImage(this.image, this.x, this.y, this.radius, this.radius) + } + } + + update(particles) { + for (let i = 0; i < particles.length; i++) { + if (this === particles[i]) { + continue; + } + if (collided(this.x, this.y, this.radius, particles[i].x, particles[i].y, particles[i].radius)) { + resolveCollision(this, particles[i]); + } + } + + if (collided(player.x, player.y, player.radius, this.x, this.y, this.radius)) { + // STRIKES + if (this.color == 'red') { + strikes++; + document.getElementById("strikes").textContent += '⨯'; + // GAME OVER + if (strikes >= 5) { + popup.showModal(); + document.getElementById("game-over-score").textContent = score; + score = 0 + strikes = 0 + window.cancelAnimationFrame(animation) + + } + // POINTS + } else { + score++; + } + document.querySelector('#score').textContent = (score >= 10) ? score : `0${score}`; + this.x = Math.random() * canvas.width; + this.y = Math.random() * canvas.height; + } + if (this.x - this.radius <= 0 || this.radius + this.x >= canvas.width) { + this.velocity.x = -this.velocity.x; + } + + if (this.y - this.radius <= 0 || this.radius + this.y >= canvas.height) { + this.velocity.y = -this.velocity.y; + } + this.x += this.velocity.x + this.y += this.velocity.y + this.draw() + } +} +class Player { + constructor(x, y, radius, color) { + this.x = x + this.y = y + this.radius = radius + this.color = color + } + + draw() { + c.beginPath() + // c.arc(this.x, this.y, this.radius, Math.PI/6, Math.PI /2, true) + c.ellipse(this.x, this.y, this.radius, this.radius, 1, 0, Math.PI * 2, true) + c.fillStyle = this.color + c.fill() + c.closePath() + } + + update() { + this.draw() + } +} + + + +function rotate(velocity, angle) { + const rotatedVelocities = { + x: velocity.x * Math.cos(angle) - velocity.y * Math.sin(angle), + y: velocity.x * Math.sin(angle) + velocity.y * Math.cos(angle) + }; + + return rotatedVelocities; +} + + +function resolveCollision(particle, otherParticle) { + const xVelocityDiff = particle.velocity.x - otherParticle.velocity.x; + const yVelocityDiff = particle.velocity.y - otherParticle.velocity.y; + + const xDist = otherParticle.x - particle.x; + const yDist = otherParticle.y - particle.y; + + // Prevent accidental overlap of particles + if (xVelocityDiff * xDist + yVelocityDiff * yDist >= 0) { + + // Grab angle between the two colliding particles + const angle = -Math.atan2(otherParticle.y - particle.y, otherParticle.x - particle.x); + + // Store mass in var for better readability in collision equation + const m1 = particle.mass; + const m2 = otherParticle.mass; + + // Velocity before equation + const u1 = rotate(particle.velocity, angle); + const u2 = rotate(otherParticle.velocity, angle); + + // Velocity after 1d collision equation + const v1 = { x: u1.x * (m1 - m2) / (m1 + m2) + u2.x * 2 * m2 / (m1 + m2), y: u1.y }; + const v2 = { x: u2.x * (m1 - m2) / (m1 + m2) + u1.x * 2 * m2 / (m1 + m2), y: u2.y }; + + // Final velocity after rotating axis back to original location + const vFinal1 = rotate(v1, -angle); + const vFinal2 = rotate(v2, -angle); + + // Swap particle velocities for realistic bounce effect + particle.velocity.x = vFinal1.x; + particle.velocity.y = vFinal1.y; + + otherParticle.velocity.x = vFinal2.x; + otherParticle.velocity.y = vFinal2.y; + } +} + + + +function collided(x1, y1, r1, x2, y2, r2) { + let h = Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2));// distance formula + if (h < r1 + r2) { + return true; + } + return false; +} + +let player, particles = []; +// Implementation +function init() { + player = new Player(undefined, undefined, 20, 'white'); + // good partilces + for (let i = 0; i < 10; i++) { + particles.push(new Particle(Math.random() * canvas.width, Math.random() * canvas.height, 22, '#FFD700', coinImage)); + } + // bad particles + for (let i = 0; i < 40; i++) { + particles.push(new Particle(Math.random() * canvas.width, Math.random() * canvas.height, 5, 'red', "")); + } +} + +// Animation Loop +function animate() { + animation = requestAnimationFrame(animate) + // c.clearRect(0, 0, canvas.width, canvas.height); + c.rect(0, 0, canvas.width, canvas.height); + c.fillStyle = '#00001122' + c.fill(); + + player.update(); + player.x = mouse.x; + player.y = mouse.y; + particles.forEach(particle => { + particle.update(particles); + }); + +} + +init() +animate() \ No newline at end of file diff --git a/projects/Space Collision Game/style.css b/projects/Space Collision Game/style.css new file mode 100644 index 000000000..17170baed --- /dev/null +++ b/projects/Space Collision Game/style.css @@ -0,0 +1,62 @@ +@import url("https://fonts.googleapis.com/css?family=Poppins"); + +:root { + --color: #000011; +} + +body { + font-family: "Poppins", sans-serif; + margin: 0; + overflow: hidden; + height: 100%; + width: 100%; +} + +#score-board { + margin-left: 1%; + margin-top: 1%; + position: absolute; + box-shadow: 0 0 40px #00000011; + background-color: rgb(33, 33, 33); + color: aliceblue; + padding: 1rem; + border-radius: 0.5rem; + font-family: "Poppins", sans-serif; +} + +#game-over { + text-align: center; + border-radius: 0.5rem; + z-index: 1; + border: none; + box-shadow: 0 0 5px #000000aa; + padding: 2rem 5rem; +} + +#strikes { + padding: 0; + width: max-content; + height: fit-content; + font-size: 30px; + color: red; + filter: drop-shadow(0 0 10px red); +} + +button { + background-color: var(--color); + color: white; + border-radius: 0.2rem; + padding: 0.5rem; + border: 2px solid transparent; + margin: auto; +} + +button:hover { + border: 2px solid var(--color); + background-color: transparent; + color: var(--color); +} + +img { + display: none; +} \ No newline at end of file diff --git a/projects/Space Invader/alien-cyan.png b/projects/Space Invader/alien-cyan.png new file mode 100644 index 000000000..342ee4ed3 Binary files /dev/null and b/projects/Space Invader/alien-cyan.png differ diff --git a/projects/Space Invader/alien-magenta.png b/projects/Space Invader/alien-magenta.png new file mode 100644 index 000000000..b09e0d781 Binary files /dev/null and b/projects/Space Invader/alien-magenta.png differ diff --git a/projects/Space Invader/alien-yellow.png b/projects/Space Invader/alien-yellow.png new file mode 100644 index 000000000..54ca7b707 Binary files /dev/null and b/projects/Space Invader/alien-yellow.png differ diff --git a/projects/Space Invader/alien.png b/projects/Space Invader/alien.png new file mode 100644 index 000000000..344b64f80 Binary files /dev/null and b/projects/Space Invader/alien.png differ diff --git a/projects/Space Invader/index.html b/projects/Space Invader/index.html new file mode 100644 index 000000000..0d41da9a0 --- /dev/null +++ b/projects/Space Invader/index.html @@ -0,0 +1,15 @@ + + + + + + Space Invaders + + + + + +

Space Invaders

+ + + \ No newline at end of file diff --git a/projects/Space Invader/ship.png b/projects/Space Invader/ship.png new file mode 100644 index 000000000..2abdd9d7a Binary files /dev/null and b/projects/Space Invader/ship.png differ diff --git a/projects/Space Invader/space.css b/projects/Space Invader/space.css new file mode 100644 index 000000000..17e623047 --- /dev/null +++ b/projects/Space Invader/space.css @@ -0,0 +1,8 @@ +body { + font-family:'Courier New', Courier, monospace; + text-align: center; +} + +#board { + background-color: black; +} \ No newline at end of file diff --git a/projects/Space Invader/space.js b/projects/Space Invader/space.js new file mode 100644 index 000000000..aa7de32e5 --- /dev/null +++ b/projects/Space Invader/space.js @@ -0,0 +1,209 @@ +//board +let tileSize = 32; +let rows = 16; +let columns = 16; + +let board; +let boardWidth = tileSize * columns; // 32 * 16 +let boardHeight = tileSize * rows; // 32 * 16 +let context; + +//ship +let shipWidth = tileSize*2; +let shipHeight = tileSize; +let shipX = tileSize * columns/2 - tileSize; +let shipY = tileSize * rows - tileSize*2; + +let ship = { + x : shipX, + y : shipY, + width : shipWidth, + height : shipHeight +} + +let shipImg; +let shipVelocityX = tileSize; //ship moving speed + +//aliens +let alienArray = []; +let alienWidth = tileSize*2; +let alienHeight = tileSize; +let alienX = tileSize; +let alienY = tileSize; +let alienImg; + +let alienRows = 2; +let alienColumns = 3; +let alienCount = 0; //number of aliens to defeat +let alienVelocityX = 1; //alien moving speed + +//bullets +let bulletArray = []; +let bulletVelocityY = -10; //bullet moving speed + +let score = 0; +let gameOver = false; + +window.onload = function() { + board = document.getElementById("board"); + board.width = boardWidth; + board.height = boardHeight; + context = board.getContext("2d"); //used for drawing on the board + + //draw initial ship + // context.fillStyle="green"; + // context.fillRect(ship.x, ship.y, ship.width, ship.height); + + //load images + shipImg = new Image(); + shipImg.src = "./ship.png"; + shipImg.onload = function() { + context.drawImage(shipImg, ship.x, ship.y, ship.width, ship.height); + } + + alienImg = new Image(); + alienImg.src = "./alien.png"; + createAliens(); + + requestAnimationFrame(update); + document.addEventListener("keydown", moveShip); + document.addEventListener("keyup", shoot); +} + +function update() { + requestAnimationFrame(update); + + if (gameOver) { + return; + } + + context.clearRect(0, 0, board.width, board.height); + + //ship + context.drawImage(shipImg, ship.x, ship.y, ship.width, ship.height); + + //alien + for (let i = 0; i < alienArray.length; i++) { + let alien = alienArray[i]; + if (alien.alive) { + alien.x += alienVelocityX; + + //if alien touches the borders + if (alien.x + alien.width >= board.width || alien.x <= 0) { + alienVelocityX *= -1; + alien.x += alienVelocityX*2; + + //move all aliens up by one row + for (let j = 0; j < alienArray.length; j++) { + alienArray[j].y += alienHeight; + } + } + context.drawImage(alienImg, alien.x, alien.y, alien.width, alien.height); + + if (alien.y >= ship.y) { + gameOver = true; + } + } + } + + //bullets + for (let i = 0; i < bulletArray.length; i++) { + let bullet = bulletArray[i]; + bullet.y += bulletVelocityY; + context.fillStyle="white"; + context.fillRect(bullet.x, bullet.y, bullet.width, bullet.height); + + //bullet collision with aliens + for (let j = 0; j < alienArray.length; j++) { + let alien = alienArray[j]; + if (!bullet.used && alien.alive && detectCollision(bullet, alien)) { + bullet.used = true; + alien.alive = false; + alienCount--; + score += 100; + } + } + } + + //clear bullets + while (bulletArray.length > 0 && (bulletArray[0].used || bulletArray[0].y < 0)) { + bulletArray.shift(); //removes the first element of the array + } + + //next level + if (alienCount == 0) { + //increase the number of aliens in columns and rows by 1 + score += alienColumns * alienRows * 100; //bonus points :) + alienColumns = Math.min(alienColumns + 1, columns/2 -2); //cap at 16/2 -2 = 6 + alienRows = Math.min(alienRows + 1, rows-4); //cap at 16-4 = 12 + if (alienVelocityX > 0) { + alienVelocityX += 0.2; //increase the alien movement speed towards the right + } + else { + alienVelocityX -= 0.2; //increase the alien movement speed towards the left + } + alienArray = []; + bulletArray = []; + createAliens(); + } + + //score + context.fillStyle="white"; + context.font="16px courier"; + context.fillText(score, 5, 20); +} + +function moveShip(e) { + if (gameOver) { + return; + } + + if (e.code == "ArrowLeft" && ship.x - shipVelocityX >= 0) { + ship.x -= shipVelocityX; //move left one tile + } + else if (e.code == "ArrowRight" && ship.x + shipVelocityX + ship.width <= board.width) { + ship.x += shipVelocityX; //move right one tile + } +} + +function createAliens() { + for (let c = 0; c < alienColumns; c++) { + for (let r = 0; r < alienRows; r++) { + let alien = { + img : alienImg, + x : alienX + c*alienWidth, + y : alienY + r*alienHeight, + width : alienWidth, + height : alienHeight, + alive : true + } + alienArray.push(alien); + } + } + alienCount = alienArray.length; +} + +function shoot(e) { + if (gameOver) { + return; + } + + if (e.code == "Space") { + //shoot + let bullet = { + x : ship.x + shipWidth*15/32, + y : ship.y, + width : tileSize/8, + height : tileSize/2, + used : false + } + bulletArray.push(bullet); + } +} + +function detectCollision(a, b) { + return a.x < b.x + b.width && //a's top left corner doesn't reach b's top right corner + a.x + a.width > b.x && //a's top right corner passes b's top left corner + a.y < b.y + b.height && //a's top left corner doesn't reach b's bottom left corner + a.y + a.height > b.y; //a's bottom left corner passes b's top left corner +} \ No newline at end of file diff --git a/projects/Super Mario/css/reset.css b/projects/Super Mario/css/reset.css new file mode 100644 index 000000000..cf1f92c3d --- /dev/null +++ b/projects/Super Mario/css/reset.css @@ -0,0 +1,141 @@ +/*ERIC MEYER's reset CSS*/ + +html, +body, +div, +span, +applet, +object, +iframe, +h1, +h2, +h3, +h4, +h5, +h6, +p, +blockquote, +pre, +a, +abbr, +acronym, +address, +big, +cite, +code, +del, +dfn, +img, +ins, +kbd, +q, +s, +samp, +small, +strike, +sub, +sup, +tt, +var, +b, +u, +i, +center, +dl, +dt, +dd, +ol, +ul, +li, +fieldset, +form, +label, +legend, +table, +caption, +tbody, +tfoot, +thead, +tr, +th, +td, +article, +aside, +canvas, +details, +embed, +figure, +figcaption, +footer, +header, +hgroup, +menu, +nav, +output, +ruby, +section, +summary, +time, +mark, +audio, +video { + margin: 0; + padding: 0; + border: 0; + font-size: 100%; + font: inherit; + vertical-align: baseline; +} +/* HTML5 display-role reset for older browsers */ +article, +aside, +details, +figcaption, +figure, +footer, +header, +hgroup, +menu, +nav, +section { + display: block; +} +body { + line-height: 1; + font-family: 'Montserrat', sans-serif; +} +ol, +ul { + list-style: none; +} +blockquote, +q { + quotes: none; +} +blockquote:before, +blockquote:after, +q:before, +q:after { + content: ''; + content: none; +} +table { + border-collapse: collapse; + border-spacing: 0; +} + +/*clearfix*/ + +.clrfix:before, +.clrfix:after { + content: ''; + display: table; +} + +.clrfix:after { + clear: both; +} + +.clrfix { + zoom: 1; +} diff --git a/projects/Super Mario/css/style.css b/projects/Super Mario/css/style.css new file mode 100644 index 000000000..3c0b054d7 --- /dev/null +++ b/projects/Super Mario/css/style.css @@ -0,0 +1,355 @@ +@font-face { + font-family: SuperMario256; + src: url('../fonts/SuperMario256.ttf'); +} + +.start-screen { + width: 1280px; + height: 530px; + margin: 0 auto; + border: 1px solid black; + background: url('../images/start-screen.png'); + position: relative; +} + +.editor-screen { + width: 1280px; + height: 480px; + margin: 0 auto; + border: 1px solid black; + background: url('../images/bg.png'); + position: relative; + overflow: hidden; + display: none; +} + +.game-screen { + width: 1280px; + height: 480px; + border: 1px solid black; + border-top: none; + background: url('../images/bg.png'); + display: none; + margin: 0 auto; +} + +.score-wrapper { + padding-left: 40px; + width: 1240px; + margin: 0 auto; + height: 50px; + display: none; + border: 1px solid black; + border-bottom: none; + line-height: 50px; + font-size: 20px; + background-color: #add1f3; + font-family: SuperMario256; + color: #ffffff; +} + +.life-count { + background: url('../images/mario-head.png') left center no-repeat; + width: 100px; + float: left; + padding-left: 40px; +} + +.coin-score { + background: url('../images/coin.png') left center no-repeat; + width: 150px; + float: left; + padding-left: 40px; +} + +.level-num { + width: 150px; + float: left; +} + +.total-score { + float: left; +} +.cell { + width: 31px; + height: 31px; + border: 1px solid blue; +} + +.active { + width: 31px; + height: 31px; + border: 1px solid blue; + background: red; + opacity: 0.5; +} + +.element-wrapper { + width: 1280px; + height: 130px; + background: #d2d2d2; + margin: 0 auto; + border: 1px solid black; + display: none; +} + +.platform { + width: 31px; + height: 31px; + background: url('../images/elements.png') 0 0; +} + +.coin-box { + width: 31px; + height: 31px; + background: url('../images/elements.png') -32px 0; +} + +.power-up-box { + width: 31px; + height: 31px; + background: url('../images/elements.png') -64px 0; +} + +.useless-box { + width: 31px; + height: 31px; + background: url('../images/elements.png') -96px 0; +} + +.flag-pole { + width: 31px; + height: 31px; + background: url('../images/elements.png') -128px 0; +} + +.flag { + width: 31px; + height: 31px; + background: url('../images/elements.png') -160px 0; +} + +.pipe-left { + width: 31px; + height: 31px; + background: url('../images/elements.png') -192px 0; +} + +.pipe-right { + width: 31px; + height: 31px; + background: url('../images/elements.png') -224px 0; +} + +.pipe-top-left { + width: 31px; + height: 31px; + background: url('../images/elements.png') -256px 0; +} + +.pipe-top-right { + width: 31px; + height: 31px; + background: url('../images/elements.png') -288px 0; +} + +.goomba { + width: 31px; + height: 31px; + background: url('../images/enemies.png') 0 0; +} + +.right-arrow { + width: 60px; + height: 60px; + top: 215px; + right: 0; + background: url('../images/slider-right.png'); + position: absolute; +} + +.left-arrow { + width: 60px; + height: 60px; + top: 215px; + left: 0; + background: url('../images/slider-left.png'); + position: absolute; +} + +.element-wrapper * { + margin: 10px; + float: left; +} + +.lvl-size { + clear: both; + float: left; + width: 115px; + height: 32px; + background: url('../images/lvl-size.png'); + margin-right: 10px; +} + +.grid-small-btn { + float: left; + width: 64px; + height: 32px; + background: url('../images/grid-small-btn.png'); + border: none; + margin-right: 10px; +} + +.grid-medium-btn:selected { + background: red; +} + +.grid-medium-btn { + float: left; + width: 96px; + height: 32px; + background: url('../images/grid-medium-btn.png'); + border: none; + margin-right: 10px; +} + +.grid-large-btn { + float: left; + width: 128px; + height: 32px; + background: url('../images/grid-large-btn.png'); + border: none; + margin-right: 10px; +} + +.save-map-btn { + float: right; + width: 100px; + height: 100px; + background: url('../images/save-map-btn.png'); + border: none; + border: 2px solid black; + margin-right: 10px; + margin-top: -35px; +} + +.clear-map-btn { + float: right; + width: 100px; + height: 100px; + background: url('../images/clear-map-btn.png'); + border: none; + border: 2px solid black; + margin-right: 10px; + margin-top: -35px; +} + +.levels-wrapper { + width: 1280px; + height: 530px; + margin: 0 auto; + border: 1px solid black; + position: relative; + overflow: hidden; + display: none; + background: url('../images/bg.png'); +} + +.start-btn { + width: 200px; + height: 50px; + color: #ffffff; + background: url('../images/start-btn.png'); + position: absolute; + bottom: 100px; + left: 252px; + border: 2px solid black; +} + +.editor-btn { + width: 200px; + height: 50px; + background: url('../images/editor-btn.png'); + position: absolute; + bottom: 100px; + left: 530px; + color: #ffffff; + border: 2px solid black; +} + +.created-btn { + width: 200px; + height: 50px; + background: url('../images/saved-btn.png'); + position: absolute; + bottom: 100px; + left: 810px; + color: #ffffff; + border: 2px solid black; +} + +.back-btn { + width: 200px; + height: 50px; + background: url('../images/back-btn.png'); + color: #ffffff; + border: 2px solid black; + margin: 10px; + display: none; +} + +.level-btn { + font-family: SuperMario256; + font-size: 25px; + float: left; + line-height: 50px; + text-align: center; + width: 248px; + height: 50px; + color: #ffffff; + border: 2px solid black; + margin: 2px; + text-transform: uppercase; + font-weight: bold; + background: #15a7d9; +} + +.delete-all-btn { + width: 100px; + height: 100px; + background: url('../images/delete-all-btn.png'); + color: #ffffff; + border: 2px solid black; + margin: 10px; + position: absolute; + bottom: 10px; + right: 10px; +} + +.btn-wrapper { + width: 1280px; + height: 100px; + margin: 0 auto; +} + +.no-maps { + width: 1000px; + text-align: center; + font-family: SuperMario256; + font-size: 25px; + margin: 0 auto; + color: #ffffff; + background: #5fb952; + border: 2px solid black; +} + +.loading-percentage { + font-size: 60px; + font-family: SuperMario256; + text-align: center; + padding: 100px; +} + +.fb-comments { + margin: 0 auto; +} diff --git a/projects/Super Mario/fonts/SuperMario256.ttf b/projects/Super Mario/fonts/SuperMario256.ttf new file mode 100644 index 000000000..5e1ccd4be Binary files /dev/null and b/projects/Super Mario/fonts/SuperMario256.ttf differ diff --git a/projects/Super Mario/images/back-btn.png b/projects/Super Mario/images/back-btn.png new file mode 100644 index 000000000..890941c50 Binary files /dev/null and b/projects/Super Mario/images/back-btn.png differ diff --git a/projects/Super Mario/images/bg.png b/projects/Super Mario/images/bg.png new file mode 100644 index 000000000..fa0b0852a Binary files /dev/null and b/projects/Super Mario/images/bg.png differ diff --git a/projects/Super Mario/images/bullet.png b/projects/Super Mario/images/bullet.png new file mode 100644 index 000000000..4fb3fc842 Binary files /dev/null and b/projects/Super Mario/images/bullet.png differ diff --git a/projects/Super Mario/images/clear-map-btn.png b/projects/Super Mario/images/clear-map-btn.png new file mode 100644 index 000000000..ba3d62a01 Binary files /dev/null and b/projects/Super Mario/images/clear-map-btn.png differ diff --git a/projects/Super Mario/images/coin.png b/projects/Super Mario/images/coin.png new file mode 100644 index 000000000..d676d54da Binary files /dev/null and b/projects/Super Mario/images/coin.png differ diff --git a/projects/Super Mario/images/delete-all-btn.png b/projects/Super Mario/images/delete-all-btn.png new file mode 100644 index 000000000..5fb43335d Binary files /dev/null and b/projects/Super Mario/images/delete-all-btn.png differ diff --git a/projects/Super Mario/images/editor-btn.png b/projects/Super Mario/images/editor-btn.png new file mode 100644 index 000000000..b5c37b82c Binary files /dev/null and b/projects/Super Mario/images/editor-btn.png differ diff --git a/projects/Super Mario/images/elements.png b/projects/Super Mario/images/elements.png new file mode 100644 index 000000000..4e115bb8f Binary files /dev/null and b/projects/Super Mario/images/elements.png differ diff --git a/projects/Super Mario/images/enemies.png b/projects/Super Mario/images/enemies.png new file mode 100644 index 000000000..c7a273ed6 Binary files /dev/null and b/projects/Super Mario/images/enemies.png differ diff --git a/projects/Super Mario/images/flag-pole.png b/projects/Super Mario/images/flag-pole.png new file mode 100644 index 000000000..0a00ae243 Binary files /dev/null and b/projects/Super Mario/images/flag-pole.png differ diff --git a/projects/Super Mario/images/flag.png b/projects/Super Mario/images/flag.png new file mode 100644 index 000000000..de4376521 Binary files /dev/null and b/projects/Super Mario/images/flag.png differ diff --git a/projects/Super Mario/images/grid-large-btn.png b/projects/Super Mario/images/grid-large-btn.png new file mode 100644 index 000000000..3a159b18f Binary files /dev/null and b/projects/Super Mario/images/grid-large-btn.png differ diff --git a/projects/Super Mario/images/grid-medium-btn.png b/projects/Super Mario/images/grid-medium-btn.png new file mode 100644 index 000000000..e6e29b4bb Binary files /dev/null and b/projects/Super Mario/images/grid-medium-btn.png differ diff --git a/projects/Super Mario/images/grid-small-btn.png b/projects/Super Mario/images/grid-small-btn.png new file mode 100644 index 000000000..b3904283d Binary files /dev/null and b/projects/Super Mario/images/grid-small-btn.png differ diff --git a/projects/Super Mario/images/grid.png b/projects/Super Mario/images/grid.png new file mode 100644 index 000000000..ea288390f Binary files /dev/null and b/projects/Super Mario/images/grid.png differ diff --git a/projects/Super Mario/images/lvl-size.png b/projects/Super Mario/images/lvl-size.png new file mode 100644 index 000000000..a45abc2cb Binary files /dev/null and b/projects/Super Mario/images/lvl-size.png differ diff --git a/projects/Super Mario/images/mario-head.png b/projects/Super Mario/images/mario-head.png new file mode 100644 index 000000000..36ceb3def Binary files /dev/null and b/projects/Super Mario/images/mario-head.png differ diff --git a/projects/Super Mario/images/mario-sprites.png b/projects/Super Mario/images/mario-sprites.png new file mode 100644 index 000000000..967c9b1b5 Binary files /dev/null and b/projects/Super Mario/images/mario-sprites.png differ diff --git a/projects/Super Mario/images/powerups.png b/projects/Super Mario/images/powerups.png new file mode 100644 index 000000000..ae229fa69 Binary files /dev/null and b/projects/Super Mario/images/powerups.png differ diff --git a/projects/Super Mario/images/save-map-btn.png b/projects/Super Mario/images/save-map-btn.png new file mode 100644 index 000000000..ccf1342fb Binary files /dev/null and b/projects/Super Mario/images/save-map-btn.png differ diff --git a/projects/Super Mario/images/saved-btn.png b/projects/Super Mario/images/saved-btn.png new file mode 100644 index 000000000..04e1fa8a7 Binary files /dev/null and b/projects/Super Mario/images/saved-btn.png differ diff --git a/projects/Super Mario/images/slider-left.png b/projects/Super Mario/images/slider-left.png new file mode 100644 index 000000000..d2b41c044 Binary files /dev/null and b/projects/Super Mario/images/slider-left.png differ diff --git a/projects/Super Mario/images/slider-right.png b/projects/Super Mario/images/slider-right.png new file mode 100644 index 000000000..10212d578 Binary files /dev/null and b/projects/Super Mario/images/slider-right.png differ diff --git a/projects/Super Mario/images/start-btn.png b/projects/Super Mario/images/start-btn.png new file mode 100644 index 000000000..c7da721c5 Binary files /dev/null and b/projects/Super Mario/images/start-btn.png differ diff --git a/projects/Super Mario/images/start-screen.png b/projects/Super Mario/images/start-screen.png new file mode 100644 index 000000000..06eb7fbd1 Binary files /dev/null and b/projects/Super Mario/images/start-screen.png differ diff --git a/projects/Super Mario/index.html b/projects/Super Mario/index.html new file mode 100644 index 000000000..71b8ecc11 --- /dev/null +++ b/projects/Super Mario/index.html @@ -0,0 +1,36 @@ + + + + + + Super Mario Run + + + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/projects/Super Mario/js/GameUI.js b/projects/Super Mario/js/GameUI.js new file mode 100644 index 000000000..91eb49ef1 --- /dev/null +++ b/projects/Super Mario/js/GameUI.js @@ -0,0 +1,74 @@ +//canvas elements for the main mario game + +var GameUI = (function() { + var instance; + + function GameUI() { + var canvas = document.getElementsByClassName('game-screen')[0]; + var ctx = canvas.getContext('2d'); + + var that = this; + + this.setWidth = function(width) { + canvas.width = width; + }; + + this.setHeight = function(height) { + canvas.height = height; + }; + + this.getWidth = function() { + return canvas.width; + }; + + this.getHeight = function() { + return canvas.height; + }; + + this.getCanvas = function() { + return canvas; + }; + + this.show = function() { + canvas.style.display = 'block'; + }; + + this.hide = function() { + canvas.style.display = 'none'; + }; + + this.clear = function(x, y, width, height) { + ctx.clearRect(x, y, width, height); + }; + + this.scrollWindow = function(x, y) { + ctx.translate(x, y); + }; + + this.draw = function(image, sx, sy, width, height, x, y, width, height) { + ctx.drawImage(image, sx, sy, width, height, x, y, width, height); + }; + + this.makeBox = function(x, y, width, height) { + ctx.rect(x, y, width, height); + ctx.fillStyle = 'black'; + ctx.fill(); + }; + + this.writeText = function(text, x, y) { + ctx.font = '20px SuperMario256'; + ctx.fillStyle = 'white'; + ctx.fillText(text, x, y); + }; + } + + return { + getInstance: function() { + if (instance == null) { + instance = new GameUI(); + } + + return instance; + } + }; +})(); diff --git a/projects/Super Mario/js/MarioMaker.js b/projects/Super Mario/js/MarioMaker.js new file mode 100644 index 000000000..dd5b3f66c --- /dev/null +++ b/projects/Super Mario/js/MarioMaker.js @@ -0,0 +1,147 @@ +//Main Class through which both the game and level editor are instantiated + +var MarioMaker = (function() { + var instance; + + function MarioMaker() { + var view = View.getInstance(); + + var mainWrapper; + var startScreen; + var btnWrapper; + + var editorButton; + var startGameButton; + var createdLevelsButton; + + var editorStarted = 0; + + var backToMenuBtn; + + //instances + var marioGame; + var editor; + var createdLevels; + + var that = this; + + this.init = function() { + marioGame = new MarioGame(); + editor = new Editor(); + createdLevels = new CreatedLevels(); + + //main menu screen + mainWrapper = view.getMainWrapper(); + startScreen = view.create('div'); + btnWrapper = view.create('div'); + editorButton = view.create('button'); + startGameButton = view.create('button'); + createdLevelsButton = view.create('div'); + backToMenuBtn = view.create('button'); + + view.addClass(btnWrapper, 'btn-wrapper'); + view.addClass(startScreen, 'start-screen'); + view.addClass(editorButton, 'editor-btn'); + view.addClass(startGameButton, 'start-btn'); + view.addClass(createdLevelsButton, 'created-btn'); + view.addClass(backToMenuBtn, 'back-btn'); + + view.append(startScreen, editorButton); + view.append(startScreen, startGameButton); + view.append(startScreen, createdLevelsButton); + view.append(btnWrapper, backToMenuBtn); + view.append(mainWrapper, startScreen); + view.append(mainWrapper, btnWrapper); + + editorButton.onclick = that.startEditor; + + createdLevelsButton.onclick = that.startCreatedLevels; + + backToMenuBtn.onclick = that.backToMenu; + + startGameButton.onclick = function() { + map = that.loadMainGameMap(); + that.startGame(map); + }; + }; + + this.loadMainGameMap = function() { + var map = { + 1: '[[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,5,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,20,0,0,0,0,20,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,4,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,4,4,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,2,3,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,3,2,2,2,2,0,0,0,9,10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,10,0,0,0,0,0,0,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,4,4,4,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,9,10,0,0,0,0,0,9,10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,4,4,4,4,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,7,8,0,0,0,0,0,7,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,7,8,20,0,0,0,0,7,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,8,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,7,8,20,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0],[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]]', + 2: '[[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,5,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,8,0,0,0,0,0,0,0,2,0,0,2,0,0,3,0,0,2,0,0,2,0,0,0,0,0,0,7,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,4,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,9,10,0,0,0,0,0,0,9,10,0,0,0,2,0,0,2,0,0,2,0,0,2,0,0,2,0,0,0,0,0,9,10,7,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,8,0,0,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,4,4,0,0,0,4,4,4,0,0,0,0,5,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,7,8,0,0,0,0,0,0,7,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,8,7,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,0,0,7,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,7,8,0,0,0,0,0,0,7,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,10,7,8,7,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,7,8,20,0,0,0,0,20,7,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,8,7,8,7,8,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,7,8,0,0,0,0,0,0,0,0,0,0,0,0,20,20,0,0,20,20,0,0,20,20,0,20,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0],[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,7,8,7,8,7,8,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]]', + 3: '[[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,5,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,0,0,0,0,0,0,0,0,5,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,0,0,0,0,0,0,0,0,5,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,10,0,0,0,0,9,10,0,0,3,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,8,0,0,4,20,0,0,0,0,20,4,0,4,0,0,0,0,0,0,4,0,0,7,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,0,0,0,0,0,0,0,0,5,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,2,2,0,0,2,3,0,0,7,8,0,0,0,0,7,8,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,9,10,0,0,7,8,0,0,4,4,4,4,4,4,4,4,0,4,4,4,4,4,4,4,4,0,0,7,8,0,0,0,0,0,0,0,0,4,0,20,0,0,0,20,0,0,0,0,0,0,0,0,0,0,20,0,0,0,0,4,4,4,0,0,0,0,7,8,0,0,0,0,0,0,0,2,2,2,0,0,0,0,0,0,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,0,0,4,4,0,0,0,0,0,0,0,0,5,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,8,0,0,0,0,7,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,8,0,0,7,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,8,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,4,4,0,0,0,0,7,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,10,0,0,0,0,0,0,0,4,4,0,0,4,4,0,0,0,0,0,0,0,0,5,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,8,0,0,0,0,7,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,8,0,0,7,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,8,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,4,4,4,0,0,0,7,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,8,0,0,0,4,4,0,0,4,4,0,0,4,4,0,0,0,0,0,0,0,0,5,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,20,0,0,0,20,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,0,0,20,0,0,0,0,0,0,0,20,0,0,0,0,0,0,0,0,0,0,0,0,7,8,0,0,7,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,8,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,4,4,4,4,0,0,7,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,8,20,0,0,4,4,0,0,4,4,0,0,4,4,0,0,0,0,0,0,0,0,5,0,0,0,0,0],[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,7,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,8,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,4,4,4,4,4,1,1,1,1,1,1,0,0,0,1,1,1,1,1,0,0,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,4,4,0,0,4,4,0,0,4,4,1,1,1,1,1,1,1,1,1,1,1,1,1,1]]', + 4: '[[0,0,4,4,4,4,0,4,4,4,4,0,4,0,0,0,4,0,4,0,0,4,0,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,4,0,0,4,0,4,0,0,4,0,4,4,0,0,4,0,4,0,0,4,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,4,4,4,4,0,4,0,0,4,0,4,0,4,0,4,0,4,0,0,4,0,4,4,4,4,4,0,0,0,0,0,0,0,6,5,0,0,0],[0,0,4,0,0,4,0,4,0,0,4,0,4,0,0,4,4,0,4,0,0,4,0,0,0,0,0,4,0,0,0,0,0,0,0,0,5,0,0,0],[0,0,4,4,4,4,0,4,4,4,4,0,4,0,0,0,4,0,4,4,4,4,0,4,4,4,4,4,0,0,0,0,0,0,0,0,5,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0],[0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0],[0,0,0,0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,5,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0],[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]]', + 5: '[[0,0,0,0,0,0,0,0,0,7,8,0,0,0,0,0,7,8,0,0,0,7,8,0,0,0,7,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,7,8,0,0,0,0,0,7,8,0,0,0,7,8,0,0,0,7,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,7,8,0,0,0,0,0,7,8,0,0,0,7,8,0,0,0,7,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,7,8,0,0,0,0,0,7,8,0,0,0,7,8,0,0,0,7,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,5,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,9,10,0,0,0,0,0,7,8,0,0,0,9,10,0,0,0,7,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,20,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,8,0,0,0,0,0,0,0,0,7,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,10,0,0,0,9,10,0,0,0,0,0,2,2,2,2,2,2,2,0,0,0,0,0,0,7,8,0,0,0,0,0,0,0,0,0,0,9,10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,8,0,0,0,0,0,0,0,0,7,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,8,0,0,0,7,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,10,0,0,0,0,0,0,0,0,2,0,7,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,10,0,0,0,0,0,0,0,0,9,10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,8,20,0,0,7,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,8,0,0,0,0,0,0,0,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,9,10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,20,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,4,4,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,7,8,0,0,0,0,0,0,0,0,0,0,9,10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,4,4,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,7,8,0,0,0,0,0,0,0,0,0,0,7,8,0,0,0,0,0,0,0,0,0,2,0,0,2,0,0,3,0,0,2,0,0,2,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,4,4,0,0,0,0,0,9,10,0,0,0,0,0,0,0,9,10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,0,0,0,0,0,9,10,0,0,0,0,0,0,0,0,9,10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,4,4,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0],[0,0,0,0,0,0,2,3,2,7,8,0,0,0,0,0,0,0,0,0,0,7,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,4,4,0,0,0,0,0,7,8,0,0,0,0,0,0,0,7,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,8,0,0,0,0,0,0,0,0,7,8,0,0,0,0,0,0,0,0,4,0,20,0,0,0,20,0,4,0,0,0,0,7,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,4,0,0,0,4,4,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,7,8,0,0,0,0,0,9,10,0,0,0,7,8,0,0,0,9,10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,4,4,0,0,0,0,0,7,8,0,20,0,0,0,0,0,7,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,8,0,0,0,0,0,0,0,0,7,8,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,7,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,4,0,0,0,4,4,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,7,8,0,0,0,0,0,7,8,0,0,0,7,8,0,0,0,7,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,4,0,0,4,4,0,0,0,0,0,7,8,0,0,0,0,0,0,20,7,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,8,20,0,0,20,0,0,20,0,7,8,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,7,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,4,0,0,0,4,4,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0],[1,1,1,1,1,1,1,1,1,7,8,1,1,1,1,1,7,8,0,0,0,7,8,0,0,0,7,8,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,4,0,0,4,0,0,4,4,0,0,0,0,0,7,8,1,1,1,1,1,1,1,7,8,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,7,8,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,0,0,0,0,1,0,0,0,4,0,0,4,0,0,0,4,4,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]]' + }; + + return map; + }; + + this.startGame = function(levelMap) { + view.style(backToMenuBtn, { display: 'block' }); + + marioGame.clearInstances(); + marioGame.init(levelMap, 1); //initiate level 1 of map + + that.hideMainMenu(); + editor.removeEditorScreen(); + createdLevels.removeCreatedLevelsScreen(); + }; + + this.startEditor = function() { + view.style(backToMenuBtn, { display: 'block' }); + + if (editorStarted == 0) { + //instantiate only once, after that just show and hide the editor screen + editor.init(); + editorStarted = 1; + } else { + editor.showEditorScreen(); + } + + that.hideMainMenu(); + marioGame.removeGameScreen(); + createdLevels.removeCreatedLevelsScreen(); + }; + + this.startCreatedLevels = function() { + view.style(backToMenuBtn, { display: 'block' }); + + createdLevels.init(); + that.hideMainMenu(); + marioGame.removeGameScreen(); + editor.removeEditorScreen(); + }; + + this.backToMenu = function() { + marioGame.pauseGame(); //pause game when the back button is pressed so that the gameloop doesnt run more than once + marioGame.clearTimeOut(); //when mario dies, a timeout starts for resetting the game. Pressing the back button clears that timeout + marioGame.removeGameScreen(); + + editor.removeEditorScreen(); + + createdLevels.removeCreatedLevelsScreen(); + that.showMainMenu(); + + view.style(backToMenuBtn, { display: 'none' }); + }; + + this.hideMainMenu = function() { + view.style(startScreen, { display: 'none' }); + }; + + this.showMainMenu = function() { + view.style(startScreen, { display: 'block' }); + }; + } + + return { + getInstance: function() { + if (instance == null) { + instance = new MarioMaker(); + } + + return instance; + } + }; +})(); diff --git a/projects/Super Mario/js/Preloader.js b/projects/Super Mario/js/Preloader.js new file mode 100644 index 000000000..c57e7d68d --- /dev/null +++ b/projects/Super Mario/js/Preloader.js @@ -0,0 +1,85 @@ +function Preloader() { + var view = View.getInstance(); + + var loadingPercentage; + + var imageSources; + var soundSources; + + var that = this; + + this.init = function() { + loadingPercentage = view.create('div'); + + view.addClass(loadingPercentage, 'loading-percentage'); + view.setHTML(loadingPercentage, '0%'); + view.appendToBody(loadingPercentage); + + imageSources = { + 1: 'images/back-btn.png', + 2: 'images/bg.png', + 3: 'images/bullet.png', + 4: 'images/clear-map-btn.png', + 5: 'images/coin.png', + 6: 'images/delete-all-btn.png', + 7: 'images/editor-btn.png', + 8: 'images/elements.png', + 9: 'images/enemies.png', + 10: 'images/flag-pole.png', + 11: 'images/flag.png', + 12: 'images/start-screen.png', + 13: 'images/grid-large-btn.png', + 14: 'images/grid-medium-btn.png', + 15: 'images/grid-small-btn.png', + 16: 'images/grid.png', + 17: 'images/lvl-size.png', + 18: 'images/mario-head.png', + 19: 'images/mario-sprites.png', + 20: 'images/powerups.png', + 21: 'images/save-map-btn.png', + 22: 'images/saved-btn.png', + 23: 'images/slider-left.png', + 24: 'images/slider-right.png', + 25: 'images/start-btn.png' + }; + + that.loadImages(imageSources); + }; + + this.loadImages = function(imageSources) { + var images = {}; + var loadedImages = 0; + var totalImages = 0; + + for (var key in imageSources) { + totalImages++; + } + + for (var key in imageSources) { + images[key] = new Image(); + images[key].src = imageSources[key]; + + images[key].onload = function() { + loadedImages++; + percentage = Math.floor(loadedImages * 100 / totalImages); + + view.setHTML(loadingPercentage, percentage + '%'); //displaying percentage + + if (loadedImages >= totalImages) { + view.removeFromBody(loadingPercentage); + that.initMainApp(); + } + }; + } + }; + + this.initMainApp = function() { + var marioMakerInstance = MarioMaker.getInstance(); + marioMakerInstance.init(); + }; +} + +window.onload = function() { + var preloader = new Preloader(); + preloader.init(); +}; diff --git a/projects/Super Mario/js/View.js b/projects/Super Mario/js/View.js new file mode 100644 index 000000000..7fc46afb0 --- /dev/null +++ b/projects/Super Mario/js/View.js @@ -0,0 +1,67 @@ +//div elements for the application + +var View = (function() { + var instance; + + function View() { + this.getMainWrapper = function() { + var element = document.getElementsByClassName('main-wrapper')[0]; + + return element; + }; + + this.create = function(elementName) { + var element = document.createElement(elementName); + + return element; + }; + + this.addClass = function(element, className) { + element.className = className; + }; + + this.append = function(parentElement, childElement) { + //appends everything before the back button, score wrapper in top and everything else in between + if (childElement.className == 'score-wrapper') { + parentElement.insertBefore(childElement, parentElement.firstChild); + } else if (parentElement.lastChild && parentElement.lastChild.className == 'btn-wrapper') { + parentElement.insertBefore(childElement, parentElement.lastChild); + } else { + parentElement.appendChild(childElement); + } + }; + + this.appendToBody = function(childElement) { + document.body.appendChild(childElement); + }; + + this.remove = function(parentElement, childElement) { + parentElement.removeChild(childElement); + }; + + this.removeFromBody = function(childElement) { + document.body.removeChild(childElement); + }; + + //style = {display: 'block', position: 'absolute', ...} + this.style = function(element, styles) { + for (var property in styles) { + element.style[property] = styles[property]; + } + }; + + this.setHTML = function(element, content) { + element.innerHTML = content; + }; + } + + return { + getInstance: function() { + if (instance == null) { + instance = new View(); + } + + return instance; + } + }; +})(); diff --git a/projects/Super Mario/js/levelEditor/CreatedLevels.js b/projects/Super Mario/js/levelEditor/CreatedLevels.js new file mode 100644 index 000000000..d58bab01c --- /dev/null +++ b/projects/Super Mario/js/levelEditor/CreatedLevels.js @@ -0,0 +1,87 @@ +function CreatedLevels() { + var view = View.getInstance(); + + var storage; + var levelsWrapper; + + var that = this; + + this.init = function() { + var mainWrapper = view.getMainWrapper(); + var deleteAllBtn = view.create('button'); + levelsWrapper = view.create('div'); + + view.addClass(levelsWrapper, 'levels-wrapper'); + view.addClass(deleteAllBtn, 'delete-all-btn'); + view.style(levelsWrapper, { display: 'block' }); + view.append(levelsWrapper, deleteAllBtn); + view.append(mainWrapper, levelsWrapper); + + deleteAllBtn.onclick = that.deleteAllMaps; + + storage = new Storage(); + + that.showLevels(); + }; + + this.showLevels = function() { + var totalStoredLevels = storage.getLength(); + + if (totalStoredLevels != 0) { + for (var i = 1; i < totalStoredLevels; i++) { + var levelButton = view.create('div'); + var levelName = storage.getItemName(i); + + view.setHTML(levelButton, levelName); + view.addClass(levelButton, 'level-btn'); + view.append(levelsWrapper, levelButton); + + levelButton.onclick = (function(i) { + return function() { + that.startLevel(i); + that.removeCreatedLevelsScreen(); + }; + })(i); + } + } else { + var noMapsMessage = view.create('div'); + + view.addClass(noMapsMessage, 'no-maps'); + view.setHTML(noMapsMessage, 'No maps currently saved. Please use the Level Editor to create custom Maps'); + view.append(levelsWrapper, noMapsMessage); + } + }; + + this.deleteAllMaps = function() { + storage.clear(); + + that.removeCreatedLevelsScreen(); + that.init(); + }; + + this.startLevel = function(i) { + var marioMakerInstance = MarioMaker.getInstance(); + var levelName = storage.getItemName(i); + var level = storage.getItem(levelName); + var map = { 1: level }; //always only one level in saved maps. + + marioMakerInstance.startGame(map); + }; + + this.showCreatedLevelsScreen = function() { + if (levelsWrapper) { + view.style(levelsWrapper, { display: 'block' }); + } + }; + + this.removeCreatedLevelsScreen = function() { + if (levelsWrapper) { + view.style(levelsWrapper, { display: 'none' }); + + while (levelsWrapper.hasChildNodes()) { + //removes all the created levels on screen, so that it can be initiated again showing new levels that user creates + view.remove(levelsWrapper, levelsWrapper.lastChild); + } + } + }; +} diff --git a/projects/Super Mario/js/levelEditor/Editor.js b/projects/Super Mario/js/levelEditor/Editor.js new file mode 100644 index 000000000..172377e94 --- /dev/null +++ b/projects/Super Mario/js/levelEditor/Editor.js @@ -0,0 +1,335 @@ +//Main Class of Level Editor + +function Editor() { + var view = View.getInstance(); + var mainWrapper; + + var gameWorld; + var viewPort; + + var grid; + var elementwrapper; + + var map; + var maxWidth; + var height = 480; + var tileSize = 32; + var scrollMargin = 0; + + var selectedElement = []; + + var that = this; + + this.init = function() { + mainWrapper = view.getMainWrapper(); + viewPort = view.create('div'); + + view.addClass(viewPort, 'editor-screen'); + view.style(viewPort, { display: 'block' }); + view.append(mainWrapper, viewPort); + + that.createLevelEditor(); + that.drawGrid(3840); //draws grid of size 3840px by default at start + that.showElements(); + }; + + this.createLevelEditor = function() { + var rightArrow = view.create('div'); + var leftArrow = view.create('div'); + gameWorld = view.create('div'); + + view.style(gameWorld, { width: 6400 + 'px' }); + view.style(gameWorld, { height: height + 'px' }); + + view.addClass(rightArrow, 'right-arrow'); + view.addClass(leftArrow, 'left-arrow'); + + view.append(viewPort, rightArrow); + view.append(viewPort, leftArrow); + view.append(viewPort, gameWorld); + + rightArrow.addEventListener('click', that.rightScroll); + leftArrow.addEventListener('click', that.leftScroll); + }; + + this.drawGrid = function(width) { + maxWidth = width; + grid = view.create('table'); + + var row = height / tileSize; + var column = maxWidth / tileSize; + + var mousedown = false; + var selected = false; + + for (i = 1; i <= row; i++) { + var tr = view.create('tr'); + for (j = 1; j <= column; j++) { + var td = view.create('td'); + + view.addClass(td, 'cell'); + + td.addEventListener('mousedown', function(e) { + e.preventDefault(); //to stop the mouse pointer to change + }); + + td.onmousedown = (function(i, j) { + return function() { + selectedElement.push(this); + view.addClass(this, 'active'); + mousedown = true; + }; + })(i, j); + + td.onmouseover = (function(i, j) { + return function() { + if (mousedown) { + selectedElement.push(this); + view.addClass(this, 'active'); + } + }; + })(i, j); + + td.onmouseup = function() { + mousedown = false; + }; + + view.append(tr, td); + } + + view.append(grid, tr); + + grid.onmouseleave = function() { + //if mouse hovers over the editor screen + mousedown = false; + }; + } + + view.append(gameWorld, grid); + }; + + this.showElements = function() { + elementWrapper = view.create('div'); + + view.addClass(elementWrapper, 'element-wrapper'); + view.append(mainWrapper, elementWrapper); + + var elements = [ + 'cell', + 'platform', + 'coin-box', + 'power-up-box', + 'useless-box', + 'flag', + 'flag-pole', + 'pipe-left', + 'pipe-right', + 'pipe-top-left', + 'pipe-top-right', + 'goomba' + ]; + var element; + + var saveMap = view.create('button'); + var clearMap = view.create('button'); + var lvlSize = view.create('div'); + var gridSmallBtn = view.create('button'); + var gridMediumBtn = view.create('button'); + var gridLargeBtn = view.create('button'); + + //for every element in the 'elements' array, it creates a div and sets the class name + for (i = 0; i < elements.length; i++) { + element = view.create('div'); + + view.addClass(element, elements[i]); + view.append(elementWrapper, element); + + element.onclick = (function(i) { + return function() { + that.drawElement(elements[i]); + }; + })(i); + } + + view.addClass(lvlSize, 'lvl-size'); + view.addClass(gridSmallBtn, 'grid-small-btn'); + view.addClass(gridMediumBtn, 'grid-medium-btn'); + view.addClass(gridLargeBtn, 'grid-large-btn'); + view.addClass(saveMap, 'save-map-btn'); + view.addClass(clearMap, 'clear-map-btn'); + view.style(elementWrapper, { display: 'block' }); + view.append(elementWrapper, lvlSize); + view.append(elementWrapper, gridSmallBtn); + view.append(elementWrapper, gridMediumBtn); + view.append(elementWrapper, gridLargeBtn); + view.append(elementWrapper, clearMap); + view.append(elementWrapper, saveMap); + + saveMap.addEventListener('click', that.saveMap); + clearMap.addEventListener('click', that.resetEditor); + gridSmallBtn.addEventListener('click', that.gridSmall); + gridMediumBtn.addEventListener('click', that.gridMedium); + gridLargeBtn.addEventListener('click', that.gridLarge); + }; + + that.gridSmall = function() { + view.remove(gameWorld, grid); + that.drawGrid(1280); //small grid size + }; + + that.gridMedium = function() { + view.remove(gameWorld, grid); + that.drawGrid(3840); //medium grid size + }; + + that.gridLarge = function() { + view.remove(gameWorld, grid); + that.drawGrid(6400); //large grid size + }; + + this.drawElement = function(element) { + /* + every element that is selected is pushed into 'selectedElement' array + after clicking the required element, it loops through the array and sets the class name + of that cell, changing the background of the cell. + */ + + for (var i = 0; i < selectedElement.length; i++) { + view.addClass(selectedElement[i], element); + } + + selectedElement = []; + }; + + that.generateMap = function() { + var newMap = []; + var gridRows = grid.getElementsByTagName('tr'); + + //loops throught the table cells and checks for the class-name, puts the value according to its className; + for (var i = 0; i < gridRows.length; i++) { + var columns = []; + var gridColumns = gridRows[i].getElementsByTagName('td'); + for (var j = 0; j < gridColumns.length; j++) { + var value; + + switch (gridColumns[j].className) { + case 'platform': + value = 1; + break; + + case 'coin-box': + value = 2; + break; + + case 'power-up-box': + value = 3; + break; + + case 'useless-box': + value = 4; + break; + + case 'goomba': + value = 20; + break; + + case 'flag-pole': + value = 5; + break; + + case 'flag': + value = 6; + break; + + case 'pipe-left': + value = 7; + break; + + case 'pipe-right': + value = 8; + break; + + case 'pipe-top-left': + value = 9; + break; + + case 'pipe-top-right': + value = 10; + break; + + default: + value = 0; + break; + } + columns.push(value); + } + newMap.push(columns); + } + map = newMap; + }; + + this.saveMap = function() { + var storage = new Storage(); + var levelCounter = storage.getItem('levelCounter') || 0; + + that.generateMap(); + + levelCounter++; + + //for fixing the sorting of the localStorage, 01 02 ... 10 11, otherwise the sorting would be 1 10 11 .. 2 20 21 .. + if (levelCounter < 10) { + levelName = 'savedLevel' + '0' + levelCounter; + } else { + levelName = 'savedLevel' + levelCounter; + } + + storage.setItem(levelName, map); + storage.setItem('levelCounter', levelCounter); + + console.log(storage.getItem(levelName)); //for copying the generated map if required + }; + + this.rightScroll = function() { + if (scrollMargin > -(maxWidth - 1280)) { + scrollMargin += -160; + view.style(gameWorld, { 'margin-left': scrollMargin + 'px' }); + } + }; + + this.leftScroll = function() { + if (scrollMargin != 0) { + scrollMargin += 160; + view.style(gameWorld, { 'margin-left': scrollMargin + 'px' }); + } + }; + + this.resetEditor = function() { + var gridRows = grid.getElementsByTagName('tr'); + for (var i = 0; i < gridRows.length; i++) { + var gridColumns = gridRows[i].getElementsByTagName('td'); + + for (var j = 0; j < gridColumns.length; j++) { + view.addClass(gridColumns[j], 'cell'); + } + } + + selectedElement = []; + scrollMargin = 0; + view.style(gameWorld, { 'margin-left': scrollMargin + 'px' }); + }; + + this.removeEditorScreen = function() { + if (viewPort) { + that.resetEditor(); + view.style(viewPort, { display: 'none' }); + view.style(elementWrapper, { display: 'none' }); + } + }; + + this.showEditorScreen = function() { + if (viewPort) { + view.style(viewPort, { display: 'block' }); + view.style(elementWrapper, { display: 'block' }); + } + }; +} diff --git a/projects/Super Mario/js/levelEditor/Storage.js b/projects/Super Mario/js/levelEditor/Storage.js new file mode 100644 index 000000000..7351734bb --- /dev/null +++ b/projects/Super Mario/js/levelEditor/Storage.js @@ -0,0 +1,29 @@ +//for storing and retrieving from localStorage + +function Storage() { + this.getItem = function(itemName) { + var item = localStorage.getItem(itemName); + + return item; + }; + + this.getLength = function() { + var length = localStorage.length; + + return length; + }; + + this.getItemName = function(keyValue) { + var name = localStorage.key(keyValue); + + return name; + }; + + this.setItem = function(itemName, itemData) { + localStorage.setItem(itemName, JSON.stringify(itemData)); + }; + + this.clear = function() { + localStorage.clear(); + }; +} diff --git a/projects/Super Mario/js/mainGame/Bullet.js b/projects/Super Mario/js/mainGame/Bullet.js new file mode 100644 index 000000000..2efa9dccd --- /dev/null +++ b/projects/Super Mario/js/mainGame/Bullet.js @@ -0,0 +1,46 @@ +function Bullet() { + var gameUI = GameUI.getInstance(); + + var element = new Image(); + element.src = 'images/bullet.png'; + + this.x; + this.y; + this.velX; + this.velY; + this.grounded = false; + this.sX; + this.sY = 0; + this.width = 16; + this.height = 16; + + var that = this; + + this.init = function(x, y, direction) { + that.velX = 8 * direction; //changing the direction of the bullet if mario faces another side + that.velY = 0; + that.x = x + that.width; + that.y = y + 30; + that.type = 30; + that.sX = 0; + }; + + this.draw = function() { + gameUI.draw(element, that.sX, that.sY, that.width, that.height, that.x, that.y, that.width, that.height); + }; + + this.update = function() { + var gravity = 0.2; + + if (that.grounded) { + //bouncing the bullet as it touches the ground + that.velY = -4; + that.grounded = false; + } + + that.velY += gravity; + + that.x += that.velX; + that.y += that.velY; + }; +} diff --git a/projects/Super Mario/js/mainGame/Element.js b/projects/Super Mario/js/mainGame/Element.js new file mode 100644 index 000000000..860023ae1 --- /dev/null +++ b/projects/Super Mario/js/mainGame/Element.js @@ -0,0 +1,70 @@ +function Element() { + var gameUI = GameUI.getInstance(); + + var element = new Image(); + element.src = 'images/elements.png'; + + this.type; + this.sX; + this.sY = 0; + this.x; + this.y; + this.width = 32; + this.height = 32; + + var that = this; + + this.platform = function() { + that.type = 1; + that.sX = 0; + }; + + this.coinBox = function() { + that.type = 2; + that.sX = 1 * that.width; + }; + + this.powerUpBox = function() { + that.type = 3; + that.sX = 2 * that.width; + }; + + this.uselessBox = function() { + that.type = 4; + that.sX = 3 * that.width; + }; + + this.flagPole = function() { + that.type = 5; + that.sX = 4 * that.width; + }; + + this.flag = function() { + that.type = 6; + that.sX = 5 * that.width; + }; + + this.pipeLeft = function() { + that.type = 7; + that.sX = 6 * that.width; + }; + + this.pipeRight = function() { + that.type = 8; + that.sX = 7 * that.width; + }; + + this.pipeTopLeft = function() { + that.type = 9; + that.sX = 8 * that.width; + }; + + this.pipeTopRight = function() { + that.type = 10; + that.sX = 9 * that.width; + }; + + this.draw = function() { + gameUI.draw(element, that.sX, that.sY, that.width, that.height, that.x, that.y, that.width, that.height); + }; +} diff --git a/projects/Super Mario/js/mainGame/Enemy.js b/projects/Super Mario/js/mainGame/Enemy.js new file mode 100644 index 000000000..c23b58d0e --- /dev/null +++ b/projects/Super Mario/js/mainGame/Enemy.js @@ -0,0 +1,75 @@ +function Enemy() { + var gameUI = GameUI.getInstance(); + + var tickCounter = 0; //for animating enemy + var maxTick = 10; //max number for ticks to show enemy sprite + + var element = new Image(); + element.src = 'images/enemies.png'; + + this.x; + this.y; + this.velX = 1; + this.velY = 0; + this.grounded = false; + this.type; + this.state; + + this.sX; + this.sY = 0; + this.width = 32; + this.height = 32; + + this.frame = 0; + + var that = this; + + this.goomba = function() { + this.type = 20; + that.sX = 0; + }; + + this.draw = function() { + that.sX = that.width * that.frame; + gameUI.draw(element, that.sX, that.sY, that.width, that.height, that.x, that.y, that.width, that.height); + }; + + this.update = function() { + var gravity = 0.2; + + if (that.grounded) { + that.velY = 0; + } + + if (that.state == 'dead') { + that.frame = 2; //squashed goomba + + tickCounter++; + if (tickCounter >= 60) { + that.frame = 4; + } + } else if (that.state == 'deadFromBullet') { + //falling goomba + that.frame = 3; + that.velY += gravity; + that.y += that.velY; + } else { + //only animate when not dead + that.velY += gravity; + that.x += that.velX; + that.y += that.velY; + + //for animating + tickCounter += 1; + + if (tickCounter > maxTick) { + tickCounter = 0; + if (that.frame == 0) { + that.frame = 1; + } else { + that.frame = 0; + } + } + } + }; +} diff --git a/projects/Super Mario/js/mainGame/GameSound.js b/projects/Super Mario/js/mainGame/GameSound.js new file mode 100644 index 000000000..3744da6f3 --- /dev/null +++ b/projects/Super Mario/js/mainGame/GameSound.js @@ -0,0 +1,65 @@ +function GameSound() { + var coin; + var powerUpAppear; + var powerUp; + var marioDie; + var killEnemy; + var stageClear; + var bullet; + var powerDown; + var jump; + + var that = this; + + this.init = function() { + coin = new Audio('sounds/coin.wav'); + powerUpAppear = new Audio('sounds/power-up-appear.wav'); + powerUp = new Audio('sounds/power-up.wav'); + marioDie = new Audio('sounds/mario-die.wav'); + killEnemy = new Audio('sounds/kill-enemy.wav'); + stageClear = new Audio('sounds/stage-clear.wav'); + bullet = new Audio('sounds/bullet.wav'); + powerDown = new Audio('sounds/power-down.wav'); + jump = new Audio('sounds/jump.wav'); + }; + + this.play = function(element) { + if (element == 'coin') { + coin.pause(); + coin.currentTime = 0; + coin.play(); + } else if (element == 'powerUpAppear') { + powerUpAppear.pause(); + powerUpAppear.currentTime = 0; + powerUpAppear.play(); + } else if (element == 'powerUp') { + powerUp.pause(); + powerUp.currentTime = 0; + powerUp.play(); + } else if (element == 'marioDie') { + marioDie.pause(); + marioDie.currentTime = 0; + marioDie.play(); + } else if (element == 'killEnemy') { + killEnemy.pause(); + killEnemy.currentTime = 0; + killEnemy.play(); + } else if (element == 'stageClear') { + stageClear.pause(); + stageClear.currentTime = 0; + stageClear.play(); + } else if (element == 'bullet') { + bullet.pause(); + bullet.currentTime = 0; + bullet.play(); + } else if (element == 'powerDown') { + powerDown.pause(); + powerDown.currentTime = 0; + powerDown.play(); + } else if (element == 'jump') { + jump.pause(); + jump.currentTime = 0; + jump.play(); + } + }; +} diff --git a/projects/Super Mario/js/mainGame/Mario.js b/projects/Super Mario/js/mainGame/Mario.js new file mode 100644 index 000000000..48a0ba977 --- /dev/null +++ b/projects/Super Mario/js/mainGame/Mario.js @@ -0,0 +1,66 @@ +function Mario() { + var gameUI = GameUI.getInstance(); + + this.type = 'small'; + this.x; + this.y; + this.width = 32; + this.height = 44; + this.speed = 3; + this.velX = 0; + this.velY = 0; + this.jumping = false; + this.grounded = false; + this.invulnerable = false; + this.sX = 0; // sprite x + this.sY = 4; // sprite y + this.frame = 0; + + var that = this; + + this.init = function() { + that.x = 10; + that.y = gameUI.getHeight() - 40 - 40; + + marioSprite = new Image(); + marioSprite.src = 'images/mario-sprites.png'; + }; + + this.draw = function() { + that.sX = that.width * that.frame; + gameUI.draw(marioSprite, that.sX, that.sY, that.width, that.height, that.x, that.y, that.width, that.height); + }; + + this.checkMarioType = function() { + if (that.type == 'big') { + that.height = 60; + + //big mario sprite position + if (that.invulnerable) { + that.sY = 276; //if invulnerable, show transparent mario + } else { + that.sY = 90; + } + } else if (that.type == 'small') { + that.height = 44; + + //small mario sprite + if (that.invulnerable) { + that.sY = 222; //if invulnerable, show transparent mario + } else { + that.sY = 4; + } + } else if (that.type == 'fire') { + that.height = 60; + + //fire mario sprite + that.sY = 150; + } + }; + + this.resetPos = function() { + that.x = canvas.width / 10; + that.y = canvas.height - 40; + that.frame = 0; + }; +} diff --git a/projects/Super Mario/js/mainGame/MarioGame.js b/projects/Super Mario/js/mainGame/MarioGame.js new file mode 100644 index 000000000..975d2926a --- /dev/null +++ b/projects/Super Mario/js/mainGame/MarioGame.js @@ -0,0 +1,870 @@ +//Main Class of Mario Game + +function MarioGame() { + var gameUI = GameUI.getInstance(); + + var maxWidth; //width of the game world + var height; + var viewPort; //width of canvas, viewPort that can be seen + var tileSize; + var map; + var originalMaps; + + var translatedDist; //distance translated(side scrolled) as mario moves to the right + var centerPos; //center position of the viewPort, viewable screen + var marioInGround; + + //instances + var mario; + var element; + var gameSound; + var score; + + var keys = []; + var goombas; + var powerUps; + var bullets; + var bulletFlag = false; + + var currentLevel; + + var animationID; + var timeOutId; + + var tickCounter = 0; //for animating mario + var maxTick = 25; //max number for ticks to show mario sprite + var instructionTick = 0; //showing instructions counter + var that = this; + + this.init = function(levelMaps, level) { + height = 480; + maxWidth = 0; + viewPort = 1280; + tileSize = 32; + translatedDist = 0; + goombas = []; + powerUps = []; + bullets = []; + + gameUI.setWidth(viewPort); + gameUI.setHeight(height); + gameUI.show(); + + currentLevel = level; + originalMaps = levelMaps; + map = JSON.parse(levelMaps[currentLevel]); + + if (!score) { + //so that when level changes, it uses the same instance + score = new Score(); + score.init(); + } + score.displayScore(); + score.updateLevelNum(currentLevel); + + if (!mario) { + //so that when level changes, it uses the same instance + mario = new Mario(); + mario.init(); + } else { + mario.x = 10; + mario.frame = 0; + } + element = new Element(); + gameSound = new GameSound(); + gameSound.init(); + + that.calculateMaxWidth(); + that.bindKeyPress(); + that.startGame(); + }; + + that.calculateMaxWidth = function() { + //calculates the max width of the game according to map size + for (var row = 0; row < map.length; row++) { + for (var column = 0; column < map[row].length; column++) { + if (maxWidth < map[row].length * 32) { + maxWidth = map[column].length * 32; + } + } + } + }; + + that.bindKeyPress = function() { + var canvas = gameUI.getCanvas(); //for use with touch events + + //key binding + document.body.addEventListener('keydown', function(e) { + keys[e.keyCode] = true; + }); + + document.body.addEventListener('keyup', function(e) { + keys[e.keyCode] = false; + }); + + //key binding for touch events + canvas.addEventListener('touchstart', function(e) { + var touches = e.changedTouches; + e.preventDefault(); + + for (var i = 0; i < touches.length; i++) { + if (touches[i].pageX <= 200) { + keys[37] = true; //left arrow + } + if (touches[i].pageX > 200 && touches[i].pageX < 400) { + keys[39] = true; //right arrow + } + if (touches[i].pageX > 640 && touches[i].pageX <= 1080) { + //in touch events, same area acts as sprint and bullet key + keys[16] = true; //shift key + keys[17] = true; //ctrl key + } + if (touches[i].pageX > 1080 && touches[i].pageX < 1280) { + keys[32] = true; //space + } + } + }); + + canvas.addEventListener('touchend', function(e) { + var touches = e.changedTouches; + e.preventDefault(); + + for (var i = 0; i < touches.length; i++) { + if (touches[i].pageX <= 200) { + keys[37] = false; + } + if (touches[i].pageX > 200 && touches[i].pageX <= 640) { + keys[39] = false; + } + if (touches[i].pageX > 640 && touches[i].pageX <= 1080) { + keys[16] = false; + keys[17] = false; + } + if (touches[i].pageX > 1080 && touches[i].pageX < 1280) { + keys[32] = false; + } + } + }); + + canvas.addEventListener('touchmove', function(e) { + var touches = e.changedTouches; + e.preventDefault(); + + for (var i = 0; i < touches.length; i++) { + if (touches[i].pageX <= 200) { + keys[37] = true; + keys[39] = false; + } + if (touches[i].pageX > 200 && touches[i].pageX < 400) { + keys[39] = true; + keys[37] = false; + } + if (touches[i].pageX > 640 && touches[i].pageX <= 1080) { + keys[16] = true; + keys[32] = false; + } + if (touches[i].pageX > 1080 && touches[i].pageX < 1280) { + keys[32] = true; + keys[16] = false; + keys[17] = false; + } + } + }); + }; + + //Main Game Loop + this.startGame = function() { + animationID = window.requestAnimationFrame(that.startGame); + + gameUI.clear(0, 0, maxWidth, height); + + if (instructionTick < 1000) { + that.showInstructions(); //showing control instructions + instructionTick++; + } + + that.renderMap(); + + for (var i = 0; i < powerUps.length; i++) { + powerUps[i].draw(); + powerUps[i].update(); + } + + for (var i = 0; i < bullets.length; i++) { + bullets[i].draw(); + bullets[i].update(); + } + + for (var i = 0; i < goombas.length; i++) { + goombas[i].draw(); + goombas[i].update(); + } + + that.checkPowerUpMarioCollision(); + that.checkBulletEnemyCollision(); + that.checkEnemyMarioCollision(); + + mario.draw(); + that.updateMario(); + that.wallCollision(); + marioInGround = mario.grounded; //for use with flag sliding + }; + + this.showInstructions = function() { + gameUI.writeText('Controls: Arrow keys for direction, shift to run, ctrl for bullets', 30, 30); + gameUI.writeText('Tip: Jumping while running makes you jump higher', 30, 60); + }; + + this.renderMap = function() { + //setting false each time the map renders so that elements fall off a platform and not hover around + mario.grounded = false; + + for (var i = 0; i < powerUps.length; i++) { + powerUps[i].grounded = false; + } + for (var i = 0; i < goombas.length; i++) { + goombas[i].grounded = false; + } + + for (var row = 0; row < map.length; row++) { + for (var column = 0; column < map[row].length; column++) { + switch (map[row][column]) { + case 1: //platform + element.x = column * tileSize; + element.y = row * tileSize; + element.platform(); + element.draw(); + + that.checkElementMarioCollision(element, row, column); + that.checkElementPowerUpCollision(element); + that.checkElementEnemyCollision(element); + that.checkElementBulletCollision(element); + break; + + case 2: //coinBox + element.x = column * tileSize; + element.y = row * tileSize; + element.coinBox(); + element.draw(); + + that.checkElementMarioCollision(element, row, column); + that.checkElementPowerUpCollision(element); + that.checkElementEnemyCollision(element); + that.checkElementBulletCollision(element); + break; + + case 3: //powerUp Box + element.x = column * tileSize; + element.y = row * tileSize; + element.powerUpBox(); + element.draw(); + + that.checkElementMarioCollision(element, row, column); + that.checkElementPowerUpCollision(element); + that.checkElementEnemyCollision(element); + that.checkElementBulletCollision(element); + break; + + case 4: //uselessBox + element.x = column * tileSize; + element.y = row * tileSize; + element.uselessBox(); + element.draw(); + + that.checkElementMarioCollision(element, row, column); + that.checkElementPowerUpCollision(element); + that.checkElementEnemyCollision(element); + that.checkElementBulletCollision(element); + break; + + case 5: //flagPole + element.x = column * tileSize; + element.y = row * tileSize; + element.flagPole(); + element.draw(); + + that.checkElementMarioCollision(element, row, column); + break; + + case 6: //flag + element.x = column * tileSize; + element.y = row * tileSize; + element.flag(); + element.draw(); + break; + + case 7: //pipeLeft + element.x = column * tileSize; + element.y = row * tileSize; + element.pipeLeft(); + element.draw(); + + that.checkElementMarioCollision(element, row, column); + that.checkElementPowerUpCollision(element); + that.checkElementEnemyCollision(element); + that.checkElementBulletCollision(element); + break; + + case 8: //pipeRight + element.x = column * tileSize; + element.y = row * tileSize; + element.pipeRight(); + element.draw(); + + that.checkElementMarioCollision(element, row, column); + that.checkElementPowerUpCollision(element); + that.checkElementEnemyCollision(element); + that.checkElementBulletCollision(element); + break; + + case 9: //pipeTopLeft + element.x = column * tileSize; + element.y = row * tileSize; + element.pipeTopLeft(); + element.draw(); + + that.checkElementMarioCollision(element, row, column); + that.checkElementPowerUpCollision(element); + that.checkElementEnemyCollision(element); + that.checkElementBulletCollision(element); + break; + + case 10: //pipeTopRight + element.x = column * tileSize; + element.y = row * tileSize; + element.pipeTopRight(); + element.draw(); + + that.checkElementMarioCollision(element, row, column); + that.checkElementPowerUpCollision(element); + that.checkElementEnemyCollision(element); + that.checkElementBulletCollision(element); + break; + + case 20: //goomba + var enemy = new Enemy(); + enemy.x = column * tileSize; + enemy.y = row * tileSize; + enemy.goomba(); + enemy.draw(); + + goombas.push(enemy); + map[row][column] = 0; + } + } + } + }; + + this.collisionCheck = function(objA, objB) { + // get the vectors to check against + var vX = objA.x + objA.width / 2 - (objB.x + objB.width / 2); + var vY = objA.y + objA.height / 2 - (objB.y + objB.height / 2); + + // add the half widths and half heights of the objects + var hWidths = objA.width / 2 + objB.width / 2; + var hHeights = objA.height / 2 + objB.height / 2; + var collisionDirection = null; + + // if the x and y vector are less than the half width or half height, then we must be inside the object, causing a collision + if (Math.abs(vX) < hWidths && Math.abs(vY) < hHeights) { + // figures out on which side we are colliding (top, bottom, left, or right) + var offsetX = hWidths - Math.abs(vX); + var offsetY = hHeights - Math.abs(vY); + + if (offsetX >= offsetY) { + if (vY > 0 && vY < 37) { + collisionDirection = 't'; + if (objB.type != 5) { + //if flagpole then pass through it + objA.y += offsetY; + } + } else if (vY < 0) { + collisionDirection = 'b'; + if (objB.type != 5) { + //if flagpole then pass through it + objA.y -= offsetY; + } + } + } else { + if (vX > 0) { + collisionDirection = 'l'; + objA.x += offsetX; + } else { + collisionDirection = 'r'; + objA.x -= offsetX; + } + } + } + return collisionDirection; + }; + + this.checkElementMarioCollision = function(element, row, column) { + var collisionDirection = that.collisionCheck(mario, element); + + if (collisionDirection == 'l' || collisionDirection == 'r') { + mario.velX = 0; + mario.jumping = false; + + if (element.type == 5) { + //flag pole + that.levelFinish(collisionDirection); + } + } else if (collisionDirection == 'b') { + if (element.type != 5) { + //only if not flag pole + mario.grounded = true; + mario.jumping = false; + } + } else if (collisionDirection == 't') { + if (element.type != 5) { + mario.velY *= -1; + } + + if (element.type == 3) { + //PowerUp Box + var powerUp = new PowerUp(); + + //gives mushroom if mario is small, otherwise gives flower + if (mario.type == 'small') { + powerUp.mushroom(element.x, element.y); + powerUps.push(powerUp); + } else { + powerUp.flower(element.x, element.y); + powerUps.push(powerUp); + } + + map[row][column] = 4; //sets to useless box after powerUp appears + + //sound when mushroom appears + gameSound.play('powerUpAppear'); + } + + if (element.type == 11) { + //Flower Box + var powerUp = new PowerUp(); + powerUp.flower(element.x, element.y); + powerUps.push(powerUp); + + map[row][column] = 4; //sets to useless box after powerUp appears + + //sound when flower appears + gameSound.play('powerUpAppear'); + } + + if (element.type == 2) { + //Coin Box + score.coinScore++; + score.totalScore += 100; + + score.updateCoinScore(); + score.updateTotalScore(); + map[row][column] = 4; //sets to useless box after coin appears + + //sound when coin block is hit + gameSound.play('coin'); + } + } + }; + + this.checkElementPowerUpCollision = function(element) { + for (var i = 0; i < powerUps.length; i++) { + var collisionDirection = that.collisionCheck(powerUps[i], element); + + if (collisionDirection == 'l' || collisionDirection == 'r') { + powerUps[i].velX *= -1; //change direction if collision with any element from the sidr + } else if (collisionDirection == 'b') { + powerUps[i].grounded = true; + } + } + }; + + this.checkElementEnemyCollision = function(element) { + for (var i = 0; i < goombas.length; i++) { + if (goombas[i].state != 'deadFromBullet') { + //so that goombas fall from the map when dead from bullet + var collisionDirection = that.collisionCheck(goombas[i], element); + + if (collisionDirection == 'l' || collisionDirection == 'r') { + goombas[i].velX *= -1; + } else if (collisionDirection == 'b') { + goombas[i].grounded = true; + } + } + } + }; + + this.checkElementBulletCollision = function(element) { + for (var i = 0; i < bullets.length; i++) { + var collisionDirection = that.collisionCheck(bullets[i], element); + + if (collisionDirection == 'b') { + //if collision is from bottom of the bullet, it is grounded, so that it can be bounced + bullets[i].grounded = true; + } else if (collisionDirection == 't' || collisionDirection == 'l' || collisionDirection == 'r') { + bullets.splice(i, 1); + } + } + }; + + this.checkPowerUpMarioCollision = function() { + for (var i = 0; i < powerUps.length; i++) { + var collWithMario = that.collisionCheck(powerUps[i], mario); + if (collWithMario) { + if (powerUps[i].type == 30 && mario.type == 'small') { + //mushroom + mario.type = 'big'; + } else if (powerUps[i].type == 31) { + //flower + mario.type = 'fire'; + } + powerUps.splice(i, 1); + + score.totalScore += 1000; + score.updateTotalScore(); + + //sound when mushroom appears + gameSound.play('powerUp'); + } + } + }; + + this.checkEnemyMarioCollision = function() { + for (var i = 0; i < goombas.length; i++) { + if (!mario.invulnerable && goombas[i].state != 'dead' && goombas[i].state != 'deadFromBullet') { + //if mario is invulnerable or goombas state is dead, collision doesnt occur + var collWithMario = that.collisionCheck(goombas[i], mario); + + if (collWithMario == 't') { + //kill goombas if collision is from top + goombas[i].state = 'dead'; + + mario.velY = -mario.speed; + + score.totalScore += 1000; + score.updateTotalScore(); + + //sound when enemy dies + gameSound.play('killEnemy'); + } else if (collWithMario == 'r' || collWithMario == 'l' || collWithMario == 'b') { + goombas[i].velX *= -1; + + if (mario.type == 'big') { + mario.type = 'small'; + mario.invulnerable = true; + collWithMario = undefined; + + //sound when mario powerDowns + gameSound.play('powerDown'); + + setTimeout(function() { + mario.invulnerable = false; + }, 1000); + } else if (mario.type == 'fire') { + mario.type = 'big'; + mario.invulnerable = true; + + collWithMario = undefined; + + //sound when mario powerDowns + gameSound.play('powerDown'); + + setTimeout(function() { + mario.invulnerable = false; + }, 1000); + } else if (mario.type == 'small') { + //kill mario if collision occurs when he is small + that.pauseGame(); + + mario.frame = 13; + collWithMario = undefined; + + score.lifeCount--; + score.updateLifeCount(); + + //sound when mario dies + gameSound.play('marioDie'); + + timeOutId = setTimeout(function() { + if (score.lifeCount == 0) { + that.gameOver(); + } else { + that.resetGame(); + } + }, 3000); + break; + } + } + } + } + }; + + this.checkBulletEnemyCollision = function() { + for (var i = 0; i < goombas.length; i++) { + for (var j = 0; j < bullets.length; j++) { + if (goombas[i] && goombas[i].state != 'dead') { + //check for collision only if goombas exist and is not dead + var collWithBullet = that.collisionCheck(goombas[i], bullets[j]); + } + + if (collWithBullet) { + bullets[j] = null; + bullets.splice(j, 1); + + goombas[i].state = 'deadFromBullet'; + + score.totalScore += 1000; + score.updateTotalScore(); + + //sound when enemy dies + gameSound.play('killEnemy'); + } + } + } + }; + + this.wallCollision = function() { + //for walls (vieport walls) + if (mario.x >= maxWidth - mario.width) { + mario.x = maxWidth - mario.width; + } else if (mario.x <= translatedDist) { + mario.x = translatedDist + 1; + } + + //for ground (viewport ground) + if (mario.y >= height) { + that.pauseGame(); + + //sound when mario dies + gameSound.play('marioDie'); + + score.lifeCount--; + score.updateLifeCount(); + + timeOutId = setTimeout(function() { + if (score.lifeCount == 0) { + that.gameOver(); + } else { + that.resetGame(); + } + }, 3000); + } + }; + + //controlling mario with key events + this.updateMario = function() { + var friction = 0.9; + var gravity = 0.2; + + mario.checkMarioType(); + + if (keys[38] || keys[32]) { + //up arrow + if (!mario.jumping && mario.grounded) { + mario.jumping = true; + mario.grounded = false; + mario.velY = -(mario.speed / 2 + 5.5); + + // mario sprite position + if (mario.frame == 0 || mario.frame == 1) { + mario.frame = 3; //right jump + } else if (mario.frame == 8 || mario.frame == 9) { + mario.frame = 2; //left jump + } + + //sound when mario jumps + gameSound.play('jump'); + } + } + + if (keys[39]) { + //right arrow + that.checkMarioPos(); //if mario goes to the center of the screen, sidescroll the map + + if (mario.velX < mario.speed) { + mario.velX++; + } + + //mario sprite position + if (!mario.jumping) { + tickCounter += 1; + + if (tickCounter > maxTick / mario.speed) { + tickCounter = 0; + + if (mario.frame != 1) { + mario.frame = 1; + } else { + mario.frame = 0; + } + } + } + } + + if (keys[37]) { + //left arrow + if (mario.velX > -mario.speed) { + mario.velX--; + } + + //mario sprite position + if (!mario.jumping) { + tickCounter += 1; + + if (tickCounter > maxTick / mario.speed) { + tickCounter = 0; + + if (mario.frame != 9) { + mario.frame = 9; + } else { + mario.frame = 8; + } + } + } + } + + if (keys[16]) { + //shift key + mario.speed = 4.5; + } else { + mario.speed = 3; + } + + if (keys[17] && mario.type == 'fire') { + //ctrl key + if (!bulletFlag) { + bulletFlag = true; + var bullet = new Bullet(); + if (mario.frame == 9 || mario.frame == 8 || mario.frame == 2) { + var direction = -1; + } else { + var direction = 1; + } + bullet.init(mario.x, mario.y, direction); + bullets.push(bullet); + + //bullet sound + gameSound.play('bullet'); + + setTimeout(function() { + bulletFlag = false; //only lets mario fire bullet after 500ms + }, 500); + } + } + + //velocity 0 sprite position + if (mario.velX > 0 && mario.velX < 1 && !mario.jumping) { + mario.frame = 0; + } else if (mario.velX > -1 && mario.velX < 0 && !mario.jumping) { + mario.frame = 8; + } + + if (mario.grounded) { + mario.velY = 0; + + //grounded sprite position + if (mario.frame == 3) { + mario.frame = 0; //looking right + } else if (mario.frame == 2) { + mario.frame = 8; //looking left + } + } + + //change mario position + mario.velX *= friction; + mario.velY += gravity; + + mario.x += mario.velX; + mario.y += mario.velY; + }; + + this.checkMarioPos = function() { + centerPos = translatedDist + viewPort / 2; + + //side scrolling as mario reaches center of the viewPort + if (mario.x > centerPos && centerPos + viewPort / 2 < maxWidth) { + gameUI.scrollWindow(-mario.speed, 0); + translatedDist += mario.speed; + } + }; + + this.levelFinish = function(collisionDirection) { + //game finishes when mario slides the flagPole and collides with the ground + if (collisionDirection == 'r') { + mario.x += 10; + mario.velY = 2; + mario.frame = 11; + } else if (collisionDirection == 'l') { + mario.x -= 32; + mario.velY = 2; + mario.frame = 10; + } + + if (marioInGround) { + mario.x += 20; + mario.frame = 10; + tickCounter += 1; + if (tickCounter > maxTick) { + that.pauseGame(); + + mario.x += 10; + tickCounter = 0; + mario.frame = 12; + + //sound when stage clears + gameSound.play('stageClear'); + + timeOutId = setTimeout(function() { + currentLevel++; + if (originalMaps[currentLevel]) { + that.init(originalMaps, currentLevel); + score.updateLevelNum(currentLevel); + } else { + that.gameOver(); + } + }, 5000); + } + } + }; + + this.pauseGame = function() { + window.cancelAnimationFrame(animationID); + }; + + this.gameOver = function() { + score.gameOverView(); + gameUI.makeBox(0, 0, maxWidth, height); + gameUI.writeText('Game Over', centerPos - 80, height - 300); + gameUI.writeText('Thanks For Playing', centerPos - 122, height / 2); + }; + + this.resetGame = function() { + that.clearInstances(); + that.init(originalMaps, currentLevel); + }; + + this.clearInstances = function() { + mario = null; + element = null; + gameSound = null; + + goombas = []; + bullets = []; + powerUps = []; + }; + + this.clearTimeOut = function() { + clearTimeout(timeOutId); + }; + + this.removeGameScreen = function() { + gameUI.hide(); + + if (score) { + score.hideScore(); + } + }; + + this.showGameScreen = function() { + gameUI.show(); + }; +} diff --git a/projects/Super Mario/js/mainGame/PowerUp.js b/projects/Super Mario/js/mainGame/PowerUp.js new file mode 100644 index 000000000..f0fd078ed --- /dev/null +++ b/projects/Super Mario/js/mainGame/PowerUp.js @@ -0,0 +1,52 @@ +function PowerUp() { + var gameUI = GameUI.getInstance(); + + var element = new Image(); + element.src = 'images/powerups.png'; + + this.type; + this.x; + this.y; + this.velX = 2; + this.velY = 0; + this.grounded = false; + this.sX; + this.sY = 0; + this.width = 32; + this.height = 32; + + var that = this; + + this.mushroom = function(x, y) { + that.x = x; + that.y = y - that.height; + that.type = 30; + that.sX = 0; + }; + + this.flower = function(x, y) { + that.x = x; + that.y = y - that.height; + that.type = 31; + that.sX = 32; + }; + + this.draw = function() { + gameUI.draw(element, that.sX, that.sY, that.width, that.height, that.x, that.y, that.width, that.height); + }; + + this.update = function() { + if (that.type == 30) { + var gravity = 0.2; + + if (that.grounded) { + that.velY = 0; + } + + that.velY += gravity; + + that.x += that.velX; + that.y += that.velY; + } + }; +} diff --git a/projects/Super Mario/js/mainGame/Score.js b/projects/Super Mario/js/mainGame/Score.js new file mode 100644 index 000000000..6616875ff --- /dev/null +++ b/projects/Super Mario/js/mainGame/Score.js @@ -0,0 +1,88 @@ +function Score() { + var view = View.getInstance(); + + var mainWrapper; + var scoreWrapper; + var coinScoreWrapper; + var totalScoreWrapper; + var lifeCountWrapper; + var levelWrapper; + + this.coinScore; + this.totalScore; + this.lifeCount; + + var that = this; + + this.init = function() { + that.coinScore = 0; + that.totalScore = 0; + that.lifeCount = 5; + + mainWrapper = view.getMainWrapper(); + + scoreWrapper = view.create('div'); + coinScoreWrapper = view.create('div'); + totalScoreWrapper = view.create('div'); + lifeCountWrapper = view.create('div'); + levelWrapper = view.create('div'); + + view.addClass(scoreWrapper, 'score-wrapper'); + view.addClass(coinScoreWrapper, 'coin-score'); + view.addClass(totalScoreWrapper, 'total-score'); + view.addClass(lifeCountWrapper, 'life-count'); + view.addClass(levelWrapper, 'level-num'); + + view.append(scoreWrapper, levelWrapper); + view.append(scoreWrapper, lifeCountWrapper); + view.append(scoreWrapper, coinScoreWrapper); + view.append(scoreWrapper, totalScoreWrapper); + view.append(mainWrapper, scoreWrapper); + + that.updateCoinScore(); + that.updateTotalScore(); + that.updateLifeCount(); + that.updateLevelNum(1); + }; + + this.updateCoinScore = function() { + if (that.coinScore == 100) { + that.coinScore = 0; + that.lifeCount++; + that.updateLifeCount(); + } + + view.setHTML(coinScoreWrapper, 'Coins: ' + that.coinScore); + }; + + this.updateTotalScore = function() { + view.setHTML(totalScoreWrapper, 'Score: ' + that.totalScore); + }; + + this.updateLifeCount = function() { + view.setHTML(lifeCountWrapper, 'x ' + that.lifeCount); + }; + + this.updateLevelNum = function(level) { + view.setHTML(levelWrapper, 'Level: ' + level); + }; + + this.displayScore = function() { + view.style(scoreWrapper, { display: 'block', background: '#add1f3' }); + }; + + this.hideScore = function() { + view.style(scoreWrapper, { display: 'none' }); + + that.coinScore = 0; + that.lifeCount = 5; + that.totalScore = 0; + that.updateCoinScore(); + that.updateTotalScore(); + that.updateLifeCount(); + }; + + this.gameOverView = function() { + view.style(scoreWrapper, { background: 'black' }); + }; +} diff --git a/projects/Super Mario/sounds/bullet.wav b/projects/Super Mario/sounds/bullet.wav new file mode 100644 index 000000000..56ed57f83 Binary files /dev/null and b/projects/Super Mario/sounds/bullet.wav differ diff --git a/projects/Super Mario/sounds/coin.wav b/projects/Super Mario/sounds/coin.wav new file mode 100644 index 000000000..fef419194 Binary files /dev/null and b/projects/Super Mario/sounds/coin.wav differ diff --git a/projects/Super Mario/sounds/jump.wav b/projects/Super Mario/sounds/jump.wav new file mode 100644 index 000000000..6883fdac9 Binary files /dev/null and b/projects/Super Mario/sounds/jump.wav differ diff --git a/projects/Super Mario/sounds/kill-enemy.wav b/projects/Super Mario/sounds/kill-enemy.wav new file mode 100644 index 000000000..00ac6c9d6 Binary files /dev/null and b/projects/Super Mario/sounds/kill-enemy.wav differ diff --git a/projects/Super Mario/sounds/mario-die.wav b/projects/Super Mario/sounds/mario-die.wav new file mode 100644 index 000000000..bd3400f88 Binary files /dev/null and b/projects/Super Mario/sounds/mario-die.wav differ diff --git a/projects/Super Mario/sounds/power-down.wav b/projects/Super Mario/sounds/power-down.wav new file mode 100644 index 000000000..bbeec364d Binary files /dev/null and b/projects/Super Mario/sounds/power-down.wav differ diff --git a/projects/Super Mario/sounds/power-up-appear.wav b/projects/Super Mario/sounds/power-up-appear.wav new file mode 100644 index 000000000..1ab578d99 Binary files /dev/null and b/projects/Super Mario/sounds/power-up-appear.wav differ diff --git a/projects/Super Mario/sounds/power-up.wav b/projects/Super Mario/sounds/power-up.wav new file mode 100644 index 000000000..d0857839f Binary files /dev/null and b/projects/Super Mario/sounds/power-up.wav differ diff --git a/projects/Super Mario/sounds/stage-clear.wav b/projects/Super Mario/sounds/stage-clear.wav new file mode 100644 index 000000000..6c396ded1 Binary files /dev/null and b/projects/Super Mario/sounds/stage-clear.wav differ diff --git a/projects/Temprature Converter/index.html b/projects/Temprature Converter/index.html new file mode 100644 index 000000000..843318f4f --- /dev/null +++ b/projects/Temprature Converter/index.html @@ -0,0 +1,48 @@ + + + + + + +Temperature Converter + + +
+

Temperature Converter

+
+
+ + +
+
+ + +
+
+
+
+ + +
+
+ + +
+
+
+ + +
+
+ + + + diff --git a/projects/Temprature Converter/script.js b/projects/Temprature Converter/script.js new file mode 100644 index 000000000..8d8dafda6 --- /dev/null +++ b/projects/Temprature Converter/script.js @@ -0,0 +1,32 @@ +function convertTemperature() { + const fromUnit = document.getElementById("from").value; + const toUnit = document.getElementById("to").value; + const inputValue = parseFloat(document.getElementById("inputTemperature").value); + let convertedValue; + + if (fromUnit === "celsius" && toUnit === "fahrenheit") { + convertedValue = (inputValue * 9/5) + 32; + } else if (fromUnit === "celsius" && toUnit === "kelvin") { + convertedValue = inputValue + 273.15; + } else if (fromUnit === "fahrenheit" && toUnit === "celsius") { + convertedValue = (inputValue - 32) * 5/9; + } else if (fromUnit === "fahrenheit" && toUnit === "kelvin") { + convertedValue = (inputValue - 32) * 5/9 + 273.15; + } else if (fromUnit === "kelvin" && toUnit === "celsius") { + convertedValue = inputValue - 273.15; + } else if (fromUnit === "kelvin" && toUnit === "fahrenheit") { + convertedValue = (inputValue - 273.15) * 9/5 + 32; + } else { + convertedValue = inputValue; + } + + document.getElementById("result").value = convertedValue.toFixed(2); + } + + function clearFields() { + document.getElementById("from").value = "celsius"; + document.getElementById("to").value = "celsius"; + document.getElementById("inputTemperature").value = ""; + document.getElementById("result").value = ""; + } + \ No newline at end of file diff --git a/projects/Temprature Converter/style.css b/projects/Temprature Converter/style.css new file mode 100644 index 000000000..4a55dfc72 --- /dev/null +++ b/projects/Temprature Converter/style.css @@ -0,0 +1,101 @@ +@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600;700;800;900&display=swap'); + + +body { + margin: 0; + display: flex; + justify-content: center; + align-items: center; + min-height: 100vh; + background-color: #dbdada; + font-family: 'Poppins' , sans-serif; + } + + .container { + + background-color: white; + border-radius: 10px; + padding: 20px; + box-shadow: inset 5px 5px 22px #ffffff, + 5px 5px 22px rgba(0, 0, 0, 0.3); + width: 500px; + } + + .title { + text-align: center; + } + + .input-row-unit { + display: flex; + justify-content: space-between; + margin-top: 10px; + margin-left: 10px; + + } + + .input-group-unit1 { + flex: 1; + margin-right: 10px; + } + + .input-group-unit2 { + flex: 1; + margin-right: 10px; + + } + + .input-group1 { + position: relative; + margin-top: 20px; + flex: 1; + margin-right: 10px; + margin-left: 10px; + } + + .input-group2 { + position: relative; + margin-top: 20px; + flex: 1; + margin-right: 10px; + margin-left: 10px; + } + + .input-row{ + margin-right: 20px; + } + + input[type="number"], + input[type="text"], + select { + width: 100%; + padding: 10px; + border: 1px solid #ccc; + border-radius: 4px; + box-shadow: inset -1px -1px 8px #ffffff, inset 1px 1px 8px rgba(0,0,0,.16); + + } + + .button-row { + margin-top: 20px; + display: flex; + justify-content: space-between; + margin-right: 300px; + margin-left: 10px; + } + + button { + background-color: rgb(51, 172, 174); + font-weight: 700; + color: white; + border: none; + border-radius: 4px; + padding: 10px 20px; + cursor: pointer; + } + + button:hover{ + background-color: rgba(51, 172, 174,70%); + color: #1f242d; + box-shadow: 2px 2px 2px #0ef; + scale: 110%; + } \ No newline at end of file diff --git a/projects/Tilting Maze Game/index.html b/projects/Tilting Maze Game/index.html new file mode 100644 index 000000000..53f6d0b06 --- /dev/null +++ b/projects/Tilting Maze Game/index.html @@ -0,0 +1,33 @@ + + + + + + + Tilting Maze Game + + + + +
+
+
+
+
+
+
+
+
+
+
+
+
+ Click the joystick to start! +

Move every ball to the center. Ready for hard mode? Press H

+
+
+
+ + + + \ No newline at end of file diff --git a/projects/Tilting Maze Game/script.js b/projects/Tilting Maze Game/script.js new file mode 100644 index 000000000..be342a21e --- /dev/null +++ b/projects/Tilting Maze Game/script.js @@ -0,0 +1,682 @@ +/* + +If you want to know how this game works, you can find a source code walkthrough video here: https://youtu.be/bTk6dcAckuI + +Follow me on twitter for more: https://twitter.com/HunorBorbely + +*/ + +Math.minmax = (value, limit) => { + return Math.max(Math.min(value, limit), -limit); + }; + + const distance2D = (p1, p2) => { + return Math.sqrt((p2.x - p1.x) ** 2 + (p2.y - p1.y) ** 2); + }; + + // Angle between the two points + const getAngle = (p1, p2) => { + let angle = Math.atan((p2.y - p1.y) / (p2.x - p1.x)); + if (p2.x - p1.x < 0) angle += Math.PI; + return angle; + }; + + // The closest a ball and a wall cap can be + const closestItCanBe = (cap, ball) => { + let angle = getAngle(cap, ball); + + const deltaX = Math.cos(angle) * (wallW / 2 + ballSize / 2); + const deltaY = Math.sin(angle) * (wallW / 2 + ballSize / 2); + + return { x: cap.x + deltaX, y: cap.y + deltaY }; + }; + + // Roll the ball around the wall cap + const rollAroundCap = (cap, ball) => { + // The direction the ball can't move any further because the wall holds it back + let impactAngle = getAngle(ball, cap); + + // The direction the ball wants to move based on it's velocity + let heading = getAngle( + { x: 0, y: 0 }, + { x: ball.velocityX, y: ball.velocityY } + ); + + // The angle between the impact direction and the ball's desired direction + // The smaller this angle is, the bigger the impact + // The closer it is to 90 degrees the smoother it gets (at 90 there would be no collision) + let impactHeadingAngle = impactAngle - heading; + + // Velocity distance if not hit would have occurred + const velocityMagnitude = distance2D( + { x: 0, y: 0 }, + { x: ball.velocityX, y: ball.velocityY } + ); + // Velocity component diagonal to the impact + const velocityMagnitudeDiagonalToTheImpact = + Math.sin(impactHeadingAngle) * velocityMagnitude; + + // How far should the ball be from the wall cap + const closestDistance = wallW / 2 + ballSize / 2; + + const rotationAngle = Math.atan( + velocityMagnitudeDiagonalToTheImpact / closestDistance + ); + + const deltaFromCap = { + x: Math.cos(impactAngle + Math.PI - rotationAngle) * closestDistance, + y: Math.sin(impactAngle + Math.PI - rotationAngle) * closestDistance + }; + + const x = ball.x; + const y = ball.y; + const velocityX = ball.x - (cap.x + deltaFromCap.x); + const velocityY = ball.y - (cap.y + deltaFromCap.y); + const nextX = x + velocityX; + const nextY = y + velocityY; + + return { x, y, velocityX, velocityY, nextX, nextY }; + }; + + // Decreases the absolute value of a number but keeps it's sign, doesn't go below abs 0 + const slow = (number, difference) => { + if (Math.abs(number) <= difference) return 0; + if (number > difference) return number - difference; + return number + difference; + }; + + const mazeElement = document.getElementById("maze"); + const joystickHeadElement = document.getElementById("joystick-head"); + const noteElement = document.getElementById("note"); // Note element for instructions and game won, game failed texts + + let hardMode = false; + let previousTimestamp; + let gameInProgress; + let mouseStartX; + let mouseStartY; + let accelerationX; + let accelerationY; + let frictionX; + let frictionY; + + const pathW = 25; // Path width + const wallW = 10; // Wall width + const ballSize = 10; // Width and height of the ball + const holeSize = 18; + + const debugMode = false; + + let balls = []; + let ballElements = []; + let holeElements = []; + + resetGame(); + + // Draw balls for the first time + balls.forEach(({ x, y }) => { + const ball = document.createElement("div"); + ball.setAttribute("class", "ball"); + ball.style.cssText = `left: ${x}px; top: ${y}px; `; + + mazeElement.appendChild(ball); + ballElements.push(ball); + }); + + // Wall metadata + const walls = [ + // Border + { column: 0, row: 0, horizontal: true, length: 10 }, + { column: 0, row: 0, horizontal: false, length: 9 }, + { column: 0, row: 9, horizontal: true, length: 10 }, + { column: 10, row: 0, horizontal: false, length: 9 }, + + // Horizontal lines starting in 1st column + { column: 0, row: 6, horizontal: true, length: 1 }, + { column: 0, row: 8, horizontal: true, length: 1 }, + + // Horizontal lines starting in 2nd column + { column: 1, row: 1, horizontal: true, length: 2 }, + { column: 1, row: 7, horizontal: true, length: 1 }, + + // Horizontal lines starting in 3rd column + { column: 2, row: 2, horizontal: true, length: 2 }, + { column: 2, row: 4, horizontal: true, length: 1 }, + { column: 2, row: 5, horizontal: true, length: 1 }, + { column: 2, row: 6, horizontal: true, length: 1 }, + + // Horizontal lines starting in 4th column + { column: 3, row: 3, horizontal: true, length: 1 }, + { column: 3, row: 8, horizontal: true, length: 3 }, + + // Horizontal lines starting in 5th column + { column: 4, row: 6, horizontal: true, length: 1 }, + + // Horizontal lines starting in 6th column + { column: 5, row: 2, horizontal: true, length: 2 }, + { column: 5, row: 7, horizontal: true, length: 1 }, + + // Horizontal lines starting in 7th column + { column: 6, row: 1, horizontal: true, length: 1 }, + { column: 6, row: 6, horizontal: true, length: 2 }, + + // Horizontal lines starting in 8th column + { column: 7, row: 3, horizontal: true, length: 2 }, + { column: 7, row: 7, horizontal: true, length: 2 }, + + // Horizontal lines starting in 9th column + { column: 8, row: 1, horizontal: true, length: 1 }, + { column: 8, row: 2, horizontal: true, length: 1 }, + { column: 8, row: 3, horizontal: true, length: 1 }, + { column: 8, row: 4, horizontal: true, length: 2 }, + { column: 8, row: 8, horizontal: true, length: 2 }, + + // Vertical lines after the 1st column + { column: 1, row: 1, horizontal: false, length: 2 }, + { column: 1, row: 4, horizontal: false, length: 2 }, + + // Vertical lines after the 2nd column + { column: 2, row: 2, horizontal: false, length: 2 }, + { column: 2, row: 5, horizontal: false, length: 1 }, + { column: 2, row: 7, horizontal: false, length: 2 }, + + // Vertical lines after the 3rd column + { column: 3, row: 0, horizontal: false, length: 1 }, + { column: 3, row: 4, horizontal: false, length: 1 }, + { column: 3, row: 6, horizontal: false, length: 2 }, + + // Vertical lines after the 4th column + { column: 4, row: 1, horizontal: false, length: 2 }, + { column: 4, row: 6, horizontal: false, length: 1 }, + + // Vertical lines after the 5th column + { column: 5, row: 0, horizontal: false, length: 2 }, + { column: 5, row: 6, horizontal: false, length: 1 }, + { column: 5, row: 8, horizontal: false, length: 1 }, + + // Vertical lines after the 6th column + { column: 6, row: 4, horizontal: false, length: 1 }, + { column: 6, row: 6, horizontal: false, length: 1 }, + + // Vertical lines after the 7th column + { column: 7, row: 1, horizontal: false, length: 4 }, + { column: 7, row: 7, horizontal: false, length: 2 }, + + // Vertical lines after the 8th column + { column: 8, row: 2, horizontal: false, length: 1 }, + { column: 8, row: 4, horizontal: false, length: 2 }, + + // Vertical lines after the 9th column + { column: 9, row: 1, horizontal: false, length: 1 }, + { column: 9, row: 5, horizontal: false, length: 2 } + ].map((wall) => ({ + x: wall.column * (pathW + wallW), + y: wall.row * (pathW + wallW), + horizontal: wall.horizontal, + length: wall.length * (pathW + wallW) + })); + + // Draw walls + walls.forEach(({ x, y, horizontal, length }) => { + const wall = document.createElement("div"); + wall.setAttribute("class", "wall"); + wall.style.cssText = ` + left: ${x}px; + top: ${y}px; + width: ${wallW}px; + height: ${length}px; + transform: rotate(${horizontal ? -90 : 0}deg); + `; + + mazeElement.appendChild(wall); + }); + + const holes = [ + { column: 0, row: 5 }, + { column: 2, row: 0 }, + { column: 2, row: 4 }, + { column: 4, row: 6 }, + { column: 6, row: 2 }, + { column: 6, row: 8 }, + { column: 8, row: 1 }, + { column: 8, row: 2 } + ].map((hole) => ({ + x: hole.column * (wallW + pathW) + (wallW / 2 + pathW / 2), + y: hole.row * (wallW + pathW) + (wallW / 2 + pathW / 2) + })); + + joystickHeadElement.addEventListener("mousedown", function (event) { + if (!gameInProgress) { + mouseStartX = event.clientX; + mouseStartY = event.clientY; + gameInProgress = true; + window.requestAnimationFrame(main); + noteElement.style.opacity = 0; + joystickHeadElement.style.cssText = ` + animation: none; + cursor: grabbing; + `; + } + }); + + window.addEventListener("mousemove", function (event) { + if (gameInProgress) { + const mouseDeltaX = -Math.minmax(mouseStartX - event.clientX, 15); + const mouseDeltaY = -Math.minmax(mouseStartY - event.clientY, 15); + + joystickHeadElement.style.cssText = ` + left: ${mouseDeltaX}px; + top: ${mouseDeltaY}px; + animation: none; + cursor: grabbing; + `; + + const rotationY = mouseDeltaX * 0.8; // Max rotation = 12 + const rotationX = mouseDeltaY * 0.8; + + mazeElement.style.cssText = ` + transform: rotateY(${rotationY}deg) rotateX(${-rotationX}deg) + `; + + const gravity = 2; + const friction = 0.01; // Coefficients of friction + + accelerationX = gravity * Math.sin((rotationY / 180) * Math.PI); + accelerationY = gravity * Math.sin((rotationX / 180) * Math.PI); + frictionX = gravity * Math.cos((rotationY / 180) * Math.PI) * friction; + frictionY = gravity * Math.cos((rotationX / 180) * Math.PI) * friction; + } + }); + + window.addEventListener("keydown", function (event) { + // If not an arrow key or space or H was pressed then return + if (![" ", "H", "h", "E", "e"].includes(event.key)) return; + + // If an arrow key was pressed then first prevent default + event.preventDefault(); + + // If space was pressed restart the game + if (event.key == " ") { + resetGame(); + return; + } + + // Set Hard mode + if (event.key == "H" || event.key == "h") { + hardMode = true; + resetGame(); + return; + } + + // Set Easy mode + if (event.key == "E" || event.key == "e") { + hardMode = false; + resetGame(); + return; + } + }); + + function resetGame() { + previousTimestamp = undefined; + gameInProgress = false; + mouseStartX = undefined; + mouseStartY = undefined; + accelerationX = undefined; + accelerationY = undefined; + frictionX = undefined; + frictionY = undefined; + + mazeElement.style.cssText = ` + transform: rotateY(0deg) rotateX(0deg) + `; + + joystickHeadElement.style.cssText = ` + left: 0; + top: 0; + animation: glow; + cursor: grab; + `; + + if (hardMode) { + noteElement.innerHTML = `Click the joystick to start! +

Hard mode, Avoid black holes. Back to easy mode? Press E

`; + } else { + noteElement.innerHTML = `Click the joystick to start! +

Move every ball to the center. Ready for hard mode? Press H

`; + } + noteElement.style.opacity = 1; + + balls = [ + { column: 0, row: 0 }, + { column: 9, row: 0 }, + { column: 0, row: 8 }, + { column: 9, row: 8 } + ].map((ball) => ({ + x: ball.column * (wallW + pathW) + (wallW / 2 + pathW / 2), + y: ball.row * (wallW + pathW) + (wallW / 2 + pathW / 2), + velocityX: 0, + velocityY: 0 + })); + + if (ballElements.length) { + balls.forEach(({ x, y }, index) => { + ballElements[index].style.cssText = `left: ${x}px; top: ${y}px; `; + }); + } + + // Remove previous hole elements + holeElements.forEach((holeElement) => { + mazeElement.removeChild(holeElement); + }); + holeElements = []; + + // Reset hole elements if hard mode + if (hardMode) { + holes.forEach(({ x, y }) => { + const ball = document.createElement("div"); + ball.setAttribute("class", "black-hole"); + ball.style.cssText = `left: ${x}px; top: ${y}px; `; + + mazeElement.appendChild(ball); + holeElements.push(ball); + }); + } + } + + function main(timestamp) { + // It is possible to reset the game mid-game. This case the look should stop + if (!gameInProgress) return; + + if (previousTimestamp === undefined) { + previousTimestamp = timestamp; + window.requestAnimationFrame(main); + return; + } + + const maxVelocity = 1.5; + + // Time passed since last cycle divided by 16 + // This function gets called every 16 ms on average so dividing by 16 will result in 1 + const timeElapsed = (timestamp - previousTimestamp) / 16; + + try { + // If mouse didn't move yet don't do anything + if (accelerationX != undefined && accelerationY != undefined) { + const velocityChangeX = accelerationX * timeElapsed; + const velocityChangeY = accelerationY * timeElapsed; + const frictionDeltaX = frictionX * timeElapsed; + const frictionDeltaY = frictionY * timeElapsed; + + balls.forEach((ball) => { + if (velocityChangeX == 0) { + // No rotation, the plane is flat + // On flat surface friction can only slow down, but not reverse movement + ball.velocityX = slow(ball.velocityX, frictionDeltaX); + } else { + ball.velocityX = ball.velocityX + velocityChangeX; + ball.velocityX = Math.max(Math.min(ball.velocityX, 1.5), -1.5); + ball.velocityX = + ball.velocityX - Math.sign(velocityChangeX) * frictionDeltaX; + ball.velocityX = Math.minmax(ball.velocityX, maxVelocity); + } + + if (velocityChangeY == 0) { + // No rotation, the plane is flat + // On flat surface friction can only slow down, but not reverse movement + ball.velocityY = slow(ball.velocityY, frictionDeltaY); + } else { + ball.velocityY = ball.velocityY + velocityChangeY; + ball.velocityY = + ball.velocityY - Math.sign(velocityChangeY) * frictionDeltaY; + ball.velocityY = Math.minmax(ball.velocityY, maxVelocity); + } + + // Preliminary next ball position, only becomes true if no hit occurs + // Used only for hit testing, does not mean that the ball will reach this position + ball.nextX = ball.x + ball.velocityX; + ball.nextY = ball.y + ball.velocityY; + + if (debugMode) console.log("tick", ball); + + walls.forEach((wall, wi) => { + if (wall.horizontal) { + // Horizontal wall + + if ( + ball.nextY + ballSize / 2 >= wall.y - wallW / 2 && + ball.nextY - ballSize / 2 <= wall.y + wallW / 2 + ) { + // Ball got within the strip of the wall + // (not necessarily hit it, could be before or after) + + const wallStart = { + x: wall.x, + y: wall.y + }; + const wallEnd = { + x: wall.x + wall.length, + y: wall.y + }; + + if ( + ball.nextX + ballSize / 2 >= wallStart.x - wallW / 2 && + ball.nextX < wallStart.x + ) { + // Ball might hit the left cap of a horizontal wall + const distance = distance2D(wallStart, { + x: ball.nextX, + y: ball.nextY + }); + if (distance < ballSize / 2 + wallW / 2) { + if (debugMode && wi > 4) + console.warn("too close h head", distance, ball); + + // Ball hits the left cap of a horizontal wall + const closest = closestItCanBe(wallStart, { + x: ball.nextX, + y: ball.nextY + }); + const rolled = rollAroundCap(wallStart, { + x: closest.x, + y: closest.y, + velocityX: ball.velocityX, + velocityY: ball.velocityY + }); + + Object.assign(ball, rolled); + } + } + + if ( + ball.nextX - ballSize / 2 <= wallEnd.x + wallW / 2 && + ball.nextX > wallEnd.x + ) { + // Ball might hit the right cap of a horizontal wall + const distance = distance2D(wallEnd, { + x: ball.nextX, + y: ball.nextY + }); + if (distance < ballSize / 2 + wallW / 2) { + if (debugMode && wi > 4) + console.warn("too close h tail", distance, ball); + + // Ball hits the right cap of a horizontal wall + const closest = closestItCanBe(wallEnd, { + x: ball.nextX, + y: ball.nextY + }); + const rolled = rollAroundCap(wallEnd, { + x: closest.x, + y: closest.y, + velocityX: ball.velocityX, + velocityY: ball.velocityY + }); + + Object.assign(ball, rolled); + } + } + + if (ball.nextX >= wallStart.x && ball.nextX <= wallEnd.x) { + // The ball got inside the main body of the wall + if (ball.nextY < wall.y) { + // Hit horizontal wall from top + ball.nextY = wall.y - wallW / 2 - ballSize / 2; + } else { + // Hit horizontal wall from bottom + ball.nextY = wall.y + wallW / 2 + ballSize / 2; + } + ball.y = ball.nextY; + ball.velocityY = -ball.velocityY / 3; + + if (debugMode && wi > 4) + console.error("crossing h line, HIT", ball); + } + } + } else { + // Vertical wall + + if ( + ball.nextX + ballSize / 2 >= wall.x - wallW / 2 && + ball.nextX - ballSize / 2 <= wall.x + wallW / 2 + ) { + // Ball got within the strip of the wall + // (not necessarily hit it, could be before or after) + + const wallStart = { + x: wall.x, + y: wall.y + }; + const wallEnd = { + x: wall.x, + y: wall.y + wall.length + }; + + if ( + ball.nextY + ballSize / 2 >= wallStart.y - wallW / 2 && + ball.nextY < wallStart.y + ) { + // Ball might hit the top cap of a horizontal wall + const distance = distance2D(wallStart, { + x: ball.nextX, + y: ball.nextY + }); + if (distance < ballSize / 2 + wallW / 2) { + if (debugMode && wi > 4) + console.warn("too close v head", distance, ball); + + // Ball hits the left cap of a horizontal wall + const closest = closestItCanBe(wallStart, { + x: ball.nextX, + y: ball.nextY + }); + const rolled = rollAroundCap(wallStart, { + x: closest.x, + y: closest.y, + velocityX: ball.velocityX, + velocityY: ball.velocityY + }); + + Object.assign(ball, rolled); + } + } + + if ( + ball.nextY - ballSize / 2 <= wallEnd.y + wallW / 2 && + ball.nextY > wallEnd.y + ) { + // Ball might hit the bottom cap of a horizontal wall + const distance = distance2D(wallEnd, { + x: ball.nextX, + y: ball.nextY + }); + if (distance < ballSize / 2 + wallW / 2) { + if (debugMode && wi > 4) + console.warn("too close v tail", distance, ball); + + // Ball hits the right cap of a horizontal wall + const closest = closestItCanBe(wallEnd, { + x: ball.nextX, + y: ball.nextY + }); + const rolled = rollAroundCap(wallEnd, { + x: closest.x, + y: closest.y, + velocityX: ball.velocityX, + velocityY: ball.velocityY + }); + + Object.assign(ball, rolled); + } + } + + if (ball.nextY >= wallStart.y && ball.nextY <= wallEnd.y) { + // The ball got inside the main body of the wall + if (ball.nextX < wall.x) { + // Hit vertical wall from left + ball.nextX = wall.x - wallW / 2 - ballSize / 2; + } else { + // Hit vertical wall from right + ball.nextX = wall.x + wallW / 2 + ballSize / 2; + } + ball.x = ball.nextX; + ball.velocityX = -ball.velocityX / 3; + + if (debugMode && wi > 4) + console.error("crossing v line, HIT", ball); + } + } + } + }); + + // Detect is a ball fell into a hole + if (hardMode) { + holes.forEach((hole, hi) => { + const distance = distance2D(hole, { + x: ball.nextX, + y: ball.nextY + }); + + if (distance <= holeSize / 2) { + // The ball fell into a hole + holeElements[hi].style.backgroundColor = "red"; + throw Error("The ball fell into a hole"); + } + }); + } + + // Adjust ball metadata + ball.x = ball.x + ball.velocityX; + ball.y = ball.y + ball.velocityY; + }); + + // Move balls to their new position on the UI + balls.forEach(({ x, y }, index) => { + ballElements[index].style.cssText = `left: ${x}px; top: ${y}px; `; + }); + } + + // Win detection + if ( + balls.every( + (ball) => distance2D(ball, { x: 350 / 2, y: 315 / 2 }) < 65 / 2 + ) + ) { + noteElement.innerHTML = `Congrats, you did it! + ${!hardMode ? "

Press H for hard mode

" : ""}`; + noteElement.style.opacity = 1; + gameInProgress = false; + } else { + previousTimestamp = timestamp; + window.requestAnimationFrame(main); + } + } catch (error) { + if (error.message == "The ball fell into a hole") { + noteElement.innerHTML = `A ball fell into a black hole! Press space to reset the game. +

+ Back to easy? Press E +

`; + noteElement.style.opacity = 1; + gameInProgress = false; + } else throw error; + } + } + \ No newline at end of file diff --git a/projects/Tilting Maze Game/style.css b/projects/Tilting Maze Game/style.css new file mode 100644 index 000000000..6c99a0651 --- /dev/null +++ b/projects/Tilting Maze Game/style.css @@ -0,0 +1,198 @@ +body { + /* https://coolors.co/f06449-ede6e3-7d82b8-36382e-613f75 */ + --background-color: #ede6e3; + --wall-color: #36382e; + --joystick-color: #210124; + --joystick-head-color: #f06449; + --ball-color: #f06449; + --end-color: #7d82b8; + --text-color: #210124; + + font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif; + background-color: var(--background-color); +} + +html, +body { + height: 100%; + margin: 0; +} + +#center { + display: flex; + align-items: center; + justify-content: center; + height: 100%; +} + +#game { + display: grid; + grid-template-columns: auto 150px; + grid-template-rows: 1fr auto 1fr; + gap: 30px; + perspective: 600px; +} + +#maze { + position: relative; + grid-row: 1 / -1; + grid-column: 1; + width: 350px; + height: 315px; + display: flex; + justify-content: center; + align-items: center; +} + +#end { + width: 65px; + height: 65px; + border: 5px dashed var(--end-color); + border-radius: 50%; +} + +#joystick { + position: relative; + background-color: var(--joystick-color); + border-radius: 50%; + width: 50px; + height: 50px; + display: flex; + align-items: center; + justify-content: center; + margin: 10px 50px; + grid-row: 2; +} + +#joystick-head { + position: relative; + background-color: var(--joystick-head-color); + border-radius: 50%; + width: 20px; + height: 20px; + cursor: grab; + + animation-name: glow; + animation-duration: 0.6s; + animation-iteration-count: infinite; + animation-direction: alternate; + animation-timing-function: ease-in-out; + animation-delay: 4s; +} + +@keyframes glow { + 0% { + transform: scale(1); + } + + 100% { + transform: scale(1.2); + } +} + +.joystick-arrow:nth-of-type(1) { + position: absolute; + bottom: 55px; + + width: 0; + height: 0; + border-left: 10px solid transparent; + border-right: 10px solid transparent; + + border-bottom: 10px solid var(--joystick-color); +} + +.joystick-arrow:nth-of-type(2) { + position: absolute; + top: 55px; + + width: 0; + height: 0; + border-left: 10px solid transparent; + border-right: 10px solid transparent; + + border-top: 10px solid var(--joystick-color); +} + +.joystick-arrow:nth-of-type(3) { + position: absolute; + left: 55px; + + width: 0; + height: 0; + border-top: 10px solid transparent; + border-bottom: 10px solid transparent; + + border-left: 10px solid var(--joystick-color); +} + +.joystick-arrow:nth-of-type(4) { + position: absolute; + right: 55px; + + width: 0; + height: 0; + border-top: 10px solid transparent; + border-bottom: 10px solid transparent; + + border-right: 10px solid var(--joystick-color); +} + +#note { + grid-row: 3; + grid-column: 2; + text-align: center; + font-size: 0.8em; + color: var(--text-color); + transition: opacity 2s; +} + +a:visited { + color: inherit; +} + +.ball { + position: absolute; + margin-top: -5px; + margin-left: -5px; + border-radius: 50%; + background-color: var(--ball-color); + width: 10px; + height: 10px; +} + +.wall { + position: absolute; + background-color: var(--wall-color); + transform-origin: top center; + margin-left: -5px; +} + +.wall::before, +.wall::after { + display: block; + content: ""; + width: 10px; + height: 10px; + background-color: inherit; + border-radius: 50%; + position: absolute; +} + +.wall::before { + top: -5px; +} + +.wall::after { + bottom: -5px; +} + +.black-hole { + position: absolute; + margin-top: -9px; + margin-left: -9px; + border-radius: 50%; + background-color: black; + width: 18px; + height: 18px; +} \ No newline at end of file diff --git a/projects/Train Track Game/1f441.svg b/projects/Train Track Game/1f441.svg new file mode 100644 index 000000000..0e8b66567 --- /dev/null +++ b/projects/Train Track Game/1f441.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/projects/Train Track Game/1f4a5.svg b/projects/Train Track Game/1f4a5.svg new file mode 100644 index 000000000..8a9ea7a54 --- /dev/null +++ b/projects/Train Track Game/1f4a5.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/projects/Train Track Game/1f4f7.svg b/projects/Train Track Game/1f4f7.svg new file mode 100644 index 000000000..f6f39bd8d --- /dev/null +++ b/projects/Train Track Game/1f4f7.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/projects/Train Track Game/1f682.svg b/projects/Train Track Game/1f682.svg new file mode 100644 index 000000000..0120ace53 --- /dev/null +++ b/projects/Train Track Game/1f682.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/projects/Train Track Game/1f9e8.svg b/projects/Train Track Game/1f9e8.svg new file mode 100644 index 000000000..b03e3ed57 --- /dev/null +++ b/projects/Train Track Game/1f9e8.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/projects/Train Track Game/fs.svg b/projects/Train Track Game/fs.svg new file mode 100644 index 000000000..fd525f538 --- /dev/null +++ b/projects/Train Track Game/fs.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/projects/Train Track Game/index.html b/projects/Train Track Game/index.html new file mode 100644 index 000000000..af4af23b8 --- /dev/null +++ b/projects/Train Track Game/index.html @@ -0,0 +1,35 @@ + + + + + + Train Track Game + + + + + +
+
+
+
+

Loading...

+
+
+
+
Track not found?!
+
+ +
+ +
+
+
+
+
+
+
+ + + + \ No newline at end of file diff --git a/projects/Train Track Game/script.js b/projects/Train Track Game/script.js new file mode 100644 index 000000000..f52fcd539 --- /dev/null +++ b/projects/Train Track Game/script.js @@ -0,0 +1,2685 @@ +(C = { + unit: "px", + camX: 0, + camY: 0, + camZ: 0, + camRX: 0, + camRY: 0, + camRZ: 0, + sc: 0, + sprites: [], + pc: 0, + cc: 0, + o: {}, + $: (l) => self[l], + init: (l) => { + l.css || (l.css = ""), + l.html || (l.html = ""), + l.g || (l.g = "scene"), + l.o || (l.o = "center"), + "top left" == l.o && ((l.x += l.w / 2), (l.y += l.h / 2)), + "top" == l.o && (l.y += l.h / 2), + "top right" == l.o && ((l.x -= l.w / 2), (l.y += l.h / 2)), + "right" == l.o && (l.x -= l.w / 2), + "bottom right" == l.o && ((l.x -= l.w / 2), (l.y -= l.h / 2)), + "bottom" == l.o && (l.y -= l.h / 2), + "bottom left" == l.o && ((l.x += l.w / 2), (l.y -= l.h / 2)), + "left" == l.o && (l.x += l.w / 2), + l.w || (l.w = 0), + l.h || (l.h = 0), + l.x || (l.x = 0), + l.y || (l.y = 0), + l.z || (l.z = 0), + l.sk || (l.sk = 0), + l.rx || (l.rx = 0), + l.ry || (l.ry = 0), + l.rz || (l.rz = 0), + l.sx || (l.sx = 1), + l.sy || (l.sy = 1), + l.sz || (l.sz = 1), + (C.o[l.n] = l); + }, + group: (l) => { + l.d || 0 === l.d || (l.d = l.h), + C.init(l), + (C.$(l.g).innerHTML += `
`); + }, + plane: (l) => { + l.n || (l.n = "plane" + C.pc++), + C.init(l), + (C.$(l.g).innerHTML += `
${l.html + }`); + }, + sprite: (l) => { + l.n || (l.n = "sprite" + C.sc++), + C.init(l), + (C.$(l.g).innerHTML += `
${l.html + }`), + C.sprites.push(l.n); + }, + cube: (l, t, n, e, a, u, o) => { + l.n || (l.n = "cube" + C.cc++), + C.init(l), + C.group(l), + n && + C.plane({ + g: l.n, + x: l.w / 2, + y: l.d / 2, + w: l.w, + h: l.d, + b: l.b, + css: "bottom", + }), + e && + C.plane({ + g: l.n, + y: l.d / 2, + w: l.d, + h: l.h, + b: l.b1 || l.b, + rx: -90, + ry: -90, + o: "bottom", + css: "left", + }), + a && + C.plane({ + g: l.n, + x: l.w, + y: l.d / 2, + w: l.d, + h: l.h, + b: l.b2 || l.b, + rx: -90, + ry: -90, + o: "bottom", + css: "right", + }), + o && + C.plane({ + g: l.n, + x: l.w / 2, + y: 0, + w: l.w, + h: l.h, + b: l.b1 || l.b, + rx: -90, + o: "bottom", + css: "back", + }), + u && + C.plane({ + g: l.n, + x: l.w / 2, + y: l.d, + w: l.w, + h: l.h, + b: l.b2 || l.b, + rx: -90, + o: "bottom", + css: "front", + }), + t && + C.plane({ + g: l.n, + x: l.w / 2, + y: l.d / 2, + z: l.h, + w: l.w, + h: l.d, + b: l.up || l.b, + css: "top", + }); + }, + camera: (l) => { + for (var t in (l && (l.x || 0 === l.x) && (C.camX = l.x), + l && (l.y || 0 === l.y) && (C.camY = l.y), + l && (l.z || 0 === l.z) && (C.camZ = l.z), + l && (l.rx || 0 === l.rx) && (C.camRX = l.rx), + l && (l.ry || 0 === l.ry) && (C.camRY = l.ry), + l && (l.rz || 0 === l.rz) && (C.camRZ = l.rz), + (C.camX += (Math.random() - 0.5) / 1e3), + (scene.style.transform = `translateX(${-C.camX}${C.unit + })translateY(${-C.camY}${C.unit})translateZ(${-C.camZ}${C.unit})rotateX(${C.camRX + }deg)rotateY(${C.camRY}deg)rotateZ(${C.camRZ}deg)`), + C.sprites)) { + var n = C.$(C.sprites[t]), + e = n.style.transform.replace(/ *rotate.*\(.*?deg\)/g, ""); + n.style.transform = + e + `rotateZ(${-C.camRZ}deg)rotateX(${-C.camRX}deg)`; + } + }, + move: (l) => { + if (l.n) { + var t = C.$(l.n), + n = C.o[l.n]; + (l.x || 0 === l.x) && (n.x = l.x), + (l.y || 0 === l.y) && (n.y = l.y), + (l.z || 0 === l.z) && (n.z = l.z), + (l.rx || 0 === l.rx) && (n.rx = l.rx), + (l.ry || 0 === l.ry) && (n.ry = l.ry), + (l.rz || 0 === l.rz) && (n.rz = l.rz), + (l.sx || 0 === l.sx) && (n.sx = l.sx), + (l.sy || 0 === l.sy) && (n.sy = l.sy), + (l.sz || 0 === l.sz) && (n.sz = l.sz), + (C.o[l.n] = n), + (t.style.transform = C.tr(n)); + } + }, + tr: (l) => + `translateX(-50%)translateY(-50%)translateX(${l.x}${C.unit})translateY(${l.y}${C.unit})translateZ(${l.z}${C.unit})rotateX(${l.rx}deg)rotateY(${l.ry}deg)rotateZ(${l.rz}deg)scaleX(${l.sx})scaleY(${l.sy})scaleZ(${l.sz})skew(${l.sk})`, +}), + (draw_train = (l, t, n) => { + C.group({ n: "train", x: l, y: t, z: n }), + C.plane({ + g: "train", + w: 50, + h: 50, + y: -10, + z: 2, + html: "", + css: "train", + rx: -90, + ry: 180, + o: "bottom", + }), + C.plane({ + g: "train", + w: 50, + h: 50, + y: 10, + z: 2, + html: "", + css: "train", + rx: -90, + ry: 180, + o: "bottom", + }), + C.cube( + { + g: "train", + x: -15, + z: 10, + w: 16, + h: 34.5, + d: 19, + b: "#A11", + up: "#911", + }, + 1, + 0, + 1, + 1, + 0, + 0 + ), + C.cube( + { g: "train", x: 6, z: 15, w: 26, h: 18, d: 19, b: "#444" }, + 1, + 0, + 1, + 1, + 0, + 0 + ), + C.cube( + { g: "train", x: 12, z: 33, w: 8, h: 10, d: 19, b: "#666" }, + 0, + 0, + 1, + 1, + 0, + 0 + ), + C.cube( + { g: "train", x: 12, z: 42, w: 10, h: 5, d: 19, b: "#444" }, + 1, + 0, + 1, + 1, + 0, + 0 + ), + C.plane({ g: "train", b: "#c46c0a", w: 2.5, h: 19, z: 34 }), + C.plane({ g: "train", b: "#c46c0a", w: 2.5, h: 19, z: 34, x: 7.5 }), + C.plane({ + g: "train", + b: "#151515", + w: 15, + h: 19, + z: 24, + x: 20.5, + ry: 90, + }), + C.plane({ g: "train", b: "#c33", w: 15, h: 19, z: 10, x: 21, ry: 45 }); + }), + (draw_boat = (l, t, n) => { + if (!mobile) { + var e = (3.1 * Math.random()) | 0; + C.sprite({ + n: "boat", + w: 50, + h: 50, + x: l, + y: t - 5, + html: ["⛵", "⛴", "🚢", "🐳"][e], + z: [-235, -245, -240, -227][e], + css: "boat", + rx: -90, + ry: 180, + o: "bottom", + }); + } + }), + (draw_track = (l, t, n, e, a = 1, u = "") => { + C.group({ + n: "group" + gc, + w: 100, + h: 22, + sx: a, + sy: a, + sz: a, + x: l, + y: t, + z: n, + css: "track", + }), + C.cube( + { + g: "group" + gc, + w: 110, + h: 6, + d: 8, + x: 50, + y: 11, + b: "#888", + css: "iron", + }, + 1, + 0, + 0, + 0, + 1, + mobile ? 0 : 1 + ), + C.cube( + { + g: "group" + gc, + w: 110, + h: 6, + d: 8, + x: 50, + y: -11, + b: "#888", + css: "iron", + }, + 1, + 0, + 0, + 0, + mobile ? 0 : 1, + 1 + ), + C.plane({ + g: "group" + gc, + w: 107, + h: 16, + x: 50, + z: 6, + css: "woods", + html: _ ? u : "", + }), + e && + C.cube( + { + g: "group" + gc, + w: 5, + h: (n - -244) / a + (7 != S && (mobile || S < 4) ? 0 : 300), + d: 5, + x: 50, + z: + -0.2 - (n - -244) / a - (7 != S && (mobile || S < 4) ? 0 : 300), + b: "#333", + b2: "#555", + b3: "#333", + }, + 0, + 0, + 1, + 1, + 1, + 0 + ), + gc++; + }), + (draw_track_lite = (l, t, n, e, a = 1, u = "") => { + C.group({ + n: "group" + gc, + w: 500, + h: 22, + sx: a, + sy: a, + sz: a, + x: l, + y: t, + z: n, + css: "track", + }), + C.cube( + { + g: "group" + gc, + w: 500, + h: 6, + d: 8, + x: 50, + y: 11, + b: "#888", + css: "iron", + }, + 1, + 0, + 0, + 0, + 1, + mobile ? 0 : 1 + ), + C.cube( + { + g: "group" + gc, + w: 500, + h: 6, + d: 8, + x: 50, + y: -11, + b: "#888", + css: "iron", + }, + 1, + 0, + 0, + 0, + mobile ? 0 : 1, + 1 + ), + C.plane({ + g: "group" + gc, + w: 500, + h: 16, + x: 50, + z: 6, + css: "woods", + html: _ ? u : "", + }), + gc++; + }), + (draw_tracks = () => { + draw_track_lite(-400, 0, 0); + for (var l = 0; l < track.length; l++) + draw_track( + track[l][0], + track[l][1], + track[l][2], + track[l][3], + track[l][4], + l + "" + ); + track[7] + ? draw_track_lite( + track[7][0] + 500 * (track[7][4] || 1), + track[7][1], + track[7][2], + 0, + track[7][4] || 1 + ) + : draw_track_lite( + track[track.length - 1][0] + 500, + track[track.length - 1][1], + track[track.length - 1][2] + ); + }), + (draw_dynamite = (l, t, n, e) => { + C.sprite({ + w: 30, + h: 30, + x: l, + y: t - 11, + z: n + 30, + html: "", + css: "dynamite", + n: "d_" + e, + }); + }), + (draw_hills = () => { + var l, t, n; + for ( + mobile || + C.sprite({ w: 500, h: 500, x: -1e3, y: -2e3, z: 1e3, css: "sun" }), + C.plane({ n: "river", w: 668, h: 1200, x: 0, z: -247, css: "river" }), + mobile || + C.plane({ + n: "river2", + w: 668, + h: 1200, + x: 0, + z: -246, + css: "river2", + }), + C.plane({ w: 600, h: 1200, x: -700, z: -0.7, css: "hill" }), + C.plane({ w: 600, h: 1200, x: 700, z: -0.7, css: "hill" }), + C.plane({ + w: 600, + h: 1200, + x: -400, + z: -0.5, + ry: 75, + o: "left", + css: "hill2", + n: "h2left", + }), + C.plane({ + w: 600, + h: 1200, + x: 400, + z: -0.5, + ry: -75, + o: "right", + css: "hill2", + n: "h2right", + }), + C.plane({ + w: 600, + h: 600, + x: -620, + y: 0, + z: -300.8, + rx: -90, + sk: "15deg", + css: "hill3", + n: "h3left", + }), + C.plane({ + w: 600, + h: 600, + x: 620, + y: 0, + z: -300.8, + rx: -90, + sk: "-15deg", + css: "hill3", + n: "h3right", + }), + t = 0, + n = 0, + X2 = 0, + Y2 = 0, + X3 = 0, + Y3 = 0; + (Math.abs(X2 - t) < 120 && Math.abs(Y2 - n) < 100) || + (Math.abs(X3 - t) < 100 && Math.abs(Y3 - n) < 100) || + (Math.abs(X3 - X2) < 100 && Math.abs(Y3 - Y2) < 100); + + ) + (t = -470 - 300 * Math.random()), + (X2 = -470 - 300 * Math.random()), + (X3 = -470 - 300 * Math.random()), + (n = -120 - 300 * Math.random()), + (Y2 = -120 - 300 * Math.random()), + (Y3 = -120 - 300 * Math.random()); + for ( + C.sprite({ + w: 60, + h: 60, + x: t, + y: n, + z: 0, + html: (l = ["🌳", "🌴", "🌲", "🐄"][(3.1 * Math.random()) | 0]), + css: "tree fixed", + o: "bottom", + }), + mobile || + C.plane({ + w: 60, + h: 60, + x: t, + y: n, + z: 0, + html: l, + css: "tree fixed shadow", + o: "bottom", + rz: 100, + }), + C.sprite({ + w: 60, + h: 60, + x: X2, + y: Y2, + z: 0, + html: (l = ["🌳", "🌴", "🌲", "🐄"][(3.1 * Math.random()) | 0]), + css: "tree fixed", + o: "bottom", + }), + mobile || + C.plane({ + w: 60, + h: 60, + x: X2, + y: Y2, + z: 0, + html: l, + css: "tree fixed shadow", + o: "bottom", + rz: 100, + }), + C.sprite({ + w: 60, + h: 60, + x: X3, + y: Y3, + z: 0, + html: (l = ["🌳", "🌴", "🌲", "🐄"][(3.1 * Math.random()) | 0]), + css: "tree fixed", + o: "bottom", + }), + mobile || + C.plane({ + w: 60, + h: 60, + x: X3, + y: Y3, + z: 0, + html: l, + css: "tree fixed shadow", + o: "bottom", + rz: 100, + }), + t = 0, + n = 0, + X2 = 0, + Y2 = 0, + X3 = 0, + Y3 = 0; + (Math.abs(X2 - t) < 120 && Math.abs(Y2 - n) < 100) || + (Math.abs(X3 - t) < 100 && Math.abs(Y3 - n) < 100) || + (Math.abs(X3 - X2) < 100 && Math.abs(Y3 - Y2) < 100); + + ) + (t = 470 + 300 * Math.random()), + (X2 = 470 + 300 * Math.random()), + (X3 = 470 + 300 * Math.random()), + (n = -120 - 300 * Math.random()), + (Y2 = -120 - 300 * Math.random()), + (Y3 = -120 - 300 * Math.random()); + C.sprite({ + w: 60, + h: 60, + x: t, + y: n, + z: 0, + html: (l = ["🌳", "🌴", "🌲", "🦙"][(3.1 * Math.random()) | 0]), + css: "tree fixed", + o: "bottom", + }), + mobile || + C.plane({ + w: 60, + h: 60, + x: t, + y: n, + z: 0, + html: l, + css: "tree fixed shadow", + o: "bottom", + rz: 100, + }), + C.sprite({ + w: 60, + h: 60, + x: X2, + y: Y2, + z: 0, + html: (l = ["🌳", "🌴", "🌲", "🦙"][(3.1 * Math.random()) | 0]), + css: "tree fixed", + o: "bottom", + }), + mobile || + C.plane({ + w: 60, + h: 60, + x: X2, + y: Y2, + z: 0, + html: l, + css: "tree fixed shadow", + o: "bottom", + rz: 100, + }), + C.sprite({ + w: 60, + h: 60, + x: X3, + y: Y3, + z: 0, + html: (l = ["🌳", "🌴", "🌲", "🦙"][(3.1 * Math.random()) | 0]), + css: "tree fixed", + o: "bottom", + }), + mobile || + C.plane({ + w: 60, + h: 60, + x: X3, + y: Y3, + z: 0, + html: l, + css: "tree fixed shadow", + o: "bottom", + rz: 100, + }), + (t = 470 + 300 * Math.random()), + (n = 120 + 300 * Math.random()), + C.sprite({ + w: 60, + h: 60, + x: t, + y: n, + z: 0, + html: (l = ["🌳", "🌴", "🌲", "🐐"][(3.1 * Math.random()) | 0]), + css: "tree fixed", + o: "bottom", + }), + mobile || + C.plane({ + w: 60, + h: 60, + x: t, + y: n, + z: 0, + html: l, + css: "tree fixed shadow", + o: "bottom", + rz: 100, + }), + (t = -470 - 300 * Math.random()), + (n = 120 + 300 * Math.random()), + C.sprite({ + w: 60, + h: 60, + x: t, + y: n, + z: 0, + html: (l = ["🌳", "🌴", "🌲", "🐐"][(3.1 * Math.random()) | 0]), + css: "tree fixed", + o: "bottom", + }), + mobile || + C.plane({ + w: 60, + h: 60, + x: t, + y: n, + z: 0, + html: l, + css: "tree fixed shadow", + o: "bottom", + rz: 100, + }); + }), + (levels = () => { + if ( + (1 == S + ? (draw_boat(-100, -450, -235), + (track = [ + [-300, 0, 0, 1], + [-200, 0, 0, 1], + [-100, 0, 0, 1], + [0, 0, 0, 1], + [100, 0, 0, 1], + [200, 0, 0, 1], + [300, 0, 0, 1], + [400, 0, 0, 0], + ]), + (links = { + default: [ + [, 1], + [0, 2], + [1, 3], + [2, 4], + [3, 5], + [4, 6], + [5, 7], + [6], + ], + })) + : 2 == S + ? (draw_boat(200, 60, -235), + 1 == 1 || + 1 == 1 || + 1 == 1 + ? (track = [ + [-300, 0, 0, 1], + [-200, 0, 0, 1], + [-100, 100, 0, 1], + [0, 0, 0, 1], + [100, 0, 0, 1], + [202, -200, 0, 1], + [300, 0, 0, 1], + [400, 0, 0, 0], + ]) + : (track = []), + (links = { + "2d": { + front: [ + [, 1], + [0, 2], + [1, 3], + [2, 4], + [3, 5], + [4, 6], + [5, 7], + [6], + ], + }, + default: [[, 1], [0], [,], [, 4], [3], [,], [, 7], [6]], + })) + : 3 == S + ? (draw_boat(200, 100), + (track = [ + [-300, 0, 0, 1], + [-284, -165, -165, 1, 1.4], + [-100, 0, 0, 1], + [0, -400, 0, 1], + [100, 0, 0, 1], + [120, 155, 155, 1, 0.6], + [300, 0, 0, 1], + [400, 0, 0], + ]), + (links = { + "2d": { front: [[,], [,], [, 3], [2, 4], [3], [,], [, 7], [6]] }, + "3d": { + midup: [ + [, 1], + [0, 2, -200, 0, 0, 1], + [1], + [,], + [, 5, 60, 155, 155, 0.6], + [4, 6, 120, 155, 155, 0.6], + [5, 7, 180, 155, 155, 0.6], + [6, , 240, 155, 155, 0.6], + ], + }, + })) + : 4 == S + ? (draw_boat(-200, -400, -235), + (track = [ + [-300, 0, 0, 1], + [-200, 0, 0, 1], + [-73, 13, 150, 1, 0.73], + [0, 0, 0, 1], + [100, 0, 0, 1], + [200, -200, 0, 1], + [300, 0, 0, 1], + [400, 0, 0, 0], + ]), + (links = { + default: [[, 1], [0], [,], [, 4], [3], [,], [, 7], [6]], + "3d": { + up: [ + [, 1, -219, 13, 150, 0.72], + [0, 2, -146, 13, 150, 0.72], + [1, 3], + [2, 4, 0, 13, 150, 0.72], + [3, , 73, 13, 150, 0.72], + [,], + [, 7], + [6], + ], + }, + "2d": { + middle: [ + [, 1], + [0], + [, 3], + [2, 4], + [3, 5], + [4, 6, 200, 0, 0], + [5, 7], + [6], + ], + }, + })) + : 5 == S && + (draw_boat(250, -400, -235), + (track = [ + [-298, 0, 0, 1.05], + [-202, -300, 0, 1.05], + [-100, -300, 0, 0], + [0, -300, 0, 0], + [100, -300, 0, 1], + [133, -70, -130, 1, 0.65], + [117, -151, 157, 0, 1.12], + [506, -54, 0, 0, 1.47], + [217, 118, 151, 1, 0.9], + ]), + (links = { + default: [[,], [, 2], [1, 3], [2, 4], [3], [,], [,], [,], [,]], + "2d": { + middle: [ + [, 1], + [0, 2], + [1, 3], + [2, 4], + [3], + [,], + [, 8], + [,], + [6], + ], + midup: [ + [,], + [, 2], + [1, 3], + [2, 4], + [3], + [,], + [,], + [9, , 397, 118, 151, 0.9], + [,], + ], + }, + "3d": { + middown: [ + [,], + [, 2], + [1, 3], + [2, 4], + [3, 5], + [4, , 200, -300, 0, 1], + [, 8], + [,], + [,], + ], + down: [ + [,], + [, 2], + [1, 3], + [2, 4], + [3], + [6, , 227, -151, 157, 1.12], + [, 5], + [,], + [,], + ], + midup: [ + [,], + [, 2], + [1, 3], + [2, 4], + [3], + [,], + [,], + [8, , 307, 118, 151, 0.9], + [, 7], + ], + }, + })), + 6 == S) + ) + draw_boat(-100, -450, -235), + (track = [ + [-300, 0, 0, 1], + [-273, 140, 198, 1, 0.68], + [-100, 0, 0, 1], + [173, 172, -22, 1, 1.45], + [100, 0, 0, 1], + [22, 186, 264, 1], + [300, 0, 0, 1], + [400, 0, 0, 0], + ]), + (links = { + default: [[,], [,], [,], [,], [,], [,], [, 7], [6]], + "3d": { + leftfrontmidup: [ + [, 1, -341, 140, 198, 0.68], + [0, 2], + [1, , -205, 140, 198, 0.68], + [,], + [,], + [,], + [, 7], + [6], + ], + leftbackmiddle: [ + [,], + [,], + [, 3], + [2, 4, 0, 0, 0, 1], + [3], + [,], + [, 7], + [6], + ], + }, + "2d": { + rightbackmiddown: [ + [,], + [,], + [,], + [,], + [, 5, -78, 186, 264], + [4, 6], + [5, 7, 122, 186, 264], + [6, , 222, 186, 264], + ], + }, + }); + else if (7 == S) + draw_boat(200, 60, -235), + (cp = "leftfront"), + draw_track(0, 0, 0, 1), + setTimeout(() => { + C.camera({ rz: (camrz = -45) }), camera(); + }, 200), + (track = [ + [-300, 0, 0, 1], + [0, 375, 532, 1, 1.9], + [-100, 0, 0, 1], + [100, 0, 0, 1], + [300, 0, 0, 1], + [400, 0, 0, 0], + ]), + (links = { + "3d": { + leftbackmiddown: [ + [, 1, -190, 375, 532, 1.9], + [0, 2], + [1, , 190, 375, 532, 1.9], + [,], + [, 5], + [4], + ], + rightbackmiddown: [ + [,], + [3, 4], + [,], + [, 1, -190, 375, 532, 1.9], + [1, 5, 190, 375, 532, 1.9], + [4, , 380, 375, 532, 1.9], + ], + }, + default: [[,], [,], [,], [,], [, 5], [4]], + }); + else if (9 == S) + draw_boat(100, -100, -235), + (track = [ + [-300, 0, 0, 0], + [-200, 0, 0, 1], + [111, 0, -252, 0, 1.4], + [-0, 0, 0, 0], + [-392, 0, 422, 0, 0.3], + [200, 0, 0, 1], + [-290, 468, 225, 1, 0.65], + [402, 123, 0, 0, 0.5], + [-256, -468, 261, 1, 0.7], + [-160, 468, 225, 0, 0.65], + [-116, -468, 261, 0, 0.7], + [-33, 468, 225, 0, 0.65], + [24, -468, 261, 0, 0.7], + [90, 468, 225, 0, 0.65], + [164, -468, 261, 1, 0.7], + [243, -34, 153, 1, 0.32], + [123, 115, 439, 0, 0.5], + [73, 115, 439, 0, 0.5], + [24, 120, 210, 0, 0.52], + [76, 120, 210, 1, 0.52], + [129, 120, 210, 0, 0.52], + ]), + (links = { + "2d": { + frontmiddle: [ + [, 1], + [0], + [,], + [,], + [,], + [,], + [, 8], + [,], + [6, 9, -225, 468, 225, 0.65], + [8, 10], + [9, 11, -96, 468, 225, 0.65], + [10, 12], + [11, 13, 29, 468, 225, 0.65], + [12, 14], + [13, , 153, 468, 225, 0.65], + [,], + [17], + [, 16], + [, 19], + [18, 20], + [19], + ], + up: [ + [, 1], + [0], + [,], + [,], + [,], + [,], + [,], + [,], + [,], + [,], + [,], + [,], + [,], + [,], + [,], + [,], + [17], + [18, 16], + [, 17, 23, 115, 439, 0.5], + [18, 20], + [19], + ], + leftmidup: [ + [, 1], + [0], + [,], + [,], + [,], + [,], + [,], + [20, , 181, 120, 210, 0.52], + [,], + [,], + [,], + [,], + [,], + [,], + [,], + [,], + [17], + [, 16], + [, 19], + [18, 20], + [19, 7], + ], + }, + "3d": { + leftmidup: [ + [, 1, -512, 0, 422, 0.3], + [0, 2, -482, 0, 422, 0.3], + [1, 3, -452, 0, 422, 0.3], + [2, 4, -422, 0, 422, 0.3], + [3, 5], + [4, , -362, 0, 422, 0.3], + [,], + [,], + [,], + [,], + [,], + [,], + [,], + [,], + [,], + [,], + [17], + [, 16], + [, 19], + [18, 20], + [19], + ], + leftbackmidup: [ + [, 1], + [0], + [,], + [,], + [, 6], + [,], + [4, , -362, 0, 422, 0.3], + [,], + [,], + [,], + [,], + [,], + [,], + [,], + [,], + [,], + [17], + [, 16], + [, 19], + [18, 20], + [19], + ], + rightfrontmiddle: [ + [, 1], + [0], + [,], + [,], + [,], + [,], + [,], + [,], + [,], + [,], + [,], + [,], + [, 15], + [,], + [15], + [12, 14, 94, -468, 261, 0.7], + [17], + [, 16], + [, 19], + [18, 20], + [19], + ], + rightbackmiddown: [ + [, 1], + [0], + [,], + [,], + [,], + [,], + [,], + [,], + [,], + [,], + [,], + [,], + [,], + [,], + [,], + [16, , 173, 115, 439, 0.5], + [17, 15], + [, 16], + [, 19], + [18, 20], + [19], + ], + }, + default: [ + [, 1], + [0], + [,], + [,], + [,], + [,], + [,], + [,], + [,], + [,], + [,], + [,], + [,], + [,], + [,], + [,], + [17], + [, 16], + [, 19], + [18, 20], + [19], + ], + }); + else if (8 == S) + draw_boat(-230, 80, -235), + (track = [ + [-300, 0, 0, 0], + [-200, 0, 0, 1], + [0, 0, -1e4, 0, 1.4], + [200, 0, 0, 1], + [300, 0, 0, 0], + [400, 0, 0, 0], + ]), + draw_track(-100, 0, 0, 0), + draw_dynamite(-100, 0, 0, 1), + draw_track(0, 0, 0, 0), + draw_dynamite(0, 0, 0, 2), + draw_track(100, 0, 0, 0), + draw_dynamite(100, 0, 0, 3), + (group0.style.transition = + group1.style.transition = + group2.style.transition = + "transform 1s"), + setTimeout(() => { + (d_1.innerHTML = ""), + navigator.vibrate && navigator.vibrate(2500), + viewport.classList.add("rumble2"), + boom(), + (group6.style.transition = "opacty 1s"), + (group6.style.opacity = "0"); + }, 4500), + setTimeout(() => { + viewport.classList.remove("rumble2"); + }, 4900), + setTimeout(() => { + (d_2.innerHTML = ""), + (d_1.innerHTML = ""), + C.move({ n: "group0", z: -350 }), + viewport.classList.add("rumble2"), + boom(); + }, 5e3), + setTimeout(() => { + viewport.classList.remove("rumble2"); + }, 5400), + setTimeout(() => { + (d_3.innerHTML = ""), + (d_2.innerHTML = ""), + C.move({ n: "group1", z: -350 }), + viewport.classList.add("rumble2"), + boom(), + (go = 1); + }, 5500), + setTimeout(() => { + (d_3.innerHTML = ""), + C.move({ n: "group2", z: -350 }), + navigator.vibrate && navigator.vibrate(0), + viewport.classList.remove("rumble2"); + }, 6e3), + setTimeout(() => { + (level.innerHTML = "OK, sending you some help, catch it!"), + (level.style.transform = "translateY(18px)rotate(2deg)"), + (group0.style.display = + group1.style.display = + group2.style.display = + "none"), + C.move({ n: "group6", y: -600, z: -235 }), + (group6.style.opacity = 1), + (group6go = 1), + (track[2][2] = -235); + }, 8e3), + (links = { + default: [[, 1], [0], [,], [, 4], [3, 5], [4]], + "3d": { + leftfrontmidup: [[, 1], [0], [,], [, 4], [3, 5], [4]], + rightbackmidup: [[, 1], [0], [,], [, 4], [3, 5], [4]], + }, + }); + else if (10 == S) { + draw_boat(0, 150, -235), (track = [[-300, 0, 0, 1]]); + for (var l = 0; l < 6; l++) + track.push([ + 700 * Math.random() - 350, + 700 * Math.random() - 600, + 460 * Math.random() - 230, + 1 | Math.random(), + 1.5 * Math.random() + 0.2, + ]); + track.push([400, 0, 0, 0]); + for (l = 0; l < 10; l++) + track.push([ + 700 * Math.random() - 350, + 700 * Math.random() - 600, + 460 * Math.random() - 230, + 1 | Math.random(), + 1.5 * Math.random() + 0.2, + ]); + links = {}; + } + 11 == S && + ((track = [ + [-300, 0, 0, 1], + [-200, -300, 0, 1], + [-100, -300, 0, 0], + [0, -300, 0, 0], + [100, -300, 0, 1], + [-78, 23, 268, 1, 0.56], + [-242, 243, 104, 1, 0.77], + [390, -60, 0, 0, 1.2], + [-165, 243, 104, 0, 0.77], + [-88, 243, 104, 1, 0.77], + [147, 74, 327, 1, 0.7], + [82, 78, -200, 1, 0.75], + [7, 78, -200, 0, 0.75], + [-68, 78, -200, 1, 0.75], + [582, 204, 440, 0, 2], + [-218, 78, -200, 1, 0.75], + [782, 204, 440, 0, 2], + [-34, -1, -250, 0, 1.4], + [-8, -400, 115, 1, 0.8], + ]), + (links = { + default: [ + [,], + [, 2], + [1, 3], + [2, 4], + [3], + [,], + [, 8], + [,], + [6, 9], + [8], + [,], + [12], + [13, 11], + [, 12], + [, 16], + [,], + [14], + [,], + [,], + ], + "2d": { + frontmiddle: [ + [, 1], + [0, 2, -200, 0, 0], + [1, 3, -100, 0, 0], + [2, 4, 0, 0, 0], + [3, , 100, 0, 0], + [,], + [, 8], + [,], + [6, 9], + [8, 18], + [,], + [12], + [13, 11], + [, 12], + [, 16], + [,], + [14], + [,], + [9, , -11, 243, 104, 0.77], + ], + backmiddle: [ + [, 1], + [0, 2, -200, 0, 0], + [1, 3, -100, 0, 0], + [2, 4, 0, 0, 0], + [3, , 100, 0, 0], + [,], + [, 8], + [,], + [6, 9], + [8], + [,], + [12], + [13, 11], + [, 12], + [, 16], + [,], + [14], + [,], + [,], + ], + frontup: [ + [,], + [, 2], + [1, 3], + [2, 4], + [3], + [,], + [, 8], + [,], + [6, 9], + [8], + [,], + [12], + [13, 11], + [, 12], + [, 16], + [,], + [14], + [,], + [,], + ], + backup: [ + [,], + [, 2], + [1, 3], + [2, 4], + [3], + [,], + [, 8], + [,], + [6, 9], + [8], + [,], + [12], + [13, 11], + [, 12], + [, 16], + [,], + [14], + [,], + [,], + ], + up: [ + [,], + [, 2], + [1, 3], + [2, 4], + [3], + [,], + [, 8], + [,], + [6, 9], + [8], + [11], + [12, 10, 77, 74, 327, 0.7], + [13, 11, 7, 74, 327, 0.7], + [, 12, -63, 74, 327, 0.7], + [, 16], + [,], + [14], + [,], + [,], + ], + rightbackmidup: [ + [,], + [, 2], + [1, 3], + [2, 4], + [3], + [,], + [, 8, -63, 74, 327, 0.7], + [,], + [6, 9, 7, 74, 327, 0.7], + [8, 10, 77, 74, 327, 0.7], + [9], + [12], + [13, 11], + [, 12], + [, 16], + [,], + [14], + [,], + [,], + ], + }, + "3d": { + leftmidup: [ + [, 17], + [, 2], + [1, 3], + [2, 4], + [3], + [,], + [, 8], + [,], + [6, 9], + [8], + [,], + [12], + [13, 11], + [, 12], + [, 16], + [,], + [14], + [0, , -200, 0, 0], + [,], + ], + leftfrontmidup: [ + [,], + [, 2, -302, 23, 268, 0.56], + [1, 3, -246, 23, 268, 0.56], + [2, 4, -190, 23, 268, 0.56], + [3, 5, -134, 23, 268, 0.56], + [4], + [, 8], + [,], + [6, 9], + [8], + [,], + [12], + [13, 11], + [, 12], + [, 16], + [,], + [14], + [,], + [,], + ], + rightbackmidup: [ + [,], + [, 2], + [1, 3], + [2, 4], + [3], + [, 6], + [5, 8, -22, 23, 268, 0.56], + [,], + [6, 9, 34, 23, 268, 0.56], + [8, , 90, 23, 268, 0.56], + [,], + [12], + [13, 11], + [, 12], + [, 16], + [,], + [14], + [,], + [,], + ], + leftbackmiddown: [ + [,], + [, 2], + [1, 3], + [2, 4], + [3], + [,], + [, 8], + [16, , 982, 204, 440, 2], + [6, 9], + [8], + [,], + [12], + [13, 11], + [, 12], + [, 16], + [,], + [14, 7], + [,], + [,], + ], + leftmiddown: [ + [,], + [, 2], + [1, 3], + [2, 4], + [3], + [,], + [, 8], + [,], + [6, 9], + [8], + [,], + [12, , 1182, 204, 440, 2], + [13, 11, 982, 204, 440, 2], + [14, 12, 782, 204, 440, 2], + [15, 13], + [, 14, 382, 204, 440, 2], + [14], + [,], + [,], + ], + }, + })), + S >= 1 && + (links["2d"] && + links["2d"].up && + !links["2d"].down && + (links["2d"].down = links["2d"].up), + draw_tracks()); + }), + (init = (t) => { + if ( + ((scene.innerHTML = ""), + (dp = "500px"), + (C.sc = 0), + (C.sprites = []), + (C.pc = 0), + (C.cc = 0), + (go = 0), + (chunk = 0), + (prev_chunk = 0), + (hud.style.opacity = 0), + (win = 0), + (lose = 0), + (X = 0), + (Y = 0), + (Z = 0), + (vX = 0), + (scale = 1), + (black.style.opacity = 0), + (black.style.pointerEvents = "none"), + (viewport.style.perspective = dp), + (cam = "3d"), + (cp = "front"), + (ch = "midup"), + C.camera({ rz: 0, rx: 45 }), + (hud.style.transition = "1s"), + (camrz = 0), + (gc = 0), + (cm = 300), + (cl = -350), + (cr = -250), + (posonchunk = 0), + (scale = 1), + (dir = 1), + S && window.h4 && (h4.style.display = "none"), + viewport.classList.remove("rumble"), + 0 == S + ? viewport.classList.add("title") + : viewport.classList.remove("title"), + (k[67] = 0), + (k[88] = 0), + (oktolose = 1), + (group6go = 0), + (group6y = -600), + (cross1 = 0), + (cross2 = 0), + (wavesy = 0), + (frames9 = 0), + window.train && (train.style.transition = "none"), + (level.style.transform = "translateY(0)rotate(0)"), + (mobile = + navigator.userAgent.includes("Android") || + navigator.userAgent.includes("iOS")), + (scene.style.marginTop = S ? 0 : "20px"), + mobile && ((all.className = "mobile"), (fullscreen = 1), onresize()), + (easteregg7 = 0), + setTimeout(() => { + viewport.style.transition = "perspective 1.5s"; + }, 1e3), + S && + (level.innerHTML = + S + + ". " + + ([ + , + "Move the train with " + + (mobile + ? "the buttons below" + : "the keys X and C, or use the buttons below"), + 1 == 1 || + 1 == 1 || + 1 == 1 + ? "Change perspective with " + + (mobile + ? "the buttons below" + : "E and R, or use the buttons below") + : "Stolen content! Go play this game on js13kgames.com/entries/track-not-found", + "Optical illusions can help completing the track", + "Move the camera up & down with " + + (mobile + ? "the buttons below" + : "the arrow keys, or use the buttons below"), + "Success is not always a straight line", + "Rotate the camera to the left or the right with " + + (mobile ? "the buttons below" : "the other arrow keys"), + "This one looks easy...", + "What the...?!", + "I had to make one big level, so here it is.", + "To solve this one, go in the 4th dimension " + + (mobile + ? "with the button below!" + : "by pressing T or the button below!"), + "Here's the bonus level :3", + ][S] || "")), + (buttons.innerHTML = ""), + S >= 1 && + (self.h1 && (h1.remove(), h2.remove(), h3.remove()), + (buttons.innerHTML += + " ")), + S >= 2 && + (buttons.innerHTML += + " "), + 10 == S && + (buttons.innerHTML += + ""), + S >= 4 && + S < 6 && + (buttons.innerHTML += + "


"), + S >= 6 && + (buttons.innerHTML += + "


"), + S >= 1 && + ((b_back.onmousedown = b_back.ontouchstart = + (l) => { + k[88] = 1; + }), + (b_back.onmouseup = b_back.ontouchend = + (l) => { + k[88] = 0; + }), + (b_front.onmousedown = b_front.ontouchstart = + (l) => { + k[67] = 1; + }), + (b_front.onmouseup = b_front.ontouchend = + (l) => { + k[67] = 0; + })), + S >= 2 && + ((b_2d.onmousedown = b_2d.ontouchstart = + (l) => { + k[69] || k[82] || "2d" == cam || !go || (k[69] = 1); + }), + (b_3d.onmousedown = b_3d.ontouchstart = + (l) => { + k[69] || k[82] || "3d" == cam || !go || (k[82] = 1); + })), + 10 == S && + (b_4d.onmousedown = b_4d.ontouchstart = + (l) => { + !k[84] && "4d" != cam && go && (k[84] = 1); + }), + S >= 4 && + ((b_up.onmousedown = b_up.ontouchstart = + (l) => { + go && !u && (u = 1); + }), + (b_down.onmousedown = b_down.ontouchstart = + (l) => { + go && !d && (d = 1); + })), + S >= 6 && + ((b_left.onmousedown = b_left.ontouchstart = + (t) => { + go && !l && (l = 1); + }), + (b_right.onmousedown = b_right.ontouchstart = + (l) => { + go && !r && (r = 1); + })), + 0 == S) + ) { + (h3.style.display = "block"), + (rz = 90), + C.camera({ + z: -250, + rz: (rz += 0.5), + rx: 50 + 10 * Math.cos(rz / 27.5), + }), + C.plane({ + w: 600, + h: 500, + z: -10, + b: "radial-gradient(#aea, #6b6 50%)", + }), + draw_train(0, 0, 1); + for (var n = -800; n < 900; n += 100) draw_track(n, 11, 0); + C.sprite({ + w: 60, + h: 60, + x: 0, + y: -100, + z: 0, + html: "🌳", + css: "tree tree1", + o: "bottom", + }), + C.plane({ + w: 60, + h: 60, + x: 0, + y: -100, + z: 0, + html: "🌳", + css: "tree shadow tree1 shadow1", + o: "bottom", + rz: -25, + }), + C.sprite({ + w: 60, + h: 60, + x: 0, + y: -100, + z: 0, + html: "🌴", + css: "tree tree2", + o: "bottom", + }), + C.plane({ + w: 60, + h: 60, + x: 0, + y: -100, + z: 0, + html: "🌴", + css: "tree shadow tree2 shadow2", + o: "bottom", + rz: -25, + }), + C.sprite({ + w: 60, + h: 60, + x: 0, + y: 120, + z: 0, + html: "🌳", + css: "tree tree3", + o: "bottom", + }), + C.plane({ + w: 60, + h: 60, + x: 0, + y: 120, + z: 0, + html: "🌳", + css: "tree shadow tree3 shadow3", + o: "bottom", + rz: -25, + }), + C.sprite({ + w: 60, + h: 60, + x: 0, + y: -80, + z: 0, + html: "🌲", + css: "tree tree4", + o: "bottom", + }), + C.plane({ + w: 60, + h: 60, + x: 0, + y: -80, + z: 0, + html: "🌲", + css: "tree shadow tree4 shadow4", + o: "bottom", + rz: -25, + }), + C.sprite({ + w: 60, + h: 60, + x: 0, + y: 150, + z: 0, + html: "🌲", + css: "tree tree5", + o: "bottom", + }), + C.plane({ + w: 60, + h: 60, + x: 0, + y: 150, + z: 0, + html: "🌲", + css: "tree shadow tree5 shadow5", + o: "bottom", + rz: -25, + }), + C.sprite({ + w: 60, + h: 60, + x: 0, + y: -140, + z: 0, + html: "🌳", + css: "tree tree6", + o: "bottom", + }), + C.plane({ + w: 60, + h: 60, + x: 0, + y: -140, + z: 0, + html: "🌳", + css: "tree shadow tree6 shadow6", + o: "bottom", + rz: -25, + }), + C.sprite({ + w: 60, + h: 60, + x: 0, + y: 80, + z: 0, + html: "🌲", + css: "tree tree7", + o: "bottom", + }), + C.plane({ + w: 60, + h: 60, + x: 0, + y: 80, + z: 0, + html: "🌲", + css: "tree shadow tree7 shadow7", + o: "bottom", + rz: -25, + }); + } + S >= 1 && + ((X = -350), + (vX = 0), + C.camera({ x: -400, y: 0, z: -300, rx: 30, rz: 0 }), + draw_hills(), + draw_train(X, 0, 0), + C.move({ n: "train", x: -700, y: -11 }), + setTimeout(() => { + (scene.style.transition = "4s"), (train.style.transition = "2s"); + }, 16), + setTimeout(() => { + C.camera({ x: 0, y: 0, z: 50, rx: 45, ry: 0, rz: 0 }), + C.move({ n: "train", x: -350 }); + }, 33), + setTimeout(() => { + hud.style.opacity = 1; + }, 2e3), + setTimeout(() => { + (train.style.transition = "none"), + (scene.style.transition = "1s"), + 8 != S && (go = 1); + }, 3e3), + (viewport.className = "blue")), + levels(), + onresize(), + S > 11 && (location = location), + setTimeout(() => { + S > 0 && window.boat && (boat.style.transition = ".5s"); + }, 1e3); + }), + (animate = () => { + setInterval(() => { + 0 == S && + C.camera({ + z: -300, + rz: (rz += 0.5), + rx: 50 + 10 * Math.cos(rz / 27.5), + }), + S >= 1 && + (vX && (vX *= 0.95), + go && k[67] && vX < (scale < 1 ? 7 * scale : 7) + ? ((vX += scale < 1 ? 0.2 * scale : 0.2), (dir = 1)) + : go && + k[88] && + vX < (scale < 1 ? 5 * scale : 5) && + ((vX -= scale < 1 ? 0.2 * scale : 0.2), (dir = 0)), + !go || + win || + lose || + ((X += vX), + X < -400 && 0 == Y && 1 == scale && ((X = -400), (vX = 0)), + C.move({ n: "train", x: X, y: Y - 10 * scale, z: Z })), + (7 == chunk || (track.length < 8 && chunk == track.length - 1)) && + posonchunk > 0.75 && + ((X = 0), + (win = 1), + 7 != S || + easteregg7 || + (localStorage["OS13kTrophy,🚂,Track Not Found,Bridge saver"] = + "You didn't destroy the bridge in Track not Found"), + (train.style.transition = hud.style.transition = "1s"), + (viewport.style.transition = "none"), + C.move({ n: "train", x: 800 }), + (hud.style.opacity = 0), + (go = 0), + setTimeout(() => { + black.style.opacity = 1; + }, 800), + setTimeout(() => { + (scene.style.transition = "none"), + (viewport.style.perspective = dp), + S++, + init(); + }, 1500)), + (link = getlink()), + link && + ((cm = link[chunk].length > 2 ? link[chunk][2] : track[chunk][0]), + (scale = + (link[chunk].length > 2 ? link[chunk][5] : track[chunk][4]) || + 1), + (cl = cm - 50 * scale), + (cr = cm + 50 * scale), + Math.abs(vX) > 0.1 && (posonchunk = (X - cl) / (cr - cl)), + 7 == S && + 1 == chunk && + posonchunk > 0.5 && + !easteregg7 && + cp + ch == "leftbackmiddown" && + ((easteregg7 = 1), + (group0.style.transition = "3s"), + viewport.classList.add("rumble"), + (level.innerHTML = + "Ooops, sorry, you'll need to find another way!"), + (level.style.transform = "translateY(27px)rotate(3deg)"), + navigator.vibrate && navigator.vibrate(500), + C.move({ n: "group0", rx: 90, y: -600, z: -600 }), + (oktolose = 0), + setTimeout(() => { + group0.remove(), + navigator.vibrate && navigator.vibrate(0), + (oktolose = 1), + viewport.classList.remove("rumble"); + }, 3e3)), + 8 == S && + group6go && + (C.move({ n: "group6", y: (group6y += 0.9) }), + group6y > 600 && (2 == chunk ? (lose = 1) : (group6y = -600))), + posonchunk > 1 && + (undefined !== link[chunk][1] + ? ((posonchunk -= 1), + posonchunk < 0 && (posonchunk = 0), + (chunk = link[chunk][1])) + : (lose = 1)), + 3 == S && 1 == chunk && "2d" == cam && X < -318 + ? ((vX = 0), + (X = -318), + (posonchunk = 0.25), + (localStorage["OS13kTrophy,🚂,Track Not Found,Bonk"] = + "You bonked on the mountain in Track not Found")) + : posonchunk < 0 && + 0 != chunk && + (undefined !== link[chunk][0] + ? ((posonchunk += 1), + posonchunk < 1 && (posonchunk = 1), + (chunk = link[chunk][0])) + : (lose = 1)), + lose && + go && + (ww(), + (train.style.transition = ".5s"), + (scene.style.transition = "1s"), + (hud.style.transition = "none"), + (hud.style.opacity = "0"), + (go = 0), + 0 == dir + ? C.move({ n: "train", x: (X -= 30), z: (Z -= 30), ry: -90 }) + : C.move({ n: "train", x: (X += 30), z: (Z -= 30), ry: 90 }), + (black.style.opacity = 1), + setTimeout(() => { + C.move({ n: "train", z: (Z -= 70) }); + }, 200), + setTimeout( + () => { + (scene.style.transition = "none"), init(); + }, + oktolose ? 1e3 : 3e3 + )))), + S >= 2 && + (k[69] && + "2d" != cam && + go && + !win && + !lose && + ((b_2d.className = "on"), + (b_3d.className = ""), + (vX = 0), + (cam = "2d"), + S < 8 && + 6 != S && + ("midup" == ch || "middown" == ch) && + (ch = "middle"), + traintoreal(), + camera(), + setTimeout(ttn, 1500), + (k[69] = 0)), + k[82] && + "3d" != cam && + go && + !win && + !lose && + ((b_3d.className = "on"), + (b_2d.className = ""), + (vX = 0), + (cam = "3d"), + S < 8 && (ch = "midup"), + traintoreal(), + camera(), + setTimeout(ttn, 1500), + (k[82] = 0)), + 10 == S && + k[84] && + "4d" != cam && + go && + !win && + !lose && + ((b_4d.className = "on"), + (b_2d.className = ""), + (b_3d.className = ""), + (vX = 0), + (cam = "4d"), + (black.style.pointerEvents = "all"), + camera(), + (k[84] = 0))), + S >= 4 && + (go && + u && + !win && + !lose && + "up" != ch && + ((vX = 0), + "midup" == ch + ? (ch = "up") + : "middle" == ch + ? (ch = "midup") + : "middown" == ch + ? (ch = "middle") + : "down" == ch && (ch = "middown"), + traintoreal(), + camera(), + setTimeout(ttn, 8 == S ? 300 : 1e3), + (u = 0)), + go && + d && + !win && + !lose && + "down" != ch && + ((vX = 0), + "up" == ch + ? (ch = "midup") + : "midup" == ch + ? (ch = "middle") + : "middle" == ch + ? (ch = "middown") + : "middown" == ch && (ch = "down"), + traintoreal(), + camera(), + setTimeout(ttn, 8 == S ? 300 : 1e3), + (d = 0))), + S >= 6 && + (go && + l && + !win && + !lose && + ((vX = 0), + "right" == cp + ? (cp = "rightfront") + : "rightfront" == cp + ? (cp = "front") + : "front" == cp + ? (cp = "leftfront") + : "leftfront" == cp + ? (cp = "left") + : "left" == cp + ? (cp = "leftback") + : "leftback" == cp + ? (cp = "back") + : "back" == cp + ? (cp = "rightback") + : "rightback" == cp && (cp = "right"), + C.camera({ rz: (camrz -= 45) }), + traintoreal(), + camera(), + setTimeout(ttn, 8 == S ? 300 : 1e3), + (l = 0)), + go && + r && + !win && + !lose && + ((vX = 0), + "right" == cp + ? (cp = "rightback") + : "rightback" == cp + ? (cp = "back") + : "back" == cp + ? (cp = "leftback") + : "leftback" == cp + ? (cp = "left") + : "left" == cp + ? (cp = "leftfront") + : "leftfront" == cp + ? (cp = "front") + : "front" == cp + ? (cp = "rightfront") + : "rightfront" == cp && (cp = "right"), + C.camera({ rz: (camrz += 45) }), + traintoreal(), + camera(), + setTimeout(ttn, 8 == S ? 300 : 1e3), + (r = 0))), + 8 == S && group6y < -150 && group6y > -200 && !cross1 + ? (links["3d"].leftfrontmidup = [ + [, 1], + [0, 2], + [1], + [, 4], + [3, 5], + [4], + ]) + : 8 == S && + (links["3d"].leftfrontmidup = [ + [, 1], + [0], + [,], + [, 4], + [3, 5], + [4], + ]), + 8 == S && group6y > 150 && group6y < 200 + ? ((links["3d"].rightbackmidup = [ + [, 1], + [0], + [, 3], + [2, 4], + [3, 5], + [4], + ]), + (links["3d"].leftbackmidup = [ + [, 1], + [0, 2], + [1], + [, 4], + [3, 5], + [4], + ])) + : 8 == S && + ((links["3d"].rightbackmidup = [ + [, 1], + [0], + [,], + [, 4], + [3, 5], + [4], + ]), + (links["3d"].leftbackmidup = [ + [, 1], + [0], + [,], + [, 4], + [3, 5], + [4], + ])), + 8 != S || + cross1 || + 2 != chunk || + ((Z = -235), + (scale = 1.4), + (X = -35), + (vX = 0), + (chunkscale = 1.4), + (cm = 0), + (cl = -70), + (cr = 70), + (posonchunk = 0.25), + (cross1 = 1), + (train.style.transition = "transform .1s"), + (go = 0), + setTimeout(() => { + C.move({ + n: "train", + x: X, + y: group6y - 11, + z: Z, + sx: 1.4, + sy: 1.4, + sz: 1.4, + }); + }, 33), + setTimeout(() => { + (go = 1), lose || (train.style.transition = "none"); + }, 250)), + 8 == S && + 2 == chunk && + ((Y = group6y - 11), C.move({ n: "train", y: Y })), + 8 != S || + cross2 || + 3 != chunk || + ((Z = 0), + (scale = 1), + (X = 151), + (Y = 0), + (vX = 0), + (chunkscale = 1), + (cm = 200), + (cl = 150), + (cr = 250), + (posonchunk = 0.01), + (cross2 = 1), + (train.style.transition = "transform .1s"), + (go = 0), + setTimeout(() => { + C.move({ n: "train", x: X, y: 0, z: Z, sx: 1, sy: 1, sz: 1 }); + }, 33), + setTimeout(() => { + (go = 1), lose || (train.style.transition = "none"); + }, 250)), + 9 == S && + (frames9++, + 3600 == frames9 && + ((level.innerHTML = + 'Don\'t like this level? "), + (localStorage["OS13kTrophy,🚂,Track Not Found,100%"] = + "You completed the game Track not Found"); + }, 1e4); + } + "front" == cp + ? C.camera({ z: "3d" == cam ? 50 : 300 }) + : "left" == cp || "leftfront" == cp || "leftback" == cp + ? C.camera({ z: "middle" == ch ? 50 : "3d" == cam ? 350 : 3500 }) + : "back" == cp + ? C.camera({ z: "3d" == cam ? 90 : 300 }) + : ("right" == cp || "rightfront" == cp || "rightback" == cp) && + C.camera({ z: "middle" == ch ? 50 : "3d" == cam ? 350 : 3500 }), + "up" == ch + ? (C.camera({ rx: "3d" == cam ? 5 : 0 }), + window.boat && (boat.style.opacity = 0)) + : "midup" == ch + ? (C.camera({ rx: 45 }), + window.boat && (boat.style.opacity = 1), + setTimeout(() => { + h2left.style.opacity = + h3left.style.opacity = + h2right.style.opacity = + h3right.style.opacity = + 1; + }, 900), + setTimeout(() => { + (river.style.opacity = 1), + window.river2 && (river2.style.opacity = 1); + }, 500)) + : "middle" == ch + ? (C.camera({ + rx: "3d" == cam || "left" == cp || "right" == cp ? 85 : 90, + }), + window.boat && (boat.style.opacity = 1), + setTimeout(() => { + h2left.style.opacity = + h3left.style.opacity = + h2right.style.opacity = + h3right.style.opacity = + 1; + }, 900), + setTimeout(() => { + (river.style.opacity = 1), + window.river2 && (river2.style.opacity = 1); + }, 500)) + : "middown" == ch + ? (C.camera({ rx: 135 }), + window.boat && (boat.style.opacity = 0), + (river.style.opacity = 0), + window.river2 && (river2.style.opacity = 0), + "3d" == cam && + ("left" == cp || "leftfront" == cp || "leftback" == cp + ? ((h2left.style.opacity = 0), (h3left.style.opacity = 0)) + : setTimeout(() => { + (h2left.style.opacity = 1), (h3left.style.opacity = 1); + }, 900), + "right" == cp || "rightfront" == cp || "rightback" == cp + ? ((h2right.style.opacity = 0), (h3right.style.opacity = 0)) + : setTimeout(() => { + (h2right.style.opacity = 1), (h3right.style.opacity = 1); + }, 900)), + "2d" == cam && + (h2left.style.opacity = + h3left.style.opacity = + h2right.style.opacity = + h3right.style.opacity = + 0)) + : "down" == ch && + (C.camera({ rx: "3d" == cam ? 175 : 180 }), + "3d" == cam + ? (h2left.style.opacity = + h3left.style.opacity = + h2right.style.opacity = + h3right.style.opacity = + 1) + : (h2left.style.opacity = + h3left.style.opacity = + h2right.style.opacity = + h3right.style.opacity = + 0)); + }), + (boom = () => { + for ( + var l = function (l) { + return l > 3e4 + ? null + : (200 & Math.pow(l + 1e3 * Math.sin(0.01 * l), 0.8) + ? 0.5 + : -0.5) * Math.pow(t(l, 3e4), 1); + }, + t = (l, t) => (t - l) / t, + n = new AudioContext(), + e = n.createBuffer(1, 96e3, 48e3), + a = e.getChannelData(0), + u = 96e3; + u--; + + ) + a[u] = l(u) / 5; + var o = n.createBufferSource(); + (o.buffer = e), o.connect(n.destination), o.start(); + }), + (ww = () => { + var l = function (l) { + return (l = 1.3 * Math.pow(l, 0.96)) > 5e4 + ? null + : ((l + 80 * Math.sin(l / 1900)) & 64 ? 1 : -1) * + Math.pow(t(l, 5e4), 3); + }, + t = (l, t) => (t - l) / t, + n = new AudioContext(), + e = n.createBuffer(1, 96e3, 48e3), + a = e.getChannelData(0); + for (i = 96e3; i--;) a[i] = l(i) / 5; + var u = n.createBufferSource(); + (u.buffer = e), u.connect(n.destination), u.start(); + }), + (mu = () => { + (n = -3), (A = new AudioContext()), (G = A.createGain()), note(); + }), + (note = () => { + var l = [ + "`dgd`dgd`dgd`dgdbeiebeiebeiebeieY]`]Y]`]Y]`]Y]`][_b_[_b_[_b_[_b_", + "l(((k(((g(((((gkl(((n(((n(p(pnlki(((((((i(((k(ikl(((n(((((nlkgik", + ]; + S && + ((O1 = A.createOscillator()), + (O2 = A.createOscillator()), + S && + "(" != l[0][n % 64] && + (O1.connect(G), + G.connect(A.destination), + O1.start(A.currentTime), + O1.frequency.setValueAtTime( + 440 * 1.06 ** (n >= 0 ? -105 + l[0].charCodeAt(n % 64) : 0), + A.currentTime + ), + (O1.type = + "2d" == cam ? "sine" : "3d" == cam ? "triangle" : "square"), + G.gain.setValueAtTime( + n >= 0 ? 0.06 : 1e-4, + A.currentTime + ("4d" == cam ? Math.random() / 3 : 0) + ), + G.gain.setTargetAtTime( + 0.001, + A.currentTime + ("4d" == cam ? Math.random() / 4 : 0.1), + 0.05 + ), + O1.stop(A.currentTime + ("4d" == cam ? Math.random() / 3 : 0.24))), + S && + "(" != l[1][n % 64] && + (O2.connect(G), + G.connect(A.destination), + O2.start(A.currentTime), + O2.frequency.setValueAtTime( + 440 * 1.06 ** (n >= 0 ? -105 + l[1].charCodeAt(n % 64) : 0), + A.currentTime + ), + (O2.type = + "2d" == cam ? "sine" : "3d" == cam ? "triangle" : "square"), + G.gain.setValueAtTime( + n >= 0 ? 0.08 : 1e-4, + A.currentTime + ("4d" == cam ? Math.random() / 3 : 0) + ), + G.gain.setTargetAtTime( + 0.001, + A.currentTime + ("4d" == cam ? Math.random() / 4 : 0.1), + 0.05 + ), + O2.stop(A.currentTime + ("4d" == cam ? Math.random() / 3 : 0.24))), + n++), + setTimeout(note, 270 + ("4d" == cam ? Math.random() / 2 - 0.25 : 0)); + }); +onload = () => { + fullscreen = 0; + S = 0; + _ = 0; + onresize(); + init(); + animate(); +}; \ No newline at end of file diff --git a/projects/Train Track Game/style.css b/projects/Train Track Game/style.css new file mode 100644 index 000000000..befd468b3 --- /dev/null +++ b/projects/Train Track Game/style.css @@ -0,0 +1,444 @@ +@font-face { + font-family: emoji; + src: url(https://xem.github.io/track-not-found/twemoji.ttf); +} + +@keyframes wood { + 100% { + background-position: -100% center; + } +} + +@keyframes tree { + 0% { + left: 600px; + } + + 100% { + left: -600px; + } +} + +@keyframes wobble { + 0% { + transform: rotate(-5deg); + } + + 50% { + transform: rotate(5deg); + } + + 100% { + transform: rotate(-5deg); + } +} + +@keyframes rumble { + 10% { + margin-top: -5px; + } + + 20% { + margin-top: 5px; + } + + 30% { + margin-top: -5px; + } + + 40% { + margin-top: 5px; + } + + 50% { + margin-top: -5px; + } + + 60% { + margin-top: 5px; + } + + 70% { + margin-top: -5px; + } + + 80% { + margin-top: 5px; + } + + 90% { + margin-top: -5px; + } + + 100% { + margin-top: 5px; + } +} + +@keyframes wiggle { + 50% { + transform: scale(1.5); + } +} + +#viewport { + width: 900px; + height: 480px; + overflow: hidden; + contain: strict; + border: 1px solid; + position: relative; + perspective: 600px; +} + +#viewport * { + transform-style: preserve-3d; + box-sizing: border-box; +} + +#camera { + width: 0; + height: 0; + position: absolute; + top: 50%; + left: 50%; +} + +* { + user-select: none; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + touch-action: manipulation; + box-sizing: border-box; +} + +#viewport { + background: #6b6; + font-family: emoji, calibri, sans-serif; +} + +#all { + transform-origin: 0 0; +} + +#viewport.blue { + background: linear-gradient(#abf, #def); +} + +h1 { + margin-left: -70px; +} + +body { + font-family: calibri, arial; + overflow: hidden; + margin: 0; + background: #000; +} + +#gg, +#h1, +#h2, +#h3, +#h4, +#hud { + position: fixed; + color: #fff; + text-align: center; + width: 900px; + text-shadow: 3px 3px 5px #000; +} + +#h1 { + margin-top: -480px; + font-size: 60px; +} + +#h2 { + margin-top: -400px; + font-size: 20px; +} + +#h3 { + margin-top: -100px; + font-size: 40px; + animation: wobble 2s infinite; + cursor: pointer; +} + +#h4 { + margin-top: -465px; + margin-left: 420px; + font-size: 30px; + cursor: pointer; +} + +.mobile #h4 { + display: none; +} + +.plane { + opacity: 1; +} + +.train { + font-size: 50px; + line-height: 50px; +} + +#train * { + pointer-events: none; +} + +.boat { + font-size: 80px; + line-height: 80px; +} + +.ground { + border-radius: 50%; +} + +.tree { + font-size: 60px; + line-height: 60px; +} + +.shadow { + color: rgba(0, 0, 0, 0.002); + text-shadow: 0 0 rgba(0, 0, 0, 0.35); + line-height: 70px; +} + +.title .woods { + position: fixed; + animation: wood 0.9s infinite linear; +} + +.tree { + position: fixed; + animation: tree 9s infinite linear; +} + +.tree.fixed { + animation: none; + transition: 1s; +} + +.tree2 { + animation-delay: -1.5s; +} + +.tree3 { + animation-delay: -2.5s; +} + +.tree4 { + animation-delay: -3.5s; +} + +.tree5 { + animation-delay: -5s; +} + +.tree6 { + animation-delay: -6.5s; +} + +.tree6 { + animation-delay: -7s; +} + +#hud { + width: 900px; + height: 480px; + margin-top: -480px; + text-align: left; + font-size: 26px; + padding: 5px 0 0 5px; + opacity: 0; + transition: opacity 2s; + pointer-events: none; +} + +#hud * { + pointer-events: all; + margin-top: 5px; +} + +.fixed { + animation: none; +} + +.hill { + background: linear-gradient(rgba(255, 255, 255, 0), + #6b6 10%, + #6b6 90%, + rgba(255, 255, 255, 0)); +} + +.mobile .hill { + background: #6b6; +} + +.hill2 { + transition: opacity 0.2s; + background: linear-gradient(rgba(255, 255, 255, 0), + #494 10%, + #494 90%, + rgba(255, 255, 255, 0)); +} + +.mobile .hill2 { + background: #494; +} + +.hill3 { + transition: opacity 0.2s; + background: #494; +} + +.river { + background: linear-gradient(rgba(255, 255, 255, 0), + #78d 10%, + #45f 90%, + rgba(255, 255, 255, 0)); + transition: opacity 0.5s; +} + +.mobile .river { + background: linear-gradient(#78d 10%, #45f 90%); +} + +.river2 { + background: linear-gradient(#fff1, + rgba(255, 255, 255, 0) 10%, + rgba(255, 255, 255, 0) 50%, + #fff2); + background-size: 100% 200px; + transition: opacity 0.5s; +} + +#buttons { + margin: 370px 0; +} + +button { + font-size: 25px; + background: #c8c8c8; + min-width: 50px; + min-height: 50px; + margin-left: 10px; +} + +button img { + vertical-align: bottom; +} + +#hud button * { + pointer-events: none; +} + +button span { + font-family: emoji, calibri; +} + +.reverse { + transform: scaleX(-1); + display: inline-block; +} + +#b_2d { + margin-left: 50px; +} + +button.on { + background: #fff; +} + +#black { + width: 900px; + height: 480px; + background: #000; + position: absolute; + top: 0; + opacity: 1; + transition: opacity 0.5s; + pointer-events: none; + color: #fff; + text-align: center; + padding: 90px 0 0; +} + +#black h1 { + margin-left: 0; +} + +.cp1 { + position: absolute; + top: 335px; + left: 830px; + text-align: center; +} + +.cp2 { + position: absolute; + top: 330px; + left: 730px; + text-align: center; +} + +.cp1 button, +.cp2 button { + min-height: 40px; +} + +.woods { + background: linear-gradient(90deg, + #ca0, + #ca0 50%, + rgba(255, 255, 255, 0) 50%); + background-size: 16.5px; + background-position: 25px 0; + font-size: 40px; + font-family: arial; + text-indent: 50px; + padding-top: 16px; +} + +.track * { + pointer-events: none; +} + +.sun { + background: radial-gradient(#fea, rgba(255, 255, 255, 0) 50%); + transition: transform 1s; +} + +.rumble { + animation: rumble 0.7s; +} + +.rumble2 { + animation: rumble 0.4s; +} + +#level { + padding: 0 0 0 10px; + transition: transform 0.2s 0.5s; +} + +.dynamite img { + animation: wiggle 1s infinite; +} + +a { + color: #57f; +} + +button.mini { + padding: 5px; + font-size: 16px; + min-height: 0; +} \ No newline at end of file diff --git a/projects/Tribute Page/Mah G.jpeg b/projects/Tribute Page/Mah G.jpeg new file mode 100644 index 000000000..7b83d67b9 Binary files /dev/null and b/projects/Tribute Page/Mah G.jpeg differ diff --git a/projects/Tribute Page/Tribute.html b/projects/Tribute Page/Tribute.html new file mode 100644 index 000000000..3f9b25d16 --- /dev/null +++ b/projects/Tribute Page/Tribute.html @@ -0,0 +1,78 @@ + + + + Mahatma Gandhi + + + +

Mahatma Gandhi

+ Mahatma Gandhi +
+
+ +

Biography

+

Name: Mohandas Karamchand Gandhi.

+

Birth: Born on October 2, 1869, in Porbandar, Gujarat, India.

+

Title: Revered as "Mahatma" (meaning "Great Soul").

+

Philosophy: Promoted Ahimsa (non-violence) and Satyagraha (truth-force) as methods of peaceful resistance.

+

Education: Studied law in London and became a barrister in 1891.

+

South Africa: Fought against racial discrimination while in South Africa from 1893 to 1915.

+

Role in Indian Independence: Leader of the Indian independence movement against British rule, advocating nonviolent civil disobedience.

+
+
+

Major Movements

+
    +
  • Satyagraha (1917): First major success in India's independence movement.
  • +
  • Non-Cooperation Movement (1920): Boycott of British goods and institutions.
  • +
  • Salt March (1930): Protested British salt tax with a 240-mile march.
  • +
  • Quit India Movement (1942): Demanded an end to British rule.
  • +
  • Imprisonments: Imprisoned several times by the British government for his activism.
  • +
+
+
+

Beliefs and Legacy

+

Belief in Simple Living: Advocated for self-reliance, handmade goods, and rural development.

+

Attire: Adopted the traditional Indian dhoti made of khadi, symbolizing simplicity and rejection of British goods.

+

Religious Pluralism: Believed in equality for all religions, working towards Hindu-Muslim unity.

+

Influence on Global Leaders: Inspired civil rights leaders like Martin Luther King Jr. and Nelson Mandela.

+

Assassination: Gandhi was assassinated on January 30, 1948, by Nathuram Godse.

+

Legacy: Regarded as the "Father of the Nation" in India, remembered for his contributions to nonviolent resistance and social reform.

+
+
+ + \ No newline at end of file diff --git a/projects/Virtual Pet Game/README.md b/projects/Virtual Pet Game/README.md new file mode 100644 index 000000000..523c646fc --- /dev/null +++ b/projects/Virtual Pet Game/README.md @@ -0,0 +1,11 @@ +virtual-pet-Game + +Here are some key features of virtual pet games: + +//Adoption and customization: Players can choose from various virtual pets, such as dogs, cats, birds, or even fantastical creatures, and customize their appearance, name, and behavior. + +//Care and nurturing: Players must feed, groom, play with, and provide shelter for their virtual pets, which can grow, learn, and evolve over time. + +//Interactions and activities: Players can engage in various activities with their virtual pets, such as playing games, going for walks, or training them to perform tricks. + +//Simulation and realism: Virtual pet games often simulate real-life pet care scenarios, such as feeding schedules, veterinary visits, and dealing with behavioral issues. diff --git a/projects/Virtual Pet Game/cat mouse.gif b/projects/Virtual Pet Game/cat mouse.gif new file mode 100644 index 000000000..b2b7ac533 Binary files /dev/null and b/projects/Virtual Pet Game/cat mouse.gif differ diff --git a/projects/Virtual Pet Game/dog.gif b/projects/Virtual Pet Game/dog.gif new file mode 100644 index 000000000..9743d79e7 Binary files /dev/null and b/projects/Virtual Pet Game/dog.gif differ diff --git a/projects/Virtual Pet Game/index.html b/projects/Virtual Pet Game/index.html new file mode 100644 index 000000000..2848df56a --- /dev/null +++ b/projects/Virtual Pet Game/index.html @@ -0,0 +1,43 @@ + + + + + + Virtual Pet Game + + + +
+

Virtual Pet Game

+
+

Hunger: 50

+

Boredom: 50

+

Health: 50

+

Tiredness: 50

+
+ +
+ + + + +
+ + +
+ Virtual Pet +
+ + +
+ cat +
+ +
+ dog +
+
+ + + + diff --git a/projects/Virtual Pet Game/script.js b/projects/Virtual Pet Game/script.js new file mode 100644 index 000000000..c4aaf8742 --- /dev/null +++ b/projects/Virtual Pet Game/script.js @@ -0,0 +1,88 @@ +// Initialize pet status +let hunger = 50; +let boredom = 50; +let health = 50; +let tiredness = 50; + +// Update pet status display +function updatePetStatus() { + document.getElementById('hunger').innerText = hunger; + document.getElementById('boredom').innerText = boredom; + document.getElementById('health').innerText = health; + document.getElementById('tiredness').innerText = tiredness; + + // Add animations based on pet status + const petImage = document.getElementById('pet'); + + if (hunger > 80) { + petImage.classList.add('hungry'); + } else { + petImage.classList.remove('hungry'); + } + + if (boredom > 80) { + petImage.classList.add('bored'); + } else { + petImage.classList.remove('bored'); + } + + if (health < 20) { + petImage.classList.add('sick'); + } else { + petImage.classList.remove('sick'); + } + + if (tiredness > 80) { + petImage.classList.add('tired'); + } else { + petImage.classList.remove('tired'); + } + + // Control pet movement: stop moving if the pet is bored + if (boredom < 80) { + petImage.classList.add('moving'); + } else { + petImage.classList.remove('moving'); + } +} + +// Feed pet +document.getElementById('feed-pet').addEventListener('click', () => { + hunger -= 10; + if (hunger < 0) hunger = 0; + updatePetStatus(); +}); + +// Play with pet +document.getElementById('play-with-pet').addEventListener('click', () => { + boredom -= 10; + if (boredom < 0) boredom = 0; + updatePetStatus(); +}); + +// Give medicine +document.getElementById('give-medicine').addEventListener('click', () => { + health += 10; + if (health > 100) health = 100; + updatePetStatus(); +}); + +// Put pet to bed +document.getElementById('put-to-bed').addEventListener('click', () => { + tiredness -= 10; + if (tiredness < 0) tiredness = 0; + updatePetStatus(); +}); + +// Update pet status every second +setInterval(() => { + hunger += 1; + boredom += 1; + health -= 1; + tiredness += 1; + if (hunger > 100) hunger = 100; + if (boredom > 100) boredom = 100; + if (health < 0) health = 0; + if (tiredness > 100) tiredness = 100; + updatePetStatus(); +}, 1000); diff --git a/projects/Virtual Pet Game/style.css b/projects/Virtual Pet Game/style.css new file mode 100644 index 000000000..2b0d2e713 --- /dev/null +++ b/projects/Virtual Pet Game/style.css @@ -0,0 +1,165 @@ +/* Main game container */ +.game-container { + width: 80%; + margin: 40px auto; + text-align: center; + position: relative; + overflow: hidden; +} + +/* Status of the pet */ +.pet-status { + margin-bottom: 20px; +} + +.pet-status p { + margin-bottom: 10px; +} + +/* Button styles */ +.game-actions { + margin-top: 20px; +} + +.game-actions button { + margin: 10px; + padding: 10px 20px; + border: none; + border-radius: 5px; + background-color: #4CAF50; + color: #fff; + cursor: pointer; +} + +.game-actions button:hover { + background-color: #3e8e41; +} + +/* Pet image container */ +.pet-image { + margin-top: 20px; + position: relative; + width: 100%; + height: 200px; /* Define height for the container */ +} + +/* Style for the turtle image */ +.pet-image img { + width: 200px; + height: 200px; + border-radius: 50%; + transition: transform 0.5s; + position: absolute; /* Allows movement */ + top: 0; /* Align the turtle vertically in the middle */ + left: 0; + right: 0; + margin: auto; /* Center the turtle horizontally */ +} + +.pet-image img:hover { + transform: scale(1.1); +} + +/* Linear movement animation for turtle */ +@keyframes movePet { + 0% { + left: calc(100% - 700px); /* Start from the right edge */ + } + 100% { + left: 0; /* Move to the left edge */ + } +} + + +.moving { + animation: movePet 15s linear infinite; /* Slower, linear movement */ +} + +/* Cat mouse image positioned at bottom-right */ +.cat-mouse { + position: fixed; + bottom: 10px; + right: 10px; +} + +.cat-mouse img { + width: 300px; /* Adjust the size as necessary */ + height: auto; +} + +/* Dog image positioned at bottom-left */ +.dog { + position: fixed; + bottom: 10px; + left: 10px; +} + +.dog img { + width: 300px; /* Adjust the size as necessary */ + height: auto; +} + +/* Animations for pet states */ +.hungry { + animation: hungry 2s infinite; +} + +.bored { + animation: bored 2s infinite; +} + +.sick { + animation: sick 2s infinite; +} + +.tired { + animation: tired 2s infinite; +} + +@keyframes hungry { + 0% { + transform: scale(1); + } + 50% { + transform: scale(1.1); + } + 100% { + transform: scale(1); + } +} + +@keyframes bored { + 0% { + transform: rotate(0deg); + } + 50% { + transform: rotate(10deg); + } + 100% { + transform: rotate(0deg); + } +} + +@keyframes sick { + 0% { + transform: scale(1); + } + 50% { + transform: scale(0.9); + } + 100% { + transform: scale(1); + } +} + +@keyframes tired { + 0% { + transform: rotate(0deg); + } + 50% { + transform: rotate(-10deg); + } + 100% { + transform: rotate(0deg); + } +} diff --git a/projects/Virtual Pet Game/turtle.gif b/projects/Virtual Pet Game/turtle.gif new file mode 100644 index 000000000..43bb29701 Binary files /dev/null and b/projects/Virtual Pet Game/turtle.gif differ diff --git a/projects/WordSearch Game/index.html b/projects/WordSearch Game/index.html new file mode 100644 index 000000000..42fca69ac --- /dev/null +++ b/projects/WordSearch Game/index.html @@ -0,0 +1,21 @@ + + + + + + Word Search Game + + + +
+

Word Search Game

+
+
+

Words to Find

+
    +
    + +
    + + + \ No newline at end of file diff --git a/projects/WordSearch Game/script.js b/projects/WordSearch Game/script.js new file mode 100644 index 000000000..c32b057e6 --- /dev/null +++ b/projects/WordSearch Game/script.js @@ -0,0 +1,131 @@ +document.addEventListener('DOMContentLoaded', () => { + const wordSearchGrid = document.getElementById('wordSearchGrid'); + const wordsList = document.getElementById('wordsList'); + const resetButton = document.getElementById('resetButton'); + + const words = ['EXPRESS','SQL','MONGODB', 'HTML', 'CSS', 'REACT', 'NODE']; + const gridSize = 10; + let selectedCells = []; + let selectedWord = ''; + let grid = []; + + function createGrid() { + grid = Array.from({ length: gridSize }, () => Array(gridSize).fill('')); + placeWordsInGrid(); + fillEmptyCells(); + renderGrid(); + } + + function placeWordsInGrid() { + words.forEach(word => { + let placed = false; + while (!placed) { + const direction = Math.random() < 0.5 ? 'horizontal' : 'vertical'; + const row = Math.floor(Math.random() * gridSize); + const col = Math.floor(Math.random() * gridSize); + if (canPlaceWord(word, row, col, direction)) { + placeWord(word, row, col, direction); + placed = true; + } + } + }); + } + + function canPlaceWord(word, row, col, direction) { + if (direction === 'horizontal') { + if (col + word.length > gridSize) return false; + for (let i = 0; i < word.length; i++) { + if (grid[row][col + i] !== '') return false; + } + } else { + if (row + word.length > gridSize) return false; + for (let i = 0; i < word.length; i++) { + if (grid[row + i][col] !== '') return false; + } + } + return true; + } + + function placeWord(word, row, col, direction) { + if (direction === 'horizontal') { + for (let i = 0; i < word.length; i++) { + grid[row][col + i] = word[i]; + } + } else { + for (let i = 0; i < word.length; i++) { + grid[row + i][col] = word[i]; + } + } + } + + function fillEmptyCells() { + for (let row = 0; row < gridSize; row++) { + for (let col = 0; col < gridSize; col++) { + if (grid[row][col] === '') { + grid[row][col] = getRandomLetter(); + } + } + } + } + + function renderGrid() { + wordSearchGrid.innerHTML = ''; + for (let row = 0; row < gridSize; row++) { + for (let col = 0; col < gridSize; col++) { + const cell = document.createElement('div'); + cell.textContent = grid[row][col]; + cell.addEventListener('click', () => selectCell(cell, row, col)); + wordSearchGrid.appendChild(cell); + } + } + } + + function getRandomLetter() { + const letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; + return letters[Math.floor(Math.random() * letters.length)]; + } + + function displayWords() { + wordsList.innerHTML = ''; + words.forEach(word => { + const li = document.createElement('li'); + li.textContent = word; + wordsList.appendChild(li); + }); + } + + function selectCell(cell, row, col) { + if (!cell.classList.contains('found')) { // Ensure we don't select already found words + cell.classList.add('selected'); + selectedCells.push(cell); + selectedWord += cell.textContent; + checkWord(); + } + } + + function checkWord() { + if (words.includes(selectedWord)) { + alert(`You found the word: ${selectedWord}`); + selectedCells.forEach(cell => { + cell.classList.remove('selected'); // Remove selected class + cell.classList.add('found'); // Add found class + }); + resetSelection(); + } + } + + function resetSelection() { + selectedCells.forEach(cell => cell.classList.remove('selected')); + selectedCells = []; + selectedWord = ''; + } + + resetButton.addEventListener('click', () => { + createGrid(); + displayWords(); + resetSelection(); + }); + + createGrid(); + displayWords(); +}); diff --git a/projects/WordSearch Game/styles.css b/projects/WordSearch Game/styles.css new file mode 100644 index 000000000..7112c8116 --- /dev/null +++ b/projects/WordSearch Game/styles.css @@ -0,0 +1,69 @@ +/* General styling */ +body { + font-family: Arial, sans-serif; + background: #f5f7fa; + color: #333; + text-align: center; + padding: 20px; +} + +.container { + background: #fff; + padding: 20px; + border-radius: 10px; + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); + max-width: 600px; + margin: 0 auto; +} + +h1 { + font-size: 2.5em; + margin-bottom: 20px; +} + +.grid { + display: grid; + grid-template-columns: repeat(10, 1fr); + gap: 5px; + margin-bottom: 20px; +} + +.grid div { + width: 30px; + height: 30px; + background: #e0e0e0; + display: flex; + align-items: center; + justify-content: center; + font-size: 1.2em; + cursor: pointer; +} + +.grid div.selected { + background: #007bff; + color: #fff; +} + +.grid div.found { + background: #28a745; /* Green background for found words */ + color: #fff; +} + +.words-container { + margin-bottom: 20px; +} + +.reset-button { + background: #007bff; + color: #fff; + border: none; + padding: 10px 20px; + font-size: 1em; + border-radius: 5px; + cursor: pointer; + transition: background 0.3s; +} + +.reset-button:hover { + background: #0056b3; +} diff --git a/projects/clone_of_amazon/imgs/amazon_favicon.png b/projects/clone_of_amazon/imgs/amazon_favicon.png new file mode 100644 index 000000000..2e6cc9fba Binary files /dev/null and b/projects/clone_of_amazon/imgs/amazon_favicon.png differ diff --git a/projects/clone_of_amazon/imgs/amazon_logo.png b/projects/clone_of_amazon/imgs/amazon_logo.png new file mode 100644 index 000000000..320210efc Binary files /dev/null and b/projects/clone_of_amazon/imgs/amazon_logo.png differ diff --git a/projects/clone_of_amazon/imgs/box1_image.jpg b/projects/clone_of_amazon/imgs/box1_image.jpg new file mode 100644 index 000000000..f4aa14e41 Binary files /dev/null and b/projects/clone_of_amazon/imgs/box1_image.jpg differ diff --git a/projects/clone_of_amazon/imgs/box2_image.jpg b/projects/clone_of_amazon/imgs/box2_image.jpg new file mode 100644 index 000000000..d807dc459 Binary files /dev/null and b/projects/clone_of_amazon/imgs/box2_image.jpg differ diff --git a/projects/clone_of_amazon/imgs/box3_image.jpg b/projects/clone_of_amazon/imgs/box3_image.jpg new file mode 100644 index 000000000..300f1f328 Binary files /dev/null and b/projects/clone_of_amazon/imgs/box3_image.jpg differ diff --git a/projects/clone_of_amazon/imgs/box4_image.jpg b/projects/clone_of_amazon/imgs/box4_image.jpg new file mode 100644 index 000000000..90ee126d0 Binary files /dev/null and b/projects/clone_of_amazon/imgs/box4_image.jpg differ diff --git a/projects/clone_of_amazon/imgs/box5_image.jpg b/projects/clone_of_amazon/imgs/box5_image.jpg new file mode 100644 index 000000000..4fe84c406 Binary files /dev/null and b/projects/clone_of_amazon/imgs/box5_image.jpg differ diff --git a/projects/clone_of_amazon/imgs/box6_image.jpg b/projects/clone_of_amazon/imgs/box6_image.jpg new file mode 100644 index 000000000..ca7f184bc Binary files /dev/null and b/projects/clone_of_amazon/imgs/box6_image.jpg differ diff --git a/projects/clone_of_amazon/imgs/box7_image.jpg b/projects/clone_of_amazon/imgs/box7_image.jpg new file mode 100644 index 000000000..21c237361 Binary files /dev/null and b/projects/clone_of_amazon/imgs/box7_image.jpg differ diff --git a/projects/clone_of_amazon/imgs/box8_image.jpg b/projects/clone_of_amazon/imgs/box8_image.jpg new file mode 100644 index 000000000..231274095 Binary files /dev/null and b/projects/clone_of_amazon/imgs/box8_image.jpg differ diff --git a/projects/clone_of_amazon/imgs/hero_image.jpg b/projects/clone_of_amazon/imgs/hero_image.jpg new file mode 100644 index 000000000..b4a28344a Binary files /dev/null and b/projects/clone_of_amazon/imgs/hero_image.jpg differ diff --git a/projects/clone_of_amazon/index.html b/projects/clone_of_amazon/index.html new file mode 100644 index 000000000..f7ef6ec88 --- /dev/null +++ b/projects/clone_of_amazon/index.html @@ -0,0 +1,178 @@ + + + + + + + amazon + + + + + +
    + +
    +
    + + All +
    + +
    +

    todays deals

    +

    costumer service

    +

    registry

    +

    gift card

    +

    sells

    +
    +
    + shop deals in electonics +
    +
    + +
    + +
    +
    your on amazon.com you can also shop on amazon india with fast local deliveryclick here to go to amazon.com
    +
    + +
    +
    +

    clothes

    +
    +

    see more

    +
    +

    Health & presonal care

    +
    +

    see more

    +
    +
    +

    furniture

    +
    +

    see more

    +
    +
    +

    electronics

    +
    +

    see more

    +
    +
    +

    beauty picks

    +
    +

    see more

    +
    +

    pet care

    +
    +

    see more

    +
    +
    +

    new arrival in toys

    +
    +

    see more

    +
    +
    +

    discover fashion trends

    +
    +

    see more

    +
    +
    + + + + \ No newline at end of file diff --git a/projects/clone_of_amazon/style.css b/projects/clone_of_amazon/style.css new file mode 100644 index 000000000..b4635f083 --- /dev/null +++ b/projects/clone_of_amazon/style.css @@ -0,0 +1,316 @@ +*{ + margin: 0; +} +.navbar{ + background-color: black; + height: 60px; + color:white ; + display: flex; + justify-content: space-evenly; +} +.navlogo{ + height: 50px; + width: 100px; +} +.logo{ + background-image: url("./imgs/amazon_logo.png"); + height: 50px; + width: 100px; + + background-size: cover; +} +border{ + border: 2px solid transparent; +} +.border:hover{ + border: 2px solid white; + padding: 3px; + +} +.ad1{ + font-size:10px; + margin-top: 10px; + margin-left: 10px; +} +.ad2{ + margin-left: 5px; +} +.i1{ + font-size: 20px; +} +.icon{ + display: flex; + align-items: center; +} +.navsearch{ + justify-content: space-evenly; + display: flex; + height: 40px; + width: 620px; + border-top-left-radius: 4px; + border-bottom-left-radius: 4px; + margin-top: 10px; + +} +.opt{ + border-top-left-radius: 4px; + border-bottom-left-radius: 4px; + width: 50px; + text-align: center; + border: none; + ; + +} +.pl{ + width: 100%; + font-size: 1rem; + border: none; + +} +.searchicon{ + width: 45px; + background-color:#febd68; + display: flex; + justify-content: center; + align-items: center; + font-size: 1.2rem; + border-top-right-radius: 2px; + border-bottom-right-radius: 2px; +} +.navsearch:hover{ + border: 5px solid #febd68; +} +.navsignin{ + margin-top: 10px; +} +.navreturn{ + margin-top: 10px; +} +.navcart{ + margin-top: 10px; +} +span{ + font-size: 0.7rem; + +} +.nav2{ + font-size: 0.85rem; + font-weight: 700; + +} +.navcart i{ + font-size: 30px; +} +.panel{ + height: 40px; + background-color: #222f3d; + color: white; + display: flex; + align-items: center; + justify-content: space-evenly; + +} +.panelop p{ + display: inline; + margin-left: 10px; +} +.panelop{ + width: 70%; + font-size: 0.85rem; + +} +.panelop p:hover{ + border: 1px solid white; + padding: 7px; + border-radius: 1px; +} +.paneldeals{ + font-size: 0.9rem; + font-weight: 700; +} + +.hero{ + background-image: url("./imgs/hero_image.jpg"); + background-size: cover; + height: 400px; + display: flex; + justify-content: center; + align-items: flex-end; +} +.heromsg{ + background-color: white; + height: 40px; + width: 1200px; + display: flex; + align-items: center; + justify-content: center; + margin-bottom: 20px; +} + +.shopsec{ + display: flex; + flex-wrap: wrap; + justify-content: space-evenly; + background-color: #e2e7e6; + +} +.box{ + height: 400px; + + width: 23%; + background-color: white; + margin-top: 20px; +} +.box1img{ + background-image: url("./imgs/box1_image.jpg"); + height: 325px; + background-size: cover; + margin-left: 10px; + margin-right: 10px; + margin-top: 10px; +} + +.box1img{ + background-image: url("./imgs/box1_image.jpg"); + height: 325px; + background-size: cover; + margin-left: 10px; + margin-right: 10px; + margin-top: 10px; +} + +.box2img{ + background-image: url("./imgs/box2_image.jpg"); + height: 325px; + background-size: cover; + margin-left: 10px; + margin-right: 10px; + margin-top: 10px; +} + +.box3img{ + background-image: url("./imgs/box3_image.jpg"); + height: 325px; + background-size: cover; + margin-left: 10px; + margin-right: 10px; + margin-top: 10px; +} + +.box4img{ + background-image: url("./imgs/box4_image.jpg"); + height: 325px; + background-size: cover; + margin-left: 10px; + margin-right: 10px; + margin-top: 10px; +} + +.box5img{ + background-image: url("./imgs/box5_image.jpg"); + height: 325px; + background-size: cover; + margin-left: 10px; + margin-right: 10px; + margin-top: 10px; +} + +.box6img{ + background-image: url("./imgs/box6_image.jpg"); + height: 325px; + background-size: cover; + margin-left: 10px; + margin-right: 10px; + margin-top: 10px; +} +.box7img{ + background-image: url("./imgs/box7_image.jpg"); + height: 325px; + background-size: cover; + margin-left: 10px; + margin-right: 10px; + margin-top: 10px; +} + +.box8img{ + background-image: url("./imgs/box8_image.jpg"); + height: 325px; + background-size: cover; + margin-left: 10px; + margin-right: 10px; + margin-top: 10px; +} +.box p{ + + margin-left: 10px; + color: #551A8B; + +} + + +h2{ + margin-top: 5px; + margin-left: 10px; +} + +.shopsec p{ + + margin-top: 10px; + +} +.foot1{ + height: 35px; + background-color: #222f3d; + color: white; + + display: flex; + justify-content: center; + align-items: center; +} +.foot2{ + background-color: #222f3d; + display: flex; + justify-content: space-evenly; + +} +ul a{ + display: block; + font-size: 0.85rem; + margin-top: 10px; + color: #e2e7e6; +} +ul a:hover{ + text-decoration: underline; +} +ul p{ + color: #e2e7e6; + font-weight: 700; +} +.foot3{ + background-color: #222f3d; + border-top: 0.5px solid white; + height: 60px; + display: flex; + justify-content: center; + align-items: center; + + +} + +.logo{ + background-image: url("./amazon_logo.png"); + background-size: cove; + height: 50px; + width: 100px; + + +} + + +.foot4{ + background-color: #222f3d; + color: white; + display: flex; + justify-content: center; + align-items: center; +} \ No newline at end of file diff --git a/projects/fashion shop/OIP.jpeg b/projects/fashion shop/OIP.jpeg new file mode 100644 index 000000000..c5a671ed5 Binary files /dev/null and b/projects/fashion shop/OIP.jpeg differ diff --git a/projects/fashion shop/app.jpg b/projects/fashion shop/app.jpg new file mode 100644 index 000000000..b0c7088ed Binary files /dev/null and b/projects/fashion shop/app.jpg differ diff --git a/projects/fashion shop/b10.jpg b/projects/fashion shop/b10.jpg new file mode 100644 index 000000000..e8436d341 Binary files /dev/null and b/projects/fashion shop/b10.jpg differ diff --git a/projects/fashion shop/b17.jpg b/projects/fashion shop/b17.jpg new file mode 100644 index 000000000..8e8a33029 Binary files /dev/null and b/projects/fashion shop/b17.jpg differ diff --git a/projects/fashion shop/b18.jpg b/projects/fashion shop/b18.jpg new file mode 100644 index 000000000..f98f205f5 Binary files /dev/null and b/projects/fashion shop/b18.jpg differ diff --git a/projects/fashion shop/b2.jpg b/projects/fashion shop/b2.jpg new file mode 100644 index 000000000..c435bc363 Binary files /dev/null and b/projects/fashion shop/b2.jpg differ diff --git a/projects/fashion shop/b4.jpg b/projects/fashion shop/b4.jpg new file mode 100644 index 000000000..cf119e56c Binary files /dev/null and b/projects/fashion shop/b4.jpg differ diff --git a/projects/fashion shop/b7.jpg b/projects/fashion shop/b7.jpg new file mode 100644 index 000000000..5a8ecb003 Binary files /dev/null and b/projects/fashion shop/b7.jpg differ diff --git a/projects/fashion shop/f1.jpg b/projects/fashion shop/f1.jpg new file mode 100644 index 000000000..7d5f516fb Binary files /dev/null and b/projects/fashion shop/f1.jpg differ diff --git a/projects/fashion shop/f1.png b/projects/fashion shop/f1.png new file mode 100644 index 000000000..0a35eb010 Binary files /dev/null and b/projects/fashion shop/f1.png differ diff --git a/projects/fashion shop/f2.jpg b/projects/fashion shop/f2.jpg new file mode 100644 index 000000000..a2cbe5be7 Binary files /dev/null and b/projects/fashion shop/f2.jpg differ diff --git a/projects/fashion shop/f2.png b/projects/fashion shop/f2.png new file mode 100644 index 000000000..c524bf359 Binary files /dev/null and b/projects/fashion shop/f2.png differ diff --git a/projects/fashion shop/f3.jpg b/projects/fashion shop/f3.jpg new file mode 100644 index 000000000..2f95e4d63 Binary files /dev/null and b/projects/fashion shop/f3.jpg differ diff --git a/projects/fashion shop/f3.png b/projects/fashion shop/f3.png new file mode 100644 index 000000000..8366e8dcf Binary files /dev/null and b/projects/fashion shop/f3.png differ diff --git a/projects/fashion shop/f4.jpg b/projects/fashion shop/f4.jpg new file mode 100644 index 000000000..17d6e4142 Binary files /dev/null and b/projects/fashion shop/f4.jpg differ diff --git a/projects/fashion shop/f4.png b/projects/fashion shop/f4.png new file mode 100644 index 000000000..4714ed257 Binary files /dev/null and b/projects/fashion shop/f4.png differ diff --git a/projects/fashion shop/f5.jpg b/projects/fashion shop/f5.jpg new file mode 100644 index 000000000..719b18f33 Binary files /dev/null and b/projects/fashion shop/f5.jpg differ diff --git a/projects/fashion shop/f5.png b/projects/fashion shop/f5.png new file mode 100644 index 000000000..4876146d7 Binary files /dev/null and b/projects/fashion shop/f5.png differ diff --git a/projects/fashion shop/f6.jpg b/projects/fashion shop/f6.jpg new file mode 100644 index 000000000..498d442b3 Binary files /dev/null and b/projects/fashion shop/f6.jpg differ diff --git a/projects/fashion shop/f6.png b/projects/fashion shop/f6.png new file mode 100644 index 000000000..2525c18fe Binary files /dev/null and b/projects/fashion shop/f6.png differ diff --git a/projects/fashion shop/f7.jpg b/projects/fashion shop/f7.jpg new file mode 100644 index 000000000..93f5881c9 Binary files /dev/null and b/projects/fashion shop/f7.jpg differ diff --git a/projects/fashion shop/f8.jpg b/projects/fashion shop/f8.jpg new file mode 100644 index 000000000..623c88555 Binary files /dev/null and b/projects/fashion shop/f8.jpg differ diff --git a/projects/fashion shop/hero.png b/projects/fashion shop/hero.png new file mode 100644 index 000000000..4a0c67403 Binary files /dev/null and b/projects/fashion shop/hero.png differ diff --git a/projects/fashion shop/hero2.jpg b/projects/fashion shop/hero2.jpg new file mode 100644 index 000000000..a634de694 Binary files /dev/null and b/projects/fashion shop/hero2.jpg differ diff --git a/projects/fashion shop/index.html b/projects/fashion shop/index.html new file mode 100644 index 000000000..014030c7f --- /dev/null +++ b/projects/fashion shop/index.html @@ -0,0 +1,424 @@ + + + + + + KKS Fashion + + + + + + +
    + +
    +
    +
    +

    Trade-in-Offer

    +

    Super Value Deals

    +

    On All Products

    +

    save more coupons & up to 70% off

    + +
    + +
    +
    + +
    Free shipping
    +
    +
    + +
    Online Order
    +
    +
    + +
    Save Money
    +
    +
    + +
    Promotions
    +
    +
    + +
    Happy Sell
    +
    +
    + +
    24*7 Support
    +
    + +
    +
    +

    Features Products

    +

    Summer Collection New Modern Design

    +
    +
    + + Adidas +

    Cartoon Astronaut T-Shirts

    +
    + + + + + +
    +

    $78

    + + +
    +
    + + Adidas +

    Cartoon Astronaut T-Shirts

    +
    + + + + + +
    +

    $78

    + + +
    +
    + + Adidas +

    Cartoon Astronaut T-Shirts

    +
    + + + + + +
    +

    $78

    + + +
    +
    + + Adidas +

    Cartoon Astronaut T-Shirts

    +
    + + + + + +
    +

    $78

    + + +
    +
    + + Adidas +

    Cartoon Astronaut T-Shirts

    +
    + + + + + +
    +

    $78

    + + +
    +
    + + Adidas +

    Cartoon Astronaut T-Shirts

    +
    + + + + + +
    +

    $78

    + + +
    +
    + + Adidas +

    Cartoon Astronaut T-Shirts

    +
    + + + + + +
    +

    $78

    + + +
    +
    + + Adidas +

    Cartoon Astronaut T-Shirts

    +
    + + + + + +
    +

    $78

    + + +
    +
    + +
    +
    +

    Repair Service

    +

    Up to 70% off - All t-shirts & Accessories

    + +
    +
    +

    New Arrivals

    +

    Summer Collection New Modern Design

    +
    +
    + + Adidas +

    Cartoon Astronaut T-Shirts

    +
    + + + + + +
    +

    $78

    + + +
    +
    + + Adidas +

    Cartoon Astronaut T-Shirts

    +
    + + + + + +
    +

    $78

    + + +
    +
    + + Adidas +

    Cartoon Astronaut T-Shirts

    +
    + + + + + +
    +

    $78

    + + +
    +
    + + Adidas +

    Cartoon Astronaut T-Shirts

    +
    + + + + + +
    +

    $78

    + + +
    +
    + + Adidas +

    Cartoon Astronaut T-Shirts

    +
    + + + + + +
    +

    $78

    + + +
    +
    + + Adidas +

    Cartoon Astronaut T-Shirts

    +
    + + + + + +
    +

    $78

    + + +
    +
    + + Adidas +

    Cartoon Astronaut T-Shirts

    +
    + + + + + +
    +

    $78

    + + +
    +
    + + Adidas +

    Cartoon Astronaut T-Shirts

    +
    + + + + + +
    +

    $78

    + + +
    +
    + +
    +
    +
    +
    +

    Crazy Deals

    +

    Buy One get 1 FREE

    + The Best Classic Sale is Live on KKs Fashion + +
    +
    +

    Spring Summer

    +

    Upcoming Season

    + The Best Classic Sale is Live on KKs Fashion + +
    +
    +
    +
    +

    Seasonal Sale

    +
    Winter Collection at 50% Off
    +
    +
    +

    New Footware Collections

    +
    50% Off
    +
    +
    +

    T-shirts

    +
    Trendy
    +
    +
    + +
    +
    + + + + \ No newline at end of file diff --git a/projects/fashion shop/n1.jpg b/projects/fashion shop/n1.jpg new file mode 100644 index 000000000..9afe15cac Binary files /dev/null and b/projects/fashion shop/n1.jpg differ diff --git a/projects/fashion shop/n2.jpg b/projects/fashion shop/n2.jpg new file mode 100644 index 000000000..4d1121f0a Binary files /dev/null and b/projects/fashion shop/n2.jpg differ diff --git a/projects/fashion shop/n3.jpg b/projects/fashion shop/n3.jpg new file mode 100644 index 000000000..b3cf21646 Binary files /dev/null and b/projects/fashion shop/n3.jpg differ diff --git a/projects/fashion shop/n4.jpg b/projects/fashion shop/n4.jpg new file mode 100644 index 000000000..b6fe24478 Binary files /dev/null and b/projects/fashion shop/n4.jpg differ diff --git a/projects/fashion shop/n5.jpg b/projects/fashion shop/n5.jpg new file mode 100644 index 000000000..84717f2da Binary files /dev/null and b/projects/fashion shop/n5.jpg differ diff --git a/projects/fashion shop/n6.jpg b/projects/fashion shop/n6.jpg new file mode 100644 index 000000000..836431856 Binary files /dev/null and b/projects/fashion shop/n6.jpg differ diff --git a/projects/fashion shop/n7.jpg b/projects/fashion shop/n7.jpg new file mode 100644 index 000000000..dbf0fdd57 Binary files /dev/null and b/projects/fashion shop/n7.jpg differ diff --git a/projects/fashion shop/n8.jpg b/projects/fashion shop/n8.jpg new file mode 100644 index 000000000..f80764b25 Binary files /dev/null and b/projects/fashion shop/n8.jpg differ diff --git a/projects/fashion shop/pay.png b/projects/fashion shop/pay.png new file mode 100644 index 000000000..393b88f7f Binary files /dev/null and b/projects/fashion shop/pay.png differ diff --git a/projects/fashion shop/play.jpg b/projects/fashion shop/play.jpg new file mode 100644 index 000000000..d67c1ceca Binary files /dev/null and b/projects/fashion shop/play.jpg differ diff --git a/projects/fashion shop/style.css b/projects/fashion shop/style.css new file mode 100644 index 000000000..40577e99b --- /dev/null +++ b/projects/fashion shop/style.css @@ -0,0 +1,366 @@ +*{ + margin: 0; + padding: 0; + box-sizing: border-box; + font-family: Cambria, Cochin, Georgia, Times, 'Times New Roman', serif; +} +h1{ + font-size: 50px; + line-height: 64px; + color: #222; + +} +h2{ + font-size: 46px; + line-height: 54px; + color: #222; + +} +h4{ + font-size: 20px; + color: #222; + + +} +h6{ + font-weight: 700; + font-size: 12px; +} +p{ + font-size: 16px; + color: #465b52; + margin: 15px 0 20px 0; +} +#header{ + display: flex; + align-items: center; + justify-content: space-between; + background-color: #e3e6f3; + padding: 20px 80px; + box-shadow: 0 5px 15px rgba(0,0,0,0.06); + z-index: 999; + position: fixed; + top: 0; + left: 0; + right: 0; +} +.header-list{ + display: flex; + align-items: center; + justify-content: center; +} +.header-list-nav ul{ + display: flex; +} +.header-list-nav ul li{ + list-style-type: none; + padding: 0 20px; + position: relative; +} +.header-list-nav ul a{ + text-decoration: none; + font-size: 16px; + font-weight: 600; + color: #1a1a1a; + transition: 0.3s ease; +} +.header-list-nav ul a:hover, +.header-list-nav ul a.active{ + color:#088178; + content: ""; + +} +.header-logo img{ + width: 60px; + height: 60px; +} +.header-list-icon a{ + color: #1a1a1a; + padding-left: 20px; + transition: 0.3s ease; +} +.header-list-icon a:hover{ + color: #088178; +} +.header-list-nav ul a:hover::after, +.header-list-nav ul a.active::after{ + content: ""; + width: 40%; + height: 2px; + background: #088178; + position: absolute; + bottom: -4px; + left: 20px; +} +#hero{ + background-image: url(hero2.jpg); + height: 80vh; + width: 100%; + background-size: cover; + display: flex; + flex-direction: column; + align-items: flex-start; + justify-content: center; + padding: 0 80px; +} +#hero h4{ + padding-bottom: 15px; + font-size: 40px; + color: brown; + +} +#hero h2{ + font-size: 70px; +} +#hero h1{ + color: #088178; + font-size: 70px; +} +#hero button{ + background-color: transparent; + background-image: url(); + background-repeat: no-repeat; + background-size: cover; + width: 260px; + height: 60px; + border: 0; + cursor: pointer; + font-size: 20px; + font-weight: 700; + color: #088178; + padding: 14px 65px 14px 65px; +} +#features{ + display: flex; + align-items: center; + justify-content: space-around; +} + +#features .f-box{ + height: 200px; + width: 180px; + text-align: center; + padding: 25px 15px; + box-shadow: 20px 20px 34px rgba(0,0,0,0.3); + border: 1px solid #cce7d0; + margin: 15px 0; + transition: box-shadow 0.3s; + +} +#features .f-box:hover{ + box-shadow: 10px 10px 54px rgba(0, 0, 0, 0.1); + +} +#features .f-box img{ + width: 100%; + margin-bottom: 10px; +} +#features .f-box h6{ + display: inline-block; + padding: 9px 8px 6px 8px; + line-height: 1; + font-size: 14px; + border-radius: 4px; + color: #088178; + background-color: #fddde4; +} + +.product-session .pro-collection{ + display: flex; + flex-wrap: wrap; + justify-content: space-around; + margin: 0px 60px; +} +.product-session h1, +.product-session p{ + text-align: center; +} +.product-session .product-cart{ + width: 200px; + padding: 1px solid #ebebeb; + padding: 13px; + margin-left: 70px; + margin-right: 150px; + margin-bottom: 30px; + border-radius: 25px; + position: relative; + box-shadow: 20px 20px 30px rgba(0, 0, 0, 0.02); + transition: box-shadow 0.2s; +} +.product-session .product-cart:hover{ + box-shadow: 20px 20px 30px rgba(0,0,0,0.06); +} +.product-session .product-cart img{ + width: 100%; + border-radius: 25px; +} +.product-session .product-cart span{ + color: #969696; + font-weight: 500; + line-height: 30px; +} +.product-session .product-cart h4{ + font-size: 18px; + color: rgb(41, 41, 41); +} +.product-session .product-cart .stars{ + color: #e6ae2c; + padding: 6px 0; +} +.product-session .product-cart .price{ + color: #088178; + padding: 4px 0; +} +.product-session .product-cart .buy-icon{ + color: #088178; + background-color: #c7e9e75e; + padding: 15px; + position: absolute; + border-radius: 50px; + right: 10px; + bottom: 10px; + +} +#off-banner{ + background-image: url(b2.jpg); + background-size: cover; + width: 100%; + height: 40vh; + display: flex; + align-items: center; + justify-content: center; + flex-direction: column; + +} +#off-banner h4{ + color: #eaebf0; + +} +#off-banner h2{ + color: #eaebf0; + padding: 20px 0; + +} +button.normal{ + font-size: 14px; + font-weight: 600; + padding: 15px 30px; + color: #000; + border-radius: 4px; + border: none; + cursor: pointer; + outline: none; + background-color: #fff; + transition: 0.2s; + + +} +#banners{ + margin: 0 60px; +} +#banners h2,h4,span{ + color: rgb(248, 248, 248); +} +#banners .big-banners{ + display: flex; + align-items: center; + justify-content: center; +} +#banners .big-banners div{ + min-width: 500px; + margin: 15px; + height: 300px; + display: flex; + flex-direction: column; + align-items: flex-start; + justify-content: center; + padding: 20px; + background-size: cover; + backdrop-filter: blur(8%); +} +#banners .big-banners-1{ + background-image: url(b17.jpg); +} +#banners .big-banners-2{ + background-image: url(b10.jpg); +} +#banners .small-banners-1{ + background-image: url(b7.jpg); +} +#banners .small-banners-2{ + background-image: url(b4.jpg); +} +#banners .small-banners-3{ + background-image: url(b18.jpg); +} +#banners .big-banners button{ + margin-top: 20px; + padding: 12px 20px; + font-size: 16px; + font-weight: 500; + background-color: transparent; + color: rgb(248, 248, 248); + border: 1px solid rgb(248, 248, 248); + cursor: pointer; + transition: 0.3s ease; +} +#banners .big-banners div:hover button{ + background-color: #088178; + border: 1px solid #088178; +} +#banners .small-banners{ + display: flex; + align-items: center; + justify-content: center; +} +#banners .small-banners div{ + min-width: 370px; + height: 200px; + margin: 15px; + display: flex; + flex-direction: column; + align-items: flex-start; + justify-content: center; + padding: 25px; + background-size: cover; +} +#banners .small-banners h2{ + font-size: 25px; + +} +#banners .small-banners h5{ + color: #771818; +} +#footer{ + display: flex; + align-items: flex-start; + justify-content: space-between; + padding: 75px; + background-color: #ececec; +} +#footer p, #footer a{ + text-decoration: none; + color: rgb(109, 109, 109); +} +#footer a:hover{ + color: #088178; +} +#footer .about a{ + display: block; + padding: 8px 0; +} +#footer .myaccount a{ + display: block; + padding: 8px 0; + +} +#footer .download img{ + border: 1px solid #08817969; + border-radius: 7px; +} + + + + + +