diff --git a/client/connection.js b/client/connection.js new file mode 100644 index 0000000..715062e --- /dev/null +++ b/client/connection.js @@ -0,0 +1,81 @@ +//===== Constructor + +const Connection = function() { + // Local event listeners + document.addEventListener('L-robots', () => { + this.ws.send(JSON.stringify({ head: { type: 'reposition-robots' }})); + }); + + document.addEventListener('L-walls', () => { + this.ws.send(JSON.stringify({ head: { type: 'regenerate-walls' }})); + }); + + document.addEventListener('L-guess', (evt) => { + this.ws.send(JSON.stringify({ head: { type: 'guess' }, rawBody: evt.detail })); + }); + + document.addEventListener('L-join', (evt) => { + this.connect(); + }); +}; + +Connection.prototype.connect = function(){ + const names = ["Biff", "Morty", "Herb", "Chester", "Lyle", "Cap", "Dale", "Ned", "Mindy"] + const r = Math.floor(Math.random() * names.length); + const rawInput = names[r] //prompt("What is your name?"); + + this.ws = new WebSocket('ws://localhost:8080/ricochet?name=' + rawInput); + + this.ws.addEventListener('open', this.onOpen.bind(this)); + this.ws.addEventListener('error', this.onError.bind(this)); + this.ws.addEventListener('message', this.onReceiveMessage.bind(this)); +}; + +//===== Connection event handlers + +Connection.prototype.onOpen = function() { + const evt = new Event('L-conn-open'); + document.dispatchEvent(evt); +}; + +Connection.prototype.onError = function(err) { + console.error(err); + + const evt = new CustomEvent('L-conn-error', { detail: err }); + document.dispatchEvent(evt); +}; + +Connection.prototype.onReceiveMessage = function({ data }) { + const msg = JSON.parse(data); + console.warn(msg); + + if (!msg.type) { + console.warn("Unprocessable message: ", msg) + return; + } + + let eventName; + + switch (msg.type) { + case 'players': + eventName = 'G-players'; + break; + + case 'robots': + eventName = 'G-robots'; + break; + + case 'walls': + eventName = 'G-walls'; + break; + + case 'guess': + eventName = 'G-guess'; + break; + } + + if (eventName) { + const evt = new CustomEvent(eventName, { detail: msg }); + document.dispatchEvent(evt); + } +}; \ No newline at end of file diff --git a/client/board.js b/client/content.js similarity index 84% rename from client/board.js rename to client/content.js index 8ff7b44..37f4429 100644 --- a/client/board.js +++ b/client/content.js @@ -1,4 +1,6 @@ -const Board = function({ parent, squares }) { +//===== Constructor + +const Content = function({ parent, squares }) { this.parent = parent; this.squares = squares; @@ -7,24 +9,26 @@ const Board = function({ parent, squares }) { this.listeners = {}; this.initialRobotState = []; - this.drawSquares(); + // this.drawSquares(); + // document.addEventListener('L-conn-open', this.msgStartGame.bind(this)); - document.addEventListener('board-reset', this.onReset.bind(this)); + // document.addEventListener('board-reset', this.onReset.bind(this)); + // from connection: board.drawRobots(data.body); + // from connection: board.drawWalls(data.body); + // from connection: board.onReceiveGuess(data.body); }; -Board.prototype.drawRobots = function(robots) { +//===== Event handlers + +//===== Event handlers + + +Content.prototype.drawRobots = function(robots) { this.initialRobotState = robots; this.robots = {}; - while (this.parent.getElementsByClassName('content-robot').length) { - const child = this.parent.getElementsByClassName('content-robot')[0]; - child.parentNode.removeChild(child); - } - - while (this.parent.getElementsByClassName('content-arrows').length) { - const child = this.parent.getElementsByClassName('content-arrows')[0]; - child.parentNode.removeChild(child); - } + this.parent.querySelectorAll('.content-robot').forEach(el => el.parentNode.removeChild(el)); + this.parent.querySelectorAll('.content-arrows').forEach(el => el.parentNode.removeChild(el)); robots.forEach(({ color, i, j }) => { const { x, y } = this.squares.ijToXy({ i, j }); @@ -83,7 +87,7 @@ Board.prototype.drawRobots = function(robots) { this.updateArrowVisibilities(); }; -Board.prototype.drawArrow = function({ direction, label, i, j, left, top, parentId }) { +Content.prototype.drawArrow = function({ direction, label, i, j, left, top, parentId }) { const s = this.squares.sideLength; const arrow = document.createElement('div'); @@ -102,7 +106,7 @@ Board.prototype.drawArrow = function({ direction, label, i, j, left, top, parent return arrow; }; -Board.prototype.drawSquares = function() { +Content.prototype.drawSquares = function() { for (let i = 0; i < this.squares.perSide; i++) { for (let j = 0; j < this.squares.perSide; j++) { // All squares are absolutely positioned relative to the viewport. @@ -120,18 +124,11 @@ Board.prototype.drawSquares = function() { } }; -Board.prototype.drawWalls = function(edges) { +Content.prototype.drawWalls = function(edges) { this.walls = {}; - while (this.parent.getElementsByClassName('content-wall-x').length) { - const child = this.parent.getElementsByClassName('content-wall-x')[0]; - child.parentNode.removeChild(child); - } - - while (this.parent.getElementsByClassName('content-wall-y').length) { - const child = this.parent.getElementsByClassName('content-wall-y')[0]; - child.parentNode.removeChild(child); - } + this.parent.querySelectorAll('.content-wall-x').forEach(el => el.parentNode.removeChild(el)); + this.parent.querySelectorAll('.content-wall-y').forEach(el => el.parentNode.removeChild(el)); edges.forEach(edge => { this.walls[edge] = true; @@ -169,7 +166,7 @@ Board.prototype.drawWalls = function(edges) { this.updateArrowVisibilities(); }; -Board.prototype.moveRobot = function({ id, i, j }) { +Content.prototype.moveRobot = function({ id, i, j }) { const robot = document.getElementById(`robot-${id}`); const arrows = document.getElementById(`arrows-${id}`); @@ -192,7 +189,7 @@ Board.prototype.moveRobot = function({ id, i, j }) { document.dispatchEvent(event); } -Board.prototype.updateArrowVisibilities = function() { +Content.prototype.updateArrowVisibilities = function() { const keys = Object.keys(this.robots); keys.forEach(key => { @@ -219,7 +216,7 @@ Board.prototype.updateArrowVisibilities = function() { }); } -Board.prototype.onArrowClick = function(evt) { +Content.prototype.onArrowClick = function(evt) { const direction = evt.currentTarget.dataset.direction; const id = evt.currentTarget.dataset.parent; @@ -234,11 +231,15 @@ Board.prototype.onArrowClick = function(evt) { this.moveRobot({ id, i: i2, j: j2 }) }; -Board.prototype.onReset = function() { +Content.prototype.onReceiveGuess = function() { + console.log("Board onReceiveGuess()") +} + +Content.prototype.onReset = function() { this.drawRobots(this.initialRobotState); }; -Board.prototype.findNextObstacle = function({ direction, i, j }) { +Content.prototype.findNextObstacle = function({ direction, i, j }) { switch (direction) { case 'right': for (let ii = i + 1; ii < this.squares.perSide; ii++) { diff --git a/client/controls.js b/client/controls.js index eddaf1f..602f1ec 100644 --- a/client/controls.js +++ b/client/controls.js @@ -1,101 +1,174 @@ +//===== Constructor + const Controls = function() { this.moves = 0; + this.names = {}; - document.addEventListener('move-increment', this.onMoveIncrement.bind(this)); - - document.getElementById('controls-moves-reset').addEventListener('click', this.onMoveReset.bind(this)); - document.getElementById('controls-next-round').addEventListener('click', this.onStartNextGame.bind(this)); - document.getElementById('controls-regenerate-walls').addEventListener('click', this.onRegenWalls.bind(this)); - document.getElementById('controls-reposition-robots').addEventListener('click', this.onRepositionRobots.bind(this)); - // document.getElementById('controls-timer-skip').addEventListener('click', this.onSkipTimer.bind(this)); -} - - // guessBuild: = function() { - // const container = document.getElementById('controls-guesses'); - // container.querySelectorAll('.controls-guess').forEach(el => el.parentNode.removeChild(el)); + // this.buildGuesses(); + // this.setUi('connecting'); - // for (let i = 1; i <= 30; i++) { - // const guess = document.createElement('div'); - // guess.className = 'controls-guess'; - // guess.innerHTML = i; - // guess.setAttribute('data-value', i); - // guess.addEventListener('click', Controls.guessClick) - // container.appendChild(guess); - // } - // }, + document.addEventListener('L-conn-open', this.msgJoin.bind(this)); - // guessClick: (evt) => { - // alert(evt.currentTarget.dataset.value) - // }, + // Message handlers: "Local message" and "Global message" + // document.addEventListener('G-move', this.onMoveIncrement.bind(this)); + // document.addEventListener('G-win', this.onMoveIncrement.bind(this)); + // document.addEventListener('G-start', this.msgStartGame.bind(this)); + // document.addEventListener('G-stop', this.msgStartGame.bind(this)); + // document.addEventListener('G-players', this.msgStartGame.bind(this)); <--- controls.playersUpdate(data.body) + + // document.addEventListener('G-walls', this.msgStartGame.bind(this)); + // document.addEventListener('G-robots', this.msgStartGame.bind(this)); + // document.addEventListener('G-guess', this.msgStartGame.bind(this)); <--- controls.onReceiveGuess(data.body); -Controls.prototype.playerAdd = function() { - const names = ["Biff", "Morty", "Herb", "Chester", "Lyle", "Cap", "Dale", "Ned", "Mindy"] - const r = Math.floor(Math.random() * names.length); + // document.addEventListener('L-move', this.onMoveIncrement.bind(this)); + + // document.addEventListener('L-conn-error', this.onConnectionError.bind(this)); + // document.addEventListener('L-skip-timer', this.msgStartGame.bind(this)); + // document.addEventListener('L-skip-timer', this.msgStartGame.bind(this)); + + // Click handlers + // document.getElementById('controls-moves-reset').addEventListener('click', this.onMoveReset.bind(this)); + // document.getElementById('controls-start-game').addEventListener('click', this.onStartGame.bind(this)); + // document.getElementById('controls-stop-game').addEventListener('click', this.onStopGame.bind(this)); + // document.getElementById('controls-regenerate-walls').addEventListener('click', this.onRegenWalls.bind(this)); + // document.getElementById('controls-reposition-robots').addEventListener('click', this.onRepositionRobots.bind(this)); + // document.getElementById('controls-timer-skip').addEventListener('click', this.onSkipTimer.bind(this)); +} - const rawInput = names[r] //prompt("What is your name?"); +//===== UI - const evt = new CustomEvent('playerAdd', { detail: rawInput }); - document.dispatchEvent(evt); -}; +Controls.prototype.drawGuesses = function() { + const container = document.getElementById('controls-guesses'); + container.querySelectorAll('.controls-guess').forEach(el => el.parentNode.removeChild(el)); -Controls.prototype.playerRemove = function(rawInput) { - alert('nope') + for (let i = 1; i <= 30; i++) { + const guess = document.createElement('div'); + guess.className = 'controls-guess'; + guess.innerHTML = i; + guess.setAttribute('data-value', i); + guess.addEventListener('click', this.onClickGuess.bind(this)) + container.appendChild(guess); + } }; -Controls.prototype.playersUpdate = function(names) { - const container = document.getElementById('controls-players'); - const keys = Object.keys(names); +Controls.prototype.showWaiting = function() { + document.getElementById('controls-start').parentNode.style.display = ''; + document.getElementById('controls-walls').parentNode.style.display = ''; + document.getElementById('controls-robots').parentNode.style.display = ''; - if (keys.length > 0) { - const nobody = document.getElementById('controls-players-nobody'); - nobody.parentNode.removeChild(nobody); - } - - keys.forEach(connectionId => { - const id = `player-${connectionId}`; - - if (document.getElementById(id)) { - return; - } - - const n = document.createElement('div'); - n.id = id; - n.innerHTML = names[connectionId]; - n.className = 'controls-player'; - container.appendChild(n) - }); - - // container.querySelectorAll('.controls-player').forEach(el => { - // if (!names[el.id]) { - // container.removeChild(el); - // } - // }) + document.getElementById('controls-stop').parentNode.style.display = 'none'; + // document.getElementById('controls-moves-reset').parentNode.style.display = 'none'; + // document.getElementById('controls-timer-skip').parentNode.style.display = 'none'; + // document.getElementById('controls-guesses').parentNode.style.display = 'none'; }; -Controls.prototype.onMoveIncrement = function() { - this.moves++; - document.getElementById('controls-moves').innerHTML = this.moves; -}; -Controls.prototype.onMoveReset = function() { - this.moves = 0; - document.getElementById('controls-moves').innerHTML = this.moves; +//===== Message handlers - const event = new Event('board-reset'); - document.dispatchEvent(event); +Controls.prototype.msgJoin = function() { + this.showWaiting(); }; -Controls.prototype.onStartNextGame = function() { - const evt = new Event('board-reset'); - document.dispatchEvent(evt); -} - -Controls.prototype.onRegenWalls = function() { - const evt = new Event('regenerateWalls'); - document.dispatchEvent(evt); -} +// Controls.prototype.playersUpdate = function(names) { +// const container = document.getElementById('controls-players'); +// const keys = Object.keys(names); -Controls.prototype.onRepositionRobots = function() { - const evt = new Event('repositionRobots'); - document.dispatchEvent(evt); -} \ No newline at end of file +// if (keys.length > 0) { +// const nobody = document.getElementById('controls-players-nobody'); +// nobody.parentNode.removeChild(nobody); +// } + +// keys.forEach(connectionId => { +// const id = `player-${connectionId}`; + +// if (document.getElementById(id)) { +// return; +// } + +// const n = document.createElement('div'); +// n.id = id; +// n.innerHTML = names[connectionId]; +// n.className = 'controls-player'; +// container.appendChild(n) +// }); +// console.log(names) +// this.names = names; + +// // container.querySelectorAll('.controls-player').forEach(el => { +// // if (!names[el.id]) { +// // container.removeChild(el); +// // } +// // }) +// }; + +// Controls.prototype.onReceiveGuess = function(message) { +// console.log(this.names[message.id] + ' has a solution') +// } + +// Controls.prototype.onClickGuess = function(evt) { +// const e = new CustomEvent('guess', { detail: { moves: evt.currentTarget.dataset.value } }); +// document.dispatchEvent(e); +// } + +// Controls.prototype.onMoveIncrement = function() { +// this.moves++; +// document.getElementById('controls-moves').innerHTML = this.moves; +// }; + +// Controls.prototype.onMoveReset = function() { +// this.moves = 0; +// document.getElementById('controls-moves').innerHTML = this.moves; + +// const event = new Event('board-reset'); +// document.dispatchEvent(event); +// }; + +// Controls.prototype.onStartGame = function() { +// this.setUi('gameStarted'); + +// const evt = new Event('startGame'); +// document.dispatchEvent(evt); +// } + +// Controls.prototype.onStopGame = function() { +// this.setUi('gameStopped'); + +// const evt = new Event('stopGame'); +// document.dispatchEvent(evt); +// } + +// Controls.prototype.onRegenWalls = function() { +// const evt = new Event('regenerateWalls'); +// document.dispatchEvent(evt); +// } + +// Controls.prototype.onRepositionRobots = function() { +// const evt = new Event('repositionRobots'); +// document.dispatchEvent(evt); +// } + +// Controls.prototype.setUi = function(state) { +// switch(state) { +// case 'gameStarted': +// document.getElementById('controls-start-round').parentNode.style.display = 'none'; +// document.getElementById('controls-regenerate-walls').parentNode.style.display = 'none'; +// document.getElementById('controls-reposition-robots').parentNode.style.display = 'none'; + +// document.getElementById('controls-stop-round').parentNode.style.display = ''; +// document.getElementById('controls-moves-reset').parentNode.style.display = ''; +// document.getElementById('controls-timer-skip').parentNode.style.display = ''; +// document.getElementById('controls-guesses').parentNode.style.display = ''; +// break; + +// case 'gameStopped': +// document.getElementById('controls-start-round').parentNode.style.display = ''; +// document.getElementById('controls-regenerate-walls').parentNode.style.display = ''; +// document.getElementById('controls-reposition-robots').parentNode.style.display = ''; + +// document.getElementById('controls-stop-round').parentNode.style.display = 'none'; +// document.getElementById('controls-moves-reset').parentNode.style.display = 'none'; +// document.getElementById('controls-timer-skip').parentNode.style.display = 'none'; +// document.getElementById('controls-guesses').parentNode.style.display = 'none'; +// break; +// } +// } \ No newline at end of file diff --git a/client/join.js b/client/join.js new file mode 100644 index 0000000..6167789 --- /dev/null +++ b/client/join.js @@ -0,0 +1,52 @@ +const Join = function() { + document.addEventListener('L-conn-error', this.onConnectionError.bind(this)); + document.addEventListener('L-conn-open', this.onConnectionOpen.bind(this)); + + document.getElementById('join-setup-start').addEventListener('click', this.onClickStart.bind(this)); + document.getElementById('join-setup-go').addEventListener('click', this.onClickStart.bind(this)); + document.getElementById('join-setup-back').addEventListener('click', this.onClickBack.bind(this)); + + this.showSetup(); +}; + +Join.prototype.showSetup = function() { + document.getElementById('join-setup').style.display = 'block'; + document.getElementById('join-connect').style.display = 'none'; + document.getElementById('join-error').style.display = 'none'; +}; + +Join.prototype.showLoad = function() { + document.getElementById('join-setup').style.display = 'none'; + document.getElementById('join-connect').style.display = 'block'; + document.getElementById('join-error').style.display = 'none'; +}; + +Join.prototype.showError = function() { + document.getElementById('join-setup').style.display = 'none'; + document.getElementById('join-connect').style.display = 'none'; + document.getElementById('join-error').style.display = 'block'; +}; + +Join.prototype.onClickBack = function() { + this.showSetup(); +}; + +Join.prototype.onClickGo = function() { + this.showLoad(); +}; + +Join.prototype.onClickStart = function() { + this.showLoad(); + + const evt = new Event('L-join'); + document.dispatchEvent(evt); +}; + +Join.prototype.onConnectionError = function() { + this.showError(); +}; + +Join.prototype.onConnectionOpen = function() { + document.getElementById('join').style.display = 'none'; + this.showSetup(); +}; \ No newline at end of file diff --git a/client/settings.js b/client/settings.js deleted file mode 100644 index fed6df2..0000000 --- a/client/settings.js +++ /dev/null @@ -1,3 +0,0 @@ -const Settings = function() { - this.squaresPerSide = 20; -} \ No newline at end of file diff --git a/content.css b/content.css new file mode 100644 index 0000000..f7e3896 --- /dev/null +++ b/content.css @@ -0,0 +1,53 @@ +#content-container { + background-color: #28313b; + background-image: linear-gradient(315deg, #28313b 0%, #1A2026 74%); + bottom: 0; + left: 0; + position: absolute; + right: 0; + top: 0; + z-index: 0; +} + +.content-square { + background: #ddd; + border-style: solid; + border-color: #aaa; + border-width: 0 1px 1px 0; + position: absolute; +} + +.content-wall-x { + background: #222; + height: 8px; + margin-top: -4px; + position: absolute; +} + +.content-wall-y { + background: #222; + margin-left: -4px; + position: absolute; + width: 8px; +} + +.content-robot { + position: absolute; + transition: left 0.4s cubic-bezier(0,1,.5,1), top 0.4s cubic-bezier(0,1,.5,1); +} + +.content-arrows { + transition: left 0.4s cubic-bezier(0,1,.5,1), top 0.4s cubic-bezier(0,1,.5,1); +} + +.content-arrow { + color: #aaa; + cursor: pointer; + position: absolute; + text-align: center; + user-select: none; +} + +.content-arrow:hover { + color: #000; +} \ No newline at end of file diff --git a/controls.css b/controls.css new file mode 100644 index 0000000..d866b42 --- /dev/null +++ b/controls.css @@ -0,0 +1,105 @@ +#controls-container { + background: #e7e7e7; + border: solid #e7e7e7; + border-width: 0 10px; + bottom: 0; + left: 20px; + position: absolute; + top: 0; + width: 300px; + z-index: 1; +} + +.controls-title { + background-color: #639978; + background-image: url('sprite-robots.png'); + /*color: #fff;*/ + font-size: 12px; + line-height: 48px; + margin-bottom: 24px; + text-align: center; +} + +.controls-subtitle { + background-color: #4D3243; + background-image: linear-gradient(90deg, #4D3243, #3C2132); + color: #fff; + padding: 12px; + margin: 24px 0 12px 0; +} + +.controls-alert { + background: #21dfae; + color: #222; + padding: 12px; + margin: 24px 0 12px 0; +} + +.controls-row { + align-items: center; + display: flex; + flex-direction: row; + padding: 8px; +} + +.controls-row :nth-child(2) { + flex: 1; + margin: 0 8px; + width: 100%; +} + +#controls-players { +} + +.controls-player { + padding: 8px; +} + + +#controls-local { +} + +.controls-guess { + background: none; + cursor: pointer; + float: left; + font-size: 12px; + height: 30px; + line-height: 30px; + text-align: center; + width: 30px; +} + +.controls-guess:hover { + background: #21dfae; +} + +#controls-footer { + background: #9A748C; + bottom: 0; + left: 0; + padding: 24px; + position: absolute; + right: 0; +} + +.controls-button { + background: none; + border: 1px solid #888; + color: #444; + cursor: pointer; + font-size: 12px; + padding: 4px 8px; +} + +.controls-button:hover { + background: #21dfae; + border-color: #21dfae; + color: #222; +} + +#controls-start { + display: block; + margin: 0 auto; + padding: 4px 8px; +} \ No newline at end of file diff --git a/index.css b/index.css index 21c9a50..fed6d47 100644 --- a/index.css +++ b/index.css @@ -8,167 +8,13 @@ body { } /* -4D3243 +PALETTE: +21DFAE Aquamarine +4D3243 Plum +DE4F21 Fire + +EXPERIMENTAL: 9A748C 639699 364B4D */ - -#controls-container { - background: #e7e7e7; - border: solid #e7e7e7; - border-width: 0 10px; - bottom: 0; - left: 20px; - position: absolute; - top: 0; - width: 300px; - z-index: 1; -} - -.controls-title { - background-color: #639978; - background-image: url('sprite-robots.png'); - /*color: #fff;*/ - font-size: 12px; - line-height: 48px; - margin-bottom: 24px; - text-align: center; -} - -.controls-subtitle { - background-color: #4D3243; - background-image: linear-gradient(90deg, #4D3243, #3C2132); - color: #fff; - padding: 12px; - margin: 24px 0 12px 0; -} - -.controls-row { - align-items: center; - display: flex; - flex-direction: row; - padding: 8px; -} - -.controls-row :nth-child(2) { - flex: 1; - margin: 0 8px; - width: 100%; -} - -.controls-button { - background: none; - border: 1px solid #888; - color: #444; - cursor: pointer; - font-size: 12px; - padding: 4px 8px; -} - -.controls-button:hover { - background: #639699; - border-color: #639699; - color: #fff; -} - -#controls-start { - display: block; - margin: 0 auto; - padding: 4px 8px; -} - -.controls-room-error { - background: #e00000; - color: #fff; - margin: 4px 0; - padding: 8px; -} - -#controls-players { -} - -.controls-player { - padding: 8px; -} - - -#controls-guesses { -} - -.controls-guess { - background: yellow; - float: left; - font-size: 12px; - height: 30px; - line-height: 30px; - text-align: center; - width: 30px; -} - -.controls-guess:hover { - background: orange; -} - -#controls-footer { - background: #9A748C; - bottom: 0; - left: 0; - padding: 24px; - position: absolute; - right: 0; -} - -#content-container { - background-color: #28313b; - background-image: linear-gradient(315deg, #28313b 0%, #1A2026 74%); - bottom: 0; - left: 0; - position: absolute; - right: 0; - top: 0; - z-index: 0; -} - -.content-square { - background: #ddd; - border-style: solid; - border-color: #aaa; - border-width: 0 1px 1px 0; - position: absolute; -} - -.content-wall-x { - background: #222; - height: 8px; - margin-top: -4px; - position: absolute; -} - -.content-wall-y { - background: #222; - margin-left: -4px; - position: absolute; - width: 8px; -} - -.content-robot { - position: absolute; - transition: left 0.4s cubic-bezier(0,1,.5,1), top 0.4s cubic-bezier(0,1,.5,1); -} - -.content-arrows { - transition: left 0.4s cubic-bezier(0,1,.5,1), top 0.4s cubic-bezier(0,1,.5,1); -} - -.content-arrow { - color: #aaa; - cursor: pointer; - position: absolute; - text-align: center; - user-select: none; -} - -.content-arrow:hover { - color: #000; -} \ No newline at end of file diff --git a/index.html b/index.html index 7c87e5f..ff141cc 100644 --- a/index.html +++ b/index.html @@ -3,43 +3,64 @@
-