From 34551788c7acd134ca16eb119333759d374447de Mon Sep 17 00:00:00 2001 From: Dan Barber Date: Tue, 5 Jan 2021 13:09:00 -0500 Subject: [PATCH 01/24] Render the initial board in Phoenix --- assets/css/components/_board.scss | 39 +++++++++++++++++-- assets/css/components/_square.scss | 25 +----------- lib/chess_web/templates/game/_board.html.eex | 35 +++++++++++++++++ lib/chess_web/templates/game/_square.html.eex | 5 +++ lib/chess_web/templates/game/show.html.eex | 25 +++++++++++- lib/chess_web/views/game_view.ex | 13 +++++++ 6 files changed, 114 insertions(+), 28 deletions(-) create mode 100644 lib/chess_web/templates/game/_board.html.eex create mode 100644 lib/chess_web/templates/game/_square.html.eex diff --git a/assets/css/components/_board.scss b/assets/css/components/_board.scss index 5d0ef5f..211da09 100644 --- a/assets/css/components/_board.scss +++ b/assets/css/components/_board.scss @@ -58,6 +58,14 @@ display: flex; flex-direction: row; } + + .board__body { + flex-direction: column-reverse; + } + + .board__row { + flex-direction: row; + } } .board--player-is-black { @@ -70,20 +78,45 @@ display: flex; flex-direction: row-reverse; } + + .board__body { + flex-direction: column; + } + + .board__row { + flex-direction: row-reverse; + } } .board__body { background: $background-color; border: 0.25rem solid $foreground-color; border-radius: calc(var(--board-size) / 100); - display: grid; - grid-template-columns: repeat(8, 1fr); - grid-template-rows: repeat(8, 1fr); + display: flex; + flex-direction: column; height: 100%; padding: 1%; width: 100%; } +.board__row { + display: flex; + flex-grow: 1; + + @include odd-between(1, 8) { + .square { + @include odd-between(1, 8) { @extend %square--black; } + @include even-between(1, 8) { @extend %square--white; } + } + } + @include even-between(1, 8) { + .square { + @include odd-between(1, 8) { @extend %square--white; } + @include even-between(1, 8) { @extend %square--black; } + } + } +} + .board__rank-labels { display: none; height: 90%; diff --git a/assets/css/components/_square.scss b/assets/css/components/_square.scss index ccbaf4c..52c3d53 100644 --- a/assets/css/components/_square.scss +++ b/assets/css/components/_square.scss @@ -57,36 +57,13 @@ border-radius: 4%; margin: 0.5px; position: relative; + flex-grow: 1; // This is to ensure the squares can be clicked on in PhantomJS // TODO: Figure out why we need this min-height: 20px; min-width: 20px; - @include odd-between(1, 8) { @extend %square--white; } - @include even-between(1, 8) { @extend %square--black; } - - @include odd-between(9, 16) { @extend %square--black; } - @include even-between(9, 16) { @extend %square--white; } - - @include odd-between(17, 24) { @extend %square--white; } - @include even-between(17, 24) { @extend %square--black; } - - @include odd-between(25, 32) { @extend %square--black; } - @include even-between(25, 32) { @extend %square--white; } - - @include odd-between(33, 40) { @extend %square--white; } - @include even-between(33, 40) { @extend %square--black; } - - @include odd-between(41, 48) { @extend %square--black; } - @include even-between(41, 48) { @extend %square--white; } - - @include odd-between(49, 56) { @extend %square--white; } - @include even-between(49, 56) { @extend %square--black; } - - @include odd-between(57, 64) { @extend %square--black; } - @include even-between(57, 64) { @extend %square--white; } - &::before { background-position: center; background-repeat: no-repeat; diff --git a/lib/chess_web/templates/game/_board.html.eex b/lib/chess_web/templates/game/_board.html.eex new file mode 100644 index 0000000..e7c94a5 --- /dev/null +++ b/lib/chess_web/templates/game/_board.html.eex @@ -0,0 +1,35 @@ +
+
+
1
+
2
+
3
+
4
+
5
+
6
+
7
+
8
+
+
+
a
+
b
+
c
+
d
+
e
+
f
+
g
+
h
+
+
+ <%= for rank <- 0..7 do %> +
+ <%= for file <- 0..7 do %> + <%= render "_square.html", + rank: rank, + file: file, + piece: @game.board["#{file},#{rank}"] %> + <% end %> +
+ <% end %> +
+
+
diff --git a/lib/chess_web/templates/game/_square.html.eex b/lib/chess_web/templates/game/_square.html.eex new file mode 100644 index 0000000..937c827 --- /dev/null +++ b/lib/chess_web/templates/game/_square.html.eex @@ -0,0 +1,5 @@ +<%= if @piece == nil do %> +
+<% else %> +
square--<%= @piece["colour"] %>">
+<% end %> diff --git a/lib/chess_web/templates/game/show.html.eex b/lib/chess_web/templates/game/show.html.eex index 96e010f..87adea1 100644 --- a/lib/chess_web/templates/game/show.html.eex +++ b/lib/chess_web/templates/game/show.html.eex @@ -1,2 +1,25 @@ -
+
+
+ <%= render "_board.html", conn: @conn, game: @game %> +
+

Playing Zaphod Beeblebrox offline

+
+
+ + + + + + + + + + + + + + +
Move no.WhiteBlack
1.e4
+
+
diff --git a/lib/chess_web/views/game_view.ex b/lib/chess_web/views/game_view.ex index 2a789ab..04c21a8 100644 --- a/lib/chess_web/views/game_view.ex +++ b/lib/chess_web/views/game_view.ex @@ -44,6 +44,19 @@ defmodule ChessWeb.GameView do (current_user(conn).id == game.user_id && "white") || "black" end + def files(conn, game) do + ranks(conn, game) + |> Enum.reverse + end + + def ranks(conn, game) do + if game.user_id == current_user(conn).id do + 7..0 + else + 0..7 + end + end + def player(game, user_id) do if game.user_id == user_id do "white" From 2f561c28fedd116bb867d748440372255b551478 Mon Sep 17 00:00:00 2001 From: Dan Barber Date: Thu, 7 Jan 2021 10:53:32 -0500 Subject: [PATCH 02/24] Few rendering fix ups --- lib/chess_web/templates/game/_board.html.eex | 8 ++++---- lib/chess_web/templates/game/show.html.eex | 5 ++++- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/lib/chess_web/templates/game/_board.html.eex b/lib/chess_web/templates/game/_board.html.eex index e7c94a5..fa55c3c 100644 --- a/lib/chess_web/templates/game/_board.html.eex +++ b/lib/chess_web/templates/game/_board.html.eex @@ -1,4 +1,4 @@ -
+
1
2
@@ -24,9 +24,9 @@
<%= for file <- 0..7 do %> <%= render "_square.html", - rank: rank, - file: file, - piece: @game.board["#{file},#{rank}"] %> + rank: rank, + file: file, + piece: @game.board["#{file},#{rank}"] %> <% end %>
<% end %> diff --git a/lib/chess_web/templates/game/show.html.eex b/lib/chess_web/templates/game/show.html.eex index 87adea1..2e4b490 100644 --- a/lib/chess_web/templates/game/show.html.eex +++ b/lib/chess_web/templates/game/show.html.eex @@ -2,7 +2,10 @@
<%= render "_board.html", conn: @conn, game: @game %>
-

Playing Zaphod Beeblebrox offline

+

+ Playing <%= opponent(@game, current_user(@conn).id).name %> + offline +

From d2074ade11226ab395dcb6373384fc8e6cd6c5cd Mon Sep 17 00:00:00 2001 From: Dan Barber Date: Thu, 7 Jan 2021 10:54:06 -0500 Subject: [PATCH 03/24] Install LiveView --- assets/js/app.js | 11 + assets/package.json | 5 +- assets/yarn-error.log | 734 ++++++++++++++++++ assets/yarn.lock | 15 +- config/config.exs | 3 +- lib/chess_web.ex | 40 + lib/chess_web/endpoint.ex | 8 +- lib/chess_web/router.ex | 2 +- lib/chess_web/templates/layout/_head.html.eex | 1 + mix.lock | 6 +- 10 files changed, 810 insertions(+), 15 deletions(-) create mode 100644 assets/yarn-error.log diff --git a/assets/js/app.js b/assets/js/app.js index 210bb1d..6d1de0a 100644 --- a/assets/js/app.js +++ b/assets/js/app.js @@ -1,5 +1,16 @@ "use strict"; +import {Socket} from "phoenix"; +import LiveSocket from "phoenix_live_view"; + +let csrfToken = document + .querySelector("meta[name='csrf-token']").getAttribute("content"); +let liveSocket = new LiveSocket( + "/live", + Socket, + {params: {_csrf_token: csrfToken}} +); + import "@babel/polyfill"; import "phoenix_html"; diff --git a/assets/package.json b/assets/package.json index 285e35d..522a7cc 100644 --- a/assets/package.json +++ b/assets/package.json @@ -13,8 +13,9 @@ "gettext.js": "^1.0.0", "immutable": "^3.8.2", "lodash": "^4.17.21", - "phoenix": "file:../deps/phoenix", - "phoenix_html": "file:../deps/phoenix_html", + "phoenix": "^1.7.0-rc.2", + "phoenix_html": "^3.2.0", + "phoenix_live_view": "^0.18.11", "react": "^17.0.2", "react-dom": "^17.0.2", "react-redux": "^7.2.4", diff --git a/assets/yarn-error.log b/assets/yarn-error.log new file mode 100644 index 0000000..67c9606 --- /dev/null +++ b/assets/yarn-error.log @@ -0,0 +1,734 @@ +Arguments: + /Users/danbarber/.asdf/installs/nodejs/16.14.0/bin/node /Users/danbarber/.asdf/installs/yarn/1.22.10/bin/yarn.js add phoenix phoenix_html phoenix_live_view + +PATH: + /Users/danbarber/.asdf/plugins/nodejs/shims:/Users/danbarber/.asdf/installs/nodejs/16.14.0/bin:/Users/danbarber/.asdf/installs/yarn/1.22.10/bin:/Users/danbarber/.bin:/usr/local/share/npm/bin:.git/safe/../../bin:/Users/danbarber/.asdf/shims:/opt/homebrew/bin/../opt/asdf/libexec/bin:/usr/local/sbin:/opt/homebrew/bin:/opt/homebrew/sbin:/usr/local/bin:/System/Cryptexes/App/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Applications/VMware Fusion.app/Contents/Public:/usr/local/zfs/bin:/opt/X11/bin:/Library/Apple/usr/bin:/Applications/Wireshark.app/Contents/MacOS:/Applications/kitty.app/Contents/MacOS:/Users/danbarber/.fzf/bin + +Yarn version: + 1.22.10 + +Node version: + 16.14.0 + +Platform: + darwin arm64 + +Trace: + Error: ENOENT: no such file or directory, open '/Users/danbarber/Library/Caches/Yarn/v6/npm-esbuild-linux-arm64-0.14.21-e05599ea6253b58394157da162d856f3ead62f9e-integrity/node_modules/esbuild-linux-arm64/.yarn-metadata.json' + +npm manifest: + { + "repository": {}, + "description": " ", + "license": "MIT", + "scripts": { + "deploy": "cd .. && mix assets.deploy && rm -f _build/esbuild" + }, + "dependencies": { + "@babel/polyfill": "^7.12.1", + "axios": "^0.21.0", + "classnames": "^2.3.1", + "esbuild": "^0.14.21", + "gettext.js": "^1.0.0", + "immutable": "^3.8.2", + "lodash": "^4.17.21", + "react": "^17.0.2", + "react-dom": "^17.0.2", + "react-redux": "^7.2.4", + "redux": "^4.1.0", + "redux-watch": "^1.2.0", + "url-loader": "^4.1.1" + }, + "devDependencies": { + "css-loader": "^5.2.6", + "mini-css-extract-plugin": "^1.6.0" + } + } + +yarn manifest: + No manifest + +Lockfile: + # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. + # yarn lockfile v1 + + + "@babel/polyfill@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/polyfill/-/polyfill-7.12.1.tgz#1f2d6371d1261bbd961f3c5d5909150e12d0bd96" + integrity sha512-X0pi0V6gxLi6lFZpGmeNa4zxtwEmCs42isWLNjZZDE0Y8yVfgu0T2OAHlzBbdYlqbW/YXVvoBHpATEM+goCj8g== + dependencies: + core-js "^2.6.5" + regenerator-runtime "^0.13.4" + + "@babel/runtime@^7.12.1", "@babel/runtime@^7.9.2": + version "7.14.6" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.14.6.tgz#535203bc0892efc7dec60bdc27b2ecf6e409062d" + integrity sha512-/PCB2uJ7oM44tz8YhC4Z/6PeOKXp4K588f+5M3clr1M4zbqztlo0XEfJ2LEzj/FgwfgGcIdl8n7YYjTCI0BYwg== + dependencies: + regenerator-runtime "^0.13.4" + + "@types/hoist-non-react-statics@^3.3.0": + version "3.3.1" + resolved "https://registry.yarnpkg.com/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz#1124aafe5118cb591977aeb1ceaaed1070eb039f" + integrity sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA== + dependencies: + "@types/react" "*" + hoist-non-react-statics "^3.3.0" + + "@types/json-schema@^7.0.6": + version "7.0.7" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.7.tgz#98a993516c859eb0d5c4c8f098317a9ea68db9ad" + integrity sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA== + + "@types/prop-types@*": + version "15.7.3" + resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.3.tgz#2ab0d5da2e5815f94b0b9d4b95d1e5f243ab2ca7" + integrity sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw== + + "@types/react-redux@^7.1.16": + version "7.1.16" + resolved "https://registry.yarnpkg.com/@types/react-redux/-/react-redux-7.1.16.tgz#0fbd04c2500c12105494c83d4a3e45c084e3cb21" + integrity sha512-f/FKzIrZwZk7YEO9E1yoxIuDNRiDducxkFlkw/GNMGEnK9n4K8wJzlJBghpSuOVDgEUHoDkDF7Gi9lHNQR4siw== + dependencies: + "@types/hoist-non-react-statics" "^3.3.0" + "@types/react" "*" + hoist-non-react-statics "^3.3.0" + redux "^4.0.0" + + "@types/react@*": + version "17.0.11" + resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.11.tgz#67fcd0ddbf5a0b083a0f94e926c7d63f3b836451" + integrity sha512-yFRQbD+whVonItSk7ZzP/L+gPTJVBkL/7shLEF+i9GC/1cV3JmUxEQz6+9ylhUpWSDuqo1N9qEvqS6vTj4USUA== + dependencies: + "@types/prop-types" "*" + "@types/scheduler" "*" + csstype "^3.0.2" + + "@types/scheduler@*": + version "0.16.1" + resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.1.tgz#18845205e86ff0038517aab7a18a62a6b9f71275" + integrity sha512-EaCxbanVeyxDRTQBkdLb3Bvl/HK7PBK6UJjsSixB0iHKoWxE5uu2Q/DgtpOhPIojN0Zl1whvOd7PoHs2P0s5eA== + + ajv-keywords@^3.5.2: + version "3.5.2" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" + integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== + + ajv@^6.12.5: + version "6.12.6" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" + integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== + 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" + + ansi-styles@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-1.0.0.tgz#cb102df1c56f5123eab8b67cd7b98027a0279178" + integrity sha1-yxAt8cVvUSPquLZ817mAJ6AnkXg= + + axios@^0.21.0: + version "0.21.1" + resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.1.tgz#22563481962f4d6bde9a76d516ef0e5d3c09b2b8" + integrity sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA== + dependencies: + follow-redirects "^1.10.0" + + big.js@^5.2.2: + version "5.2.2" + resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" + integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ== + + chalk@~0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-0.4.0.tgz#5199a3ddcd0c1efe23bc08c1b027b06176e0c64f" + integrity sha1-UZmj3c0MHv4jvAjBsCewYXbgxk8= + dependencies: + ansi-styles "~1.0.0" + has-color "~0.1.0" + strip-ansi "~0.1.0" + + classnames@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.3.1.tgz#dfcfa3891e306ec1dad105d0e88f4417b8535e8e" + integrity sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA== + + colorette@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.2.2.tgz#cbcc79d5e99caea2dbf10eb3a26fd8b3e6acfa94" + integrity sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w== + + core-js@^2.6.5: + version "2.6.12" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.12.tgz#d9333dfa7b065e347cc5682219d6f690859cc2ec" + integrity sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ== + + css-loader@^5.2.6: + version "5.2.6" + resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-5.2.6.tgz#c3c82ab77fea1f360e587d871a6811f4450cc8d1" + integrity sha512-0wyN5vXMQZu6BvjbrPdUJvkCzGEO24HC7IS7nW4llc6BBFC+zwR9CKtYGv63Puzsg10L/o12inMY5/2ByzfD6w== + dependencies: + icss-utils "^5.1.0" + loader-utils "^2.0.0" + postcss "^8.2.15" + postcss-modules-extract-imports "^3.0.0" + postcss-modules-local-by-default "^4.0.0" + postcss-modules-scope "^3.0.0" + postcss-modules-values "^4.0.0" + postcss-value-parser "^4.1.0" + schema-utils "^3.0.0" + semver "^7.3.5" + + cssesc@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" + integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== + + csstype@^3.0.2: + version "3.0.8" + resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.0.8.tgz#d2266a792729fb227cd216fb572f43728e1ad340" + integrity sha512-jXKhWqXPmlUeoQnF/EhTtTl4C9SnrxSH/jZUih3jmO6lBKr99rP3/+FmrMj4EFpOXzMtXHAZkd3x0E6h6Fgflw== + + emojis-list@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78" + integrity sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q== + + encoding@^0.1.11: + version "0.1.13" + resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.13.tgz#56574afdd791f54a8e9b2785c0582a2d26210fa9" + integrity sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A== + dependencies: + iconv-lite "^0.6.2" + + esbuild-android-arm64@0.14.21: + version "0.14.21" + resolved "https://registry.yarnpkg.com/esbuild-android-arm64/-/esbuild-android-arm64-0.14.21.tgz#8842d0c3b7c81fbe2dc46ddb416ffd6eb822184b" + integrity sha512-Bqgld1TY0wZv8TqiQmVxQFgYzz8ZmyzT7clXBDZFkOOdRybzsnj8AZuK1pwcLVA7Ya6XncHgJqIao7NFd3s0RQ== + + esbuild-darwin-64@0.14.21: + version "0.14.21" + resolved "https://registry.yarnpkg.com/esbuild-darwin-64/-/esbuild-darwin-64-0.14.21.tgz#ec7df02ad88ecf7f8fc23a3ed7917e07dea0c9c9" + integrity sha512-j+Eg+e13djzyYINVvAbOo2/zvZ2DivuJJTaBrJnJHSD7kUNuGHRkHoSfFjbI80KHkn091w350wdmXDNSgRjfYQ== + + esbuild-darwin-arm64@0.14.21: + version "0.14.21" + resolved "https://registry.yarnpkg.com/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.21.tgz#0c2a977edec1ef54097ee56a911518c820d4e5e4" + integrity sha512-nDNTKWDPI0RuoPj5BhcSB2z5EmZJJAyRtZLIjyXSqSpAyoB8eyAKXl4lB8U2P78Fnh4Lh1le/fmpewXE04JhBQ== + + esbuild-freebsd-64@0.14.21: + version "0.14.21" + resolved "https://registry.yarnpkg.com/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.21.tgz#f5b5fc1d031286c3a0949d1bda7db774b7d0404e" + integrity sha512-zIurkCHXhxELiDZtLGiexi8t8onQc2LtuE+S7457H/pP0g0MLRKMrsn/IN4LDkNe6lvBjuoZZi2OfelOHn831g== + + esbuild-freebsd-arm64@0.14.21: + version "0.14.21" + resolved "https://registry.yarnpkg.com/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.21.tgz#a05cab908013e4992b31a675850b8c44eb468c0c" + integrity sha512-wdxMmkJfbwcN+q85MpeUEamVZ40FNsBa9mPq8tAszDn8TRT2HoJvVRADPIIBa9SWWwlDChIMjkDKAnS3KS/sPA== + + esbuild-linux-32@0.14.21: + version "0.14.21" + resolved "https://registry.yarnpkg.com/esbuild-linux-32/-/esbuild-linux-32-0.14.21.tgz#638d244cc58b951f447addb4bade628d126ef84b" + integrity sha512-fmxvyzOPPh2xiEHojpCeIQP6pXcoKsWbz3ryDDIKLOsk4xp3GbpHIEAWP0xTeuhEbendmvBDVKbAVv3PnODXLg== + + esbuild-linux-64@0.14.21: + version "0.14.21" + resolved "https://registry.yarnpkg.com/esbuild-linux-64/-/esbuild-linux-64-0.14.21.tgz#8eb634abee928be7e35b985fafbfef2f2e31397f" + integrity sha512-edZyNOv1ql+kpmlzdqzzDjRQYls+tSyi4QFi+PdBhATJFUqHsnNELWA9vMSzAaInPOEaVUTA5Ml28XFChcy4DA== + + esbuild-linux-arm64@0.14.21: + version "0.14.21" + resolved "https://registry.yarnpkg.com/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.21.tgz#e05599ea6253b58394157da162d856f3ead62f9e" + integrity sha512-t5qxRkq4zdQC0zXpzSB2bTtfLgOvR0C6BXYaRE/6/k8/4SrkZcTZBeNu+xGvwCU4b5dU9ST9pwIWkK6T1grS8g== + + esbuild-linux-arm@0.14.21: + version "0.14.21" + resolved "https://registry.yarnpkg.com/esbuild-linux-arm/-/esbuild-linux-arm-0.14.21.tgz#1ae1078231cf689d3ba894a32d3723c0be9b91fd" + integrity sha512-aSU5pUueK6afqmLQsbU+QcFBT62L+4G9hHMJDHWfxgid6hzhSmfRH9U/f+ymvxsSTr/HFRU4y7ox8ZyhlVl98w== + + esbuild-linux-mips64le@0.14.21: + version "0.14.21" + resolved "https://registry.yarnpkg.com/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.21.tgz#f05be62d126764e99b37edcac5bb49b78c7a8890" + integrity sha512-jLZLQGCNlUsmIHtGqNvBs3zN+7a4D9ckf0JZ+jQTwHdZJ1SgV9mAjbB980OFo66LoY+WeM7t3WEnq3FjI1zw4A== + + esbuild-linux-ppc64le@0.14.21: + version "0.14.21" + resolved "https://registry.yarnpkg.com/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.21.tgz#592c98d82dad7982268ef8deed858c4566f07ab1" + integrity sha512-4TWxpK391en2UBUw6GSrukToTDu6lL9vkm3Ll40HrI08WG3qcnJu7bl8e1+GzelDsiw1QmfAY/nNvJ6iaHRpCQ== + + esbuild-linux-riscv64@0.14.21: + version "0.14.21" + resolved "https://registry.yarnpkg.com/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.21.tgz#0db7bd6f10d8f9afea973a7d6bf87b449b864b7b" + integrity sha512-fElngqOaOfTsF+u+oetDLHsPG74vB2ZaGZUqmGefAJn3a5z9Z2pNa4WpVbbKgHpaAAy5tWM1m1sbGohj6Ki6+Q== + + esbuild-linux-s390x@0.14.21: + version "0.14.21" + resolved "https://registry.yarnpkg.com/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.21.tgz#254a9354d34c9d1b41a3e21d2ec9269cbbb2c5df" + integrity sha512-brleZ6R5fYv0qQ7ZBwenQmP6i9TdvJCB092c/3D3pTLQHBGHJb5zWgKxOeS7bdHzmLy6a6W7GbFk6QKpjyD6QA== + + esbuild-netbsd-64@0.14.21: + version "0.14.21" + resolved "https://registry.yarnpkg.com/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.21.tgz#4cb783d060b02bf3b897a9a12cce2b3b547726f8" + integrity sha512-nCEgsLCQ8RoFWVV8pVI+kX66ICwbPP/M9vEa0NJGIEB/Vs5sVGMqkf67oln90XNSkbc0bPBDuo4G6FxlF7PN8g== + + esbuild-openbsd-64@0.14.21: + version "0.14.21" + resolved "https://registry.yarnpkg.com/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.21.tgz#f886b93feefddbe573528fa4b421c9c6e2bc969b" + integrity sha512-h9zLMyVD0T73MDTVYIb/qUTokwI6EJH9O6wESuTNq6+XpMSr6C5aYZ4fvFKdNELW+Xsod+yDS2hV2JTUAbFrLA== + + esbuild-sunos-64@0.14.21: + version "0.14.21" + resolved "https://registry.yarnpkg.com/esbuild-sunos-64/-/esbuild-sunos-64-0.14.21.tgz#3829e4d57d4cb6950837fe90b0b67cdfb37cf13a" + integrity sha512-Kl+7Cot32qd9oqpLdB1tEGXEkjBlijrIxMJ0+vlDFaqsODutif25on0IZlFxEBtL2Gosd4p5WCV1U7UskNQfXA== + + esbuild-windows-32@0.14.21: + version "0.14.21" + resolved "https://registry.yarnpkg.com/esbuild-windows-32/-/esbuild-windows-32-0.14.21.tgz#b858a22d1a82e53cdc59310cd56294133f7a95e7" + integrity sha512-V7vnTq67xPBUCk/9UtlolmQ798Ecjdr1ZoI1vcSgw7M82aSSt0eZdP6bh5KAFZU8pxDcx3qoHyWQfHYr11f22A== + + esbuild-windows-64@0.14.21: + version "0.14.21" + resolved "https://registry.yarnpkg.com/esbuild-windows-64/-/esbuild-windows-64-0.14.21.tgz#7bb5a027d5720cf9caf18a4bedd11327208f1f12" + integrity sha512-kDgHjKOHwjfJDCyRGELzVxiP/RBJBTA+wyspf78MTTJQkyPuxH2vChReNdWc+dU2S4gIZFHMdP1Qrl/k22ZmaA== + + esbuild-windows-arm64@0.14.21: + version "0.14.21" + resolved "https://registry.yarnpkg.com/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.21.tgz#25df54521ad602c826b262ea2e7cc1fe80f5c2f5" + integrity sha512-8Sbo0zpzgwWrwjQYLmHF78f7E2xg5Ve63bjB2ng3V2aManilnnTGaliq2snYg+NOX60+hEvJHRdVnuIAHW0lVw== + + esbuild@^0.14.21: + version "0.14.21" + resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.14.21.tgz#b3e05f900f1c4394f596d60d63d9816468f0f671" + integrity sha512-7WEoNMBJdLN993dr9h0CpFHPRc3yFZD+EAVY9lg6syJJ12gc5fHq8d75QRExuhnMkT2DaRiIKFThRvDWP+fO+A== + optionalDependencies: + esbuild-android-arm64 "0.14.21" + esbuild-darwin-64 "0.14.21" + esbuild-darwin-arm64 "0.14.21" + esbuild-freebsd-64 "0.14.21" + esbuild-freebsd-arm64 "0.14.21" + esbuild-linux-32 "0.14.21" + esbuild-linux-64 "0.14.21" + esbuild-linux-arm "0.14.21" + esbuild-linux-arm64 "0.14.21" + esbuild-linux-mips64le "0.14.21" + esbuild-linux-ppc64le "0.14.21" + esbuild-linux-riscv64 "0.14.21" + esbuild-linux-s390x "0.14.21" + esbuild-netbsd-64 "0.14.21" + esbuild-openbsd-64 "0.14.21" + esbuild-sunos-64 "0.14.21" + esbuild-windows-32 "0.14.21" + esbuild-windows-64 "0.14.21" + esbuild-windows-arm64 "0.14.21" + + fast-deep-equal@^3.1.1: + version "3.1.3" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" + integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== + + fast-json-stable-stringify@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" + integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== + + follow-redirects@^1.10.0: + version "1.14.1" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.1.tgz#d9114ded0a1cfdd334e164e6662ad02bfd91ff43" + integrity sha512-HWqDgT7ZEkqRzBvc2s64vSZ/hfOceEol3ac/7tKwzuvEyWx3/4UegXh5oBOIotkGsObyk3xznnSRVADBgWSQVg== + + gettext-parser@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/gettext-parser/-/gettext-parser-1.1.0.tgz#2c5a6638d893934b9b55037d0ad82cb7004b2679" + integrity sha1-LFpmONiTk0ubVQN9CtgstwBLJnk= + dependencies: + encoding "^0.1.11" + + gettext.js@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/gettext.js/-/gettext.js-1.0.0.tgz#7fefb01512c134759c51166ab4d3db26a585ae1a" + integrity sha512-cpnxNL5C9SlD7ms/NSCuGsQdaVQmwCYn9MILWpYjSPMAkX4aD/5/qC+QgH4GCRY0OMEcSiVBsqgWMEoTcETggQ== + dependencies: + po2json "^0.4.0" + + has-color@~0.1.0: + version "0.1.7" + resolved "https://registry.yarnpkg.com/has-color/-/has-color-0.1.7.tgz#67144a5260c34fc3cca677d041daf52fe7b78b2f" + integrity sha1-ZxRKUmDDT8PMpnfQQdr1L+e3iy8= + + hoist-non-react-statics@^3.3.0, hoist-non-react-statics@^3.3.2: + version "3.3.2" + resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45" + integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw== + dependencies: + react-is "^16.7.0" + + iconv-lite@^0.6.2: + version "0.6.3" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501" + integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== + dependencies: + safer-buffer ">= 2.1.2 < 3.0.0" + + icss-utils@^5.0.0, icss-utils@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-5.1.0.tgz#c6be6858abd013d768e98366ae47e25d5887b1ae" + integrity sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA== + + immutable@^3.8.2: + version "3.8.2" + resolved "https://registry.yarnpkg.com/immutable/-/immutable-3.8.2.tgz#c2439951455bb39913daf281376f1530e104adf3" + integrity sha1-wkOZUUVbs5kT2vKBN28VMOEErfM= + + "js-tokens@^3.0.0 || ^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + + json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== + + json5@^2.1.2: + version "2.2.0" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.0.tgz#2dfefe720c6ba525d9ebd909950f0515316c89a3" + integrity sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA== + dependencies: + minimist "^1.2.5" + + loader-utils@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.0.tgz#e4cace5b816d425a166b5f097e10cd12b36064b0" + integrity sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ== + dependencies: + big.js "^5.2.2" + emojis-list "^3.0.0" + json5 "^2.1.2" + + lodash@^4.17.21: + version "4.17.21" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== + + loose-envify@^1.1.0, loose-envify@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" + integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== + dependencies: + js-tokens "^3.0.0 || ^4.0.0" + + lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + + mime-db@1.48.0: + version "1.48.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.48.0.tgz#e35b31045dd7eada3aaad537ed88a33afbef2d1d" + integrity sha512-FM3QwxV+TnZYQ2aRqhlKBMHxk10lTbMt3bBkMAp54ddrNeVSfcQYOOKuGuy3Ddrm38I04If834fOUSq1yzslJQ== + + mime-types@^2.1.27: + version "2.1.31" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.31.tgz#a00d76b74317c61f9c2db2218b8e9f8e9c5c9e6b" + integrity sha512-XGZnNzm3QvgKxa8dpzyhFTHmpP3l5YNusmne07VUOXxou9CqUqYa/HBy124RqtVh/O2pECas/MOcsDgpilPOPg== + dependencies: + mime-db "1.48.0" + + mini-css-extract-plugin@^1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-1.6.0.tgz#b4db2525af2624899ed64a23b0016e0036411893" + integrity sha512-nPFKI7NSy6uONUo9yn2hIfb9vyYvkFu95qki0e21DQ9uaqNKDP15DGpK0KnV6wDroWxPHtExrdEwx/yDQ8nVRw== + dependencies: + loader-utils "^2.0.0" + schema-utils "^3.0.0" + webpack-sources "^1.1.0" + + minimist@^1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" + integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== + + nanoid@^3.1.23: + version "3.1.23" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.23.tgz#f744086ce7c2bc47ee0a8472574d5c78e4183a81" + integrity sha512-FiB0kzdP0FFVGDKlRLEQ1BgDzU87dy5NnzjeW9YZNt+/c3+q82EQDUwniSAUxp/F0gFNI1ZhKU1FqYsMuqZVnw== + + nomnom@1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/nomnom/-/nomnom-1.8.1.tgz#2151f722472ba79e50a76fc125bb8c8f2e4dc2a7" + integrity sha1-IVH3Ikcrp55Qp2/BJbuMjy5Nwqc= + dependencies: + chalk "~0.4.0" + underscore "~1.6.0" + + object-assign@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= + + object-path@^0.11.5: + version "0.11.5" + resolved "https://registry.yarnpkg.com/object-path/-/object-path-0.11.5.tgz#d4e3cf19601a5140a55a16ad712019a9c50b577a" + integrity sha512-jgSbThcoR/s+XumvGMTMf81QVBmah+/Q7K7YduKeKVWL7N111unR2d6pZZarSk6kY/caeNxUDyxOvMWyzoU2eg== + + "phoenix@file:../deps/phoenix": + version "1.6.6" + + "phoenix_html@file:../deps/phoenix_html": + <<<<<<< HEAD + version "3.2.0" + ======= + version "2.14.3" + + "phoenix_live_view@file:../deps/phoenix_live_view": + version "0.15.3" + + picomatch@^2.2.1, picomatch@^2.2.3: + version "2.3.0" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.0.tgz#f1f061de8f6a4bf022892e2d128234fb98302972" + integrity sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw== + "phoenix_live_view@file:../deps/phoenix_live_view": + version "0.15.3" + + pify@^2.0.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" + integrity sha1-7RQaasBDqEnqWISY59yosVMw6Qw= + + pinkie-promise@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" + integrity sha1-ITXW36ejWMBprJsXh3YogihFD/o= + dependencies: + pinkie "^2.0.0" + + pinkie@^2.0.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" + integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA= + + pkg-dir@^4.1.0, pkg-dir@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" + integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== + dependencies: + find-up "^4.0.0" + >>>>>>> 7af5f8c (Install LiveView) + + po2json@^0.4.0: + version "0.4.5" + resolved "https://registry.yarnpkg.com/po2json/-/po2json-0.4.5.tgz#47bb2952da32d58a1be2f256a598eebc0b745118" + integrity sha1-R7spUtoy1Yob4vJWpZjuvAt0URg= + dependencies: + gettext-parser "1.1.0" + nomnom "1.8.1" + + postcss-modules-extract-imports@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz#cda1f047c0ae80c97dbe28c3e76a43b88025741d" + integrity sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw== + + postcss-modules-local-by-default@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.0.tgz#ebbb54fae1598eecfdf691a02b3ff3b390a5a51c" + integrity sha512-sT7ihtmGSF9yhm6ggikHdV0hlziDTX7oFoXtuVWeDd3hHObNkcHRo9V3yg7vCAY7cONyxJC/XXCmmiHHcvX7bQ== + dependencies: + icss-utils "^5.0.0" + postcss-selector-parser "^6.0.2" + postcss-value-parser "^4.1.0" + + postcss-modules-scope@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz#9ef3151456d3bbfa120ca44898dfca6f2fa01f06" + integrity sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg== + dependencies: + postcss-selector-parser "^6.0.4" + + postcss-modules-values@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz#d7c5e7e68c3bb3c9b27cbf48ca0bb3ffb4602c9c" + integrity sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ== + dependencies: + icss-utils "^5.0.0" + + postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4: + version "6.0.6" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.6.tgz#2c5bba8174ac2f6981ab631a42ab0ee54af332ea" + integrity sha512-9LXrvaaX3+mcv5xkg5kFwqSzSH1JIObIx51PrndZwlmznwXRfxMddDvo9gve3gVR8ZTKgoFDdWkbRFmEhT4PMg== + dependencies: + cssesc "^3.0.0" + util-deprecate "^1.0.2" + + postcss-value-parser@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz#443f6a20ced6481a2bda4fa8532a6e55d789a2cb" + integrity sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ== + + postcss@^8.2.15: + version "8.3.5" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.3.5.tgz#982216b113412bc20a86289e91eb994952a5b709" + integrity sha512-NxTuJocUhYGsMiMFHDUkmjSKT3EdH4/WbGF6GCi1NDGk+vbcUTun4fpbOqaPtD8IIsztA2ilZm2DhYCuyN58gA== + dependencies: + colorette "^1.2.2" + nanoid "^3.1.23" + source-map-js "^0.6.2" + + prop-types@^15.7.2: + version "15.7.2" + resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5" + integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ== + dependencies: + loose-envify "^1.4.0" + object-assign "^4.1.1" + react-is "^16.8.1" + + punycode@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" + integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== + + react-dom@^17.0.2: + version "17.0.2" + resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-17.0.2.tgz#ecffb6845e3ad8dbfcdc498f0d0a939736502c23" + integrity sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA== + dependencies: + loose-envify "^1.1.0" + object-assign "^4.1.1" + scheduler "^0.20.2" + + react-is@^16.13.1, react-is@^16.7.0, react-is@^16.8.1: + version "16.13.1" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" + integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== + + react-redux@^7.2.4: + version "7.2.4" + resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-7.2.4.tgz#1ebb474032b72d806de2e0519cd07761e222e225" + integrity sha512-hOQ5eOSkEJEXdpIKbnRyl04LhaWabkDPV+Ix97wqQX3T3d2NQ8DUblNXXtNMavc7DpswyQM6xfaN4HQDKNY2JA== + dependencies: + "@babel/runtime" "^7.12.1" + "@types/react-redux" "^7.1.16" + hoist-non-react-statics "^3.3.2" + loose-envify "^1.4.0" + prop-types "^15.7.2" + react-is "^16.13.1" + + react@^17.0.2: + version "17.0.2" + resolved "https://registry.yarnpkg.com/react/-/react-17.0.2.tgz#d0b5cc516d29eb3eee383f75b62864cfb6800037" + integrity sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA== + dependencies: + loose-envify "^1.1.0" + object-assign "^4.1.1" + + redux-watch@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/redux-watch/-/redux-watch-1.2.0.tgz#b3a745e15855ef72db0e06a60a4b2fe3676d79a7" + integrity sha512-Ws4Q+e5zFGMyy1H709c1Ws8apSd6MqoJRIzBDHbI4nikome/IZWVTYXdQNz+VJxPjyX/h2E+lYEo41fXgjCF8g== + dependencies: + object-path "^0.11.5" + + redux@^4.0.0, redux@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/redux/-/redux-4.1.0.tgz#eb049679f2f523c379f1aff345c8612f294c88d4" + integrity sha512-uI2dQN43zqLWCt6B/BMGRMY6db7TTY4qeHHfGeKb3EOhmOKjU3KdWvNLJyqaHRksv/ErdNH7cFZWg9jXtewy4g== + dependencies: + "@babel/runtime" "^7.9.2" + + regenerator-runtime@^0.13.4: + version "0.13.7" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz#cac2dacc8a1ea675feaabaeb8ae833898ae46f55" + integrity sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew== + + "safer-buffer@>= 2.1.2 < 3.0.0": + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + + scheduler@^0.20.2: + version "0.20.2" + resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.20.2.tgz#4baee39436e34aa93b4874bddcbf0fe8b8b50e91" + integrity sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ== + dependencies: + loose-envify "^1.1.0" + object-assign "^4.1.1" + + schema-utils@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.0.0.tgz#67502f6aa2b66a2d4032b4279a2944978a0913ef" + integrity sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA== + dependencies: + "@types/json-schema" "^7.0.6" + ajv "^6.12.5" + ajv-keywords "^3.5.2" + + semver@^7.3.5: + version "7.3.5" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" + integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ== + dependencies: + lru-cache "^6.0.0" + + source-list-map@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34" + integrity sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw== + + source-map-js@^0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-0.6.2.tgz#0bb5de631b41cfbda6cfba8bd05a80efdfd2385e" + integrity sha512-/3GptzWzu0+0MBQFrDKzw/DvvMTUORvgY6k6jd/VS6iCR4RDTKWH6v6WPwQoUO8667uQEf9Oe38DxAYWY5F/Ug== + + source-map@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + + strip-ansi@~0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-0.1.1.tgz#39e8a98d044d150660abe4a6808acf70bb7bc991" + integrity sha1-OeipjQRNFQZgq+SmgIrPcLt7yZE= + + underscore@~1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.6.0.tgz#8b38b10cacdef63337b8b24e4ff86d45aea529a8" + integrity sha1-izixDKze9jM3uLJOT/htRa6lKag= + + uri-js@^4.2.2: + version "4.4.1" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" + integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== + dependencies: + punycode "^2.1.0" + + url-loader@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/url-loader/-/url-loader-4.1.1.tgz#28505e905cae158cf07c92ca622d7f237e70a4e2" + integrity sha512-3BTV812+AVHHOJQO8O5MkWgZ5aosP7GnROJwvzLS9hWDj00lZ6Z0wNak423Lp9PBZN05N+Jk/N5Si8jRAlGyWA== + dependencies: + loader-utils "^2.0.0" + mime-types "^2.1.27" + schema-utils "^3.0.0" + + util-deprecate@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= + + webpack-sources@^1.1.0: + version "1.4.3" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.4.3.tgz#eedd8ec0b928fbf1cbfe994e22d2d890f330a933" + integrity sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ== + dependencies: + source-list-map "^2.0.0" + source-map "~0.6.1" + + yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== diff --git a/assets/yarn.lock b/assets/yarn.lock index c9d18b3..0383dc6 100644 --- a/assets/yarn.lock +++ b/assets/yarn.lock @@ -425,11 +425,20 @@ object-path@^0.11.5: resolved "https://registry.yarnpkg.com/object-path/-/object-path-0.11.5.tgz#d4e3cf19601a5140a55a16ad712019a9c50b577a" integrity sha512-jgSbThcoR/s+XumvGMTMf81QVBmah+/Q7K7YduKeKVWL7N111unR2d6pZZarSk6kY/caeNxUDyxOvMWyzoU2eg== -"phoenix@file:../deps/phoenix": - version "1.6.6" +phoenix@^1.7.0-rc.2: + version "1.7.0-rc.2" + resolved "https://registry.yarnpkg.com/phoenix/-/phoenix-1.7.0-rc.2.tgz#aca2e5af35c94922fdfe6bb11e860937088af937" + integrity sha512-05DaSo/ws2VtieY3Z6CJVx36DyhTil6/KesK1a4JlQPxYgNHZn7swv7R/R7etoN8SGtEjMV/a9HBkPS5wF/Xdg== -"phoenix_html@file:../deps/phoenix_html": +phoenix_html@^3.2.0: version "3.2.0" + resolved "https://registry.yarnpkg.com/phoenix_html/-/phoenix_html-3.2.0.tgz#4a30e5c331a72abababa1f3b81a9fe2c0e5a43d7" + integrity sha512-zv7PIZk0MPkF0ax8n465Q6w86+sGAy5cTem6KcbkUbdgxGc0y3WZmzkM2bSlYdSGbLEZfjXxos1G72xXsha6xA== + +phoenix_live_view@^0.18.11: + version "0.18.11" + resolved "https://registry.yarnpkg.com/phoenix_live_view/-/phoenix_live_view-0.18.11.tgz#5cc302df19372f516d7b90b939b85198649b55ef" + integrity sha512-p/mBu/O3iVLvAreUoDeSZ4/myQJJeR8BH7Yu9LVCMI2xe2IZ2mffxtDGJb0mxnJrUQa7p03HHNlKGXj7LSJDdg== po2json@^0.4.0: version "0.4.5" diff --git a/config/config.exs b/config/config.exs index da75f00..494e551 100644 --- a/config/config.exs +++ b/config/config.exs @@ -16,7 +16,8 @@ config :chess, ChessWeb.Endpoint, url: [host: "localhost"], secret_key_base: "iiTDTKorCWTFoeBgAkr35XZp22cNIM2RsmnHiHdzKAuSHXUGXx42z7lawAwiu1B1", render_errors: [view: ChessWeb.ErrorView, accepts: ~w(html json)], - pubsub_server: Chess.PubSub + pubsub_server: Chess.PubSub, + live_view: [signing_salt: "R3JjvjiRi64kjFCHqCJCfk7EY8hohfadgLqO/VUFRO8="] # Configures Elixir's Logger config :logger, :console, diff --git a/lib/chess_web.ex b/lib/chess_web.ex index 67a0a2c..8118a35 100644 --- a/lib/chess_web.ex +++ b/lib/chess_web.ex @@ -19,6 +19,7 @@ defmodule ChessWeb do def controller do quote do use Phoenix.Controller, namespace: ChessWeb + import Phoenix.LiveView.Controller alias Chess.Repo import Ecto @@ -38,6 +39,8 @@ defmodule ChessWeb do # Import convenience functions from controllers import Phoenix.Controller, only: [get_csrf_token: 0, get_flash: 2, view_module: 1] + import Phoenix.LiveView.Helpers + import ChessWeb.LiveHelpers # Use all HTML functionality (forms, tags, etc) use Phoenix.HTML @@ -50,9 +53,46 @@ defmodule ChessWeb do end end + + def live_view do + quote do + use Phoenix.LiveView, + layout: {ChessWeb.LayoutView, "live.html"} + + unquote(view_helpers()) + end + end + + def live_component do + quote do + use Phoenix.LiveComponent + + unquote(view_helpers()) + end + end + + defp view_helpers do + quote do + # Use all HTML functionality (forms, tags, etc) + use Phoenix.HTML + + # Import LiveView helpers (live_render, live_component, live_patch, etc) + import Phoenix.LiveView.Helpers + import ChessWeb.LiveHelpers + + # Import basic rendering functionality (render, render_layout, etc) + import Phoenix.View + + import ChessWeb.ErrorHelpers + import ChessWeb.Gettext + alias ChessWeb.Router.Helpers, as: Routes + end + end + def router do quote do use Phoenix.Router + import Phoenix.LiveView.Router end end diff --git a/lib/chess_web/endpoint.ex b/lib/chess_web/endpoint.ex index 3a0273e..e418114 100644 --- a/lib/chess_web/endpoint.ex +++ b/lib/chess_web/endpoint.ex @@ -7,6 +7,8 @@ defmodule ChessWeb.Endpoint do socket("/socket", ChessWeb.UserSocket) + socket("/live", Phoenix.LiveView.Socket, websocket: [connect_info: [session: @session_options]]) + # Serve at "/" the static files from "priv/static" directory. # # You should set gzip to true if you are running phoenix.digest @@ -45,11 +47,7 @@ defmodule ChessWeb.Endpoint do # The session will be stored in the cookie and signed, # this means its contents can be read but not tampered with. # Set :encryption_salt if you would also like to encrypt it. - plug(Plug.Session, - store: :cookie, - key: "_chess_key", - signing_salt: "9LqUhZTU" - ) + plug(Plug.Session, @session_options) plug(ChessWeb.Router) end diff --git a/lib/chess_web/router.ex b/lib/chess_web/router.ex index f588c99..d640d43 100644 --- a/lib/chess_web/router.ex +++ b/lib/chess_web/router.ex @@ -6,7 +6,7 @@ defmodule ChessWeb.Router do pipeline :browser do plug(:accepts, ["html"]) plug(:fetch_session) - plug(:fetch_flash) + plug(:fetch_live_flash) plug(:protect_from_forgery) plug(:put_secure_browser_headers) end diff --git a/lib/chess_web/templates/layout/_head.html.eex b/lib/chess_web/templates/layout/_head.html.eex index ca18082..9524c8b 100644 --- a/lib/chess_web/templates/layout/_head.html.eex +++ b/lib/chess_web/templates/layout/_head.html.eex @@ -4,6 +4,7 @@ + <%= csrf_meta_tag() %> <%= gettext "64squares" %> diff --git a/mix.lock b/mix.lock index b0ffea1..f999a84 100644 --- a/mix.lock +++ b/mix.lock @@ -1,7 +1,7 @@ %{ "argon2_elixir": {:hex, :argon2_elixir, "3.0.0", "fd4405f593e77b525a5c667282172dd32772d7c4fa58cdecdaae79d2713b6c5f", [:make, :mix], [{:comeonin, "~> 5.3", [hex: :comeonin, repo: "hexpm", optional: false]}, {:elixir_make, "~> 0.6", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm", "8b753b270af557d51ba13fcdebc0f0ab27a2a6792df72fd5a6cf9cfaffcedc57"}, "bamboo": {:hex, :bamboo, "2.3.0", "d2392a2cabe91edf488553d3c70638b532e8db7b76b84b0a39e3dfe492ffd6fc", [:mix], [{:hackney, ">= 1.15.2", [hex: :hackney, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:mime, "~> 1.4 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "dd0037e68e108fd04d0e8773921512c940e35d981e097b5793543e3b2f9cd3f6"}, - "bunt": {:hex, :bunt, "0.2.0", "951c6e801e8b1d2cbe58ebbd3e616a869061ddadcc4863d0a2182541acae9a38", [:mix], [], "hexpm", "7af5c7e09fe1d40f76c8e4f9dd2be7cebd83909f31fee7cd0e9eadc567da8353"}, + "bunt": {:hex, :bunt, "0.2.1", "e2d4792f7bc0ced7583ab54922808919518d0e57ee162901a16a1b6664ef3b14", [:mix], [], "hexpm", "a330bfb4245239787b15005e66ae6845c9cd524a288f0d141c148b02603777a5"}, "castore": {:hex, :castore, "0.1.22", "4127549e411bedd012ca3a308dede574f43819fe9394254ca55ab4895abfa1a2", [:mix], [], "hexpm", "c17576df47eb5aa1ee40cc4134316a99f5cad3e215d5c77b8dd3cfef12a22cac"}, "certifi": {:hex, :certifi, "2.9.0", "6f2a475689dd47f19fb74334859d460a2dc4e3252a3324bd2111b8f0429e7e21", [:rebar3], [], "hexpm", "266da46bdb06d6c6d35fde799bcb28d36d985d424ad7c08b5bb48f5b5cdd4641"}, "combine": {:hex, :combine, "0.10.0", "eff8224eeb56498a2af13011d142c5e7997a80c8f5b97c499f84c841032e429f", [:mix], [], "hexpm", "1b1dbc1790073076580d0d1d64e42eae2366583e7aecd455d1215b0d16f2451b"}, @@ -10,7 +10,7 @@ "cowboy": {:hex, :cowboy, "2.9.0", "865dd8b6607e14cf03282e10e934023a1bd8be6f6bacf921a7e2a96d800cd452", [:make, :rebar3], [{:cowlib, "2.11.0", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "1.8.0", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm", "2c729f934b4e1aa149aff882f57c6372c15399a20d54f65c8d67bef583021bde"}, "cowboy_telemetry": {:hex, :cowboy_telemetry, "0.4.0", "f239f68b588efa7707abce16a84d0d2acf3a0f50571f8bb7f56a15865aae820c", [:rebar3], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "7d98bac1ee4565d31b62d59f8823dfd8356a169e7fcbb83831b8a5397404c9de"}, "cowlib": {:hex, :cowlib, "2.11.0", "0b9ff9c346629256c42ebe1eeb769a83c6cb771a6ee5960bd110ab0b9b872063", [:make, :rebar3], [], "hexpm", "2b3e9da0b21c4565751a6d4901c20d1b4cc25cbb7fd50d91d2ab6dd287bc86a9"}, - "credo": {:hex, :credo, "1.6.3", "0a9f8925dbc8f940031b789f4623fc9a0eea99d3eed600fe831e403eb96c6a83", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2.8", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "1167cde00e6661d740fc54da2ee268e35d3982f027399b64d3e2e83af57a1180"}, + "credo": {:hex, :credo, "1.6.7", "323f5734350fd23a456f2688b9430e7d517afb313fbd38671b8a4449798a7854", [:mix], [{:bunt, "~> 0.2.1", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2.8", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "41e110bfb007f7eda7f897c10bf019ceab9a0b269ce79f015d54b0dcf4fc7dd3"}, "dart_sass": {:hex, :dart_sass, "0.5.1", "d45f20a8e324313689fb83287d4702352793ce8c9644bc254155d12656ade8b6", [:mix], [{:castore, ">= 0.0.0", [hex: :castore, repo: "hexpm", optional: false]}], "hexpm", "24f8a1c67e8b5267c51a33cbe6c0b5ebf12c2c83ace88b5ac04947d676b4ec81"}, "db_connection": {:hex, :db_connection, "2.4.3", "3b9aac9f27347ec65b271847e6baeb4443d8474289bd18c1d6f4de655b70c94d", [:mix], [{:connection, "~> 1.0", [hex: :connection, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "c127c15b0fa6cfb32eed07465e05da6c815b032508d4ed7c116122871df73c12"}, "decimal": {:hex, :decimal, "2.0.0", "a78296e617b0f5dd4c6caf57c714431347912ffb1d0842e998e9792b5642d697", [:mix], [], "hexpm", "34666e9c55dea81013e77d9d87370fe6cb6291d1ef32f46a1600230b1d44f577"}, @@ -36,7 +36,7 @@ "phoenix": {:hex, :phoenix, "1.6.15", "0a1d96bbc10747fd83525370d691953cdb6f3ccbac61aa01b4acb012474b047d", [:mix], [{:castore, ">= 0.0.0", [hex: :castore, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 2.0", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:phoenix_view, "~> 1.0 or ~> 2.0", [hex: :phoenix_view, repo: "hexpm", optional: false]}, {:plug, "~> 1.10", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 2.2", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:plug_crypto, "~> 1.2", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "d70ab9fbf6b394755ea88b644d34d79d8b146e490973151f248cacd122d20672"}, "phoenix_ecto": {:hex, :phoenix_ecto, "4.4.0", "0672ed4e4808b3fbed494dded89958e22fb882de47a97634c0b13e7b0b5f7720", [:mix], [{:ecto, "~> 3.3", [hex: :ecto, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.14.2 or ~> 3.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:plug, "~> 1.9", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "09864e558ed31ee00bd48fcc1d4fc58ae9678c9e81649075431e69dbabb43cc1"}, "phoenix_html": {:hex, :phoenix_html, "3.2.0", "1c1219d4b6cb22ac72f12f73dc5fad6c7563104d083f711c3fcd8551a1f4ae11", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "36ec97ba56d25c0136ef1992c37957e4246b649d620958a1f9fa86165f8bc54f"}, - "phoenix_live_reload": {:hex, :phoenix_live_reload, "1.3.3", "3a53772a6118d5679bf50fc1670505a290e32a1d195df9e069d8c53ab040c054", [:mix], [{:file_system, "~> 0.2.1 or ~> 0.3", [hex: :file_system, repo: "hexpm", optional: false]}, {:phoenix, "~> 1.4", [hex: :phoenix, repo: "hexpm", optional: false]}], "hexpm", "766796676e5f558dbae5d1bdb066849673e956005e3730dfd5affd7a6da4abac"}, + "phoenix_live_reload": {:hex, :phoenix_live_reload, "1.4.1", "2aff698f5e47369decde4357ba91fc9c37c6487a512b41732818f2204a8ef1d3", [:mix], [{:file_system, "~> 0.2.1 or ~> 0.3", [hex: :file_system, repo: "hexpm", optional: false]}, {:phoenix, "~> 1.4", [hex: :phoenix, repo: "hexpm", optional: false]}], "hexpm", "9bffb834e7ddf08467fe54ae58b5785507aaba6255568ae22b4d46e2bb3615ab"}, "phoenix_live_view": {:hex, :phoenix_live_view, "0.18.11", "c50eac83dae6b5488859180422dfb27b2c609de87f4aa5b9c926ecd0501cd44f", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix, "~> 1.6.15 or ~> 1.7.0", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 3.1", [hex: :phoenix_html, repo: "hexpm", optional: false]}, {:phoenix_template, "~> 1.0", [hex: :phoenix_template, repo: "hexpm", optional: false]}, {:phoenix_view, "~> 2.0", [hex: :phoenix_view, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.2 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "76c99a0ffb47cd95bf06a917e74f282a603f3e77b00375f3c2dd95110971b102"}, "phoenix_pubsub": {:hex, :phoenix_pubsub, "2.1.1", "ba04e489ef03763bf28a17eb2eaddc2c20c6d217e2150a61e3298b0f4c2012b5", [:mix], [], "hexpm", "81367c6d1eea5878ad726be80808eb5a787a23dee699f96e72b1109c57cdd8d9"}, "phoenix_template": {:hex, :phoenix_template, "1.0.1", "85f79e3ad1b0180abb43f9725973e3b8c2c3354a87245f91431eec60553ed3ef", [:mix], [{:phoenix_html, "~> 2.14.2 or ~> 3.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}], "hexpm", "157dc078f6226334c91cb32c1865bf3911686f8bcd6bcff86736f6253e6993ee"}, From dea6198e307d484a6e50be9d65df91a27d7e00c4 Mon Sep 17 00:00:00 2001 From: Dan Barber Date: Mon, 11 Jan 2021 12:40:48 -0500 Subject: [PATCH 04/24] WIP --- assets/js/app.js | 4 ++ lib/chess_web.ex | 2 - lib/chess_web/templates/game/_square.html.eex | 5 -- .../game/{_board.html.eex => board.html.leex} | 12 +++-- lib/chess_web/templates/game/index.html.eex | 2 +- lib/chess_web/templates/game/show.html.eex | 7 ++- .../templates/square/square.html.leex | 7 +++ lib/chess_web/views/game_view.ex | 2 +- lib/chess_web/views/live/board_live.ex | 51 +++++++++++++++++++ lib/chess_web/views/square_view.ex | 39 ++++++++++++++ 10 files changed, 118 insertions(+), 13 deletions(-) delete mode 100644 lib/chess_web/templates/game/_square.html.eex rename lib/chess_web/templates/game/{_board.html.eex => board.html.leex} (80%) create mode 100644 lib/chess_web/templates/square/square.html.leex create mode 100644 lib/chess_web/views/live/board_live.ex create mode 100644 lib/chess_web/views/square_view.ex diff --git a/assets/js/app.js b/assets/js/app.js index 6d1de0a..1f4f342 100644 --- a/assets/js/app.js +++ b/assets/js/app.js @@ -11,6 +11,10 @@ let liveSocket = new LiveSocket( {params: {_csrf_token: csrfToken}} ); +liveSocket.connect() + +window.liveSocket = liveSocket + import "@babel/polyfill"; import "phoenix_html"; diff --git a/lib/chess_web.ex b/lib/chess_web.ex index 8118a35..aa29f97 100644 --- a/lib/chess_web.ex +++ b/lib/chess_web.ex @@ -40,7 +40,6 @@ defmodule ChessWeb do import Phoenix.Controller, only: [get_csrf_token: 0, get_flash: 2, view_module: 1] import Phoenix.LiveView.Helpers - import ChessWeb.LiveHelpers # Use all HTML functionality (forms, tags, etc) use Phoenix.HTML @@ -78,7 +77,6 @@ defmodule ChessWeb do # Import LiveView helpers (live_render, live_component, live_patch, etc) import Phoenix.LiveView.Helpers - import ChessWeb.LiveHelpers # Import basic rendering functionality (render, render_layout, etc) import Phoenix.View diff --git a/lib/chess_web/templates/game/_square.html.eex b/lib/chess_web/templates/game/_square.html.eex deleted file mode 100644 index 937c827..0000000 --- a/lib/chess_web/templates/game/_square.html.eex +++ /dev/null @@ -1,5 +0,0 @@ -<%= if @piece == nil do %> -
-<% else %> -
square--<%= @piece["colour"] %>">
-<% end %> diff --git a/lib/chess_web/templates/game/_board.html.eex b/lib/chess_web/templates/game/board.html.leex similarity index 80% rename from lib/chess_web/templates/game/_board.html.eex rename to lib/chess_web/templates/game/board.html.leex index fa55c3c..437d2e6 100644 --- a/lib/chess_web/templates/game/_board.html.eex +++ b/lib/chess_web/templates/game/board.html.leex @@ -1,4 +1,4 @@ -
+
1
2
@@ -9,6 +9,7 @@
7
8
+
a
b
@@ -19,17 +20,22 @@
g
h
+
<%= for rank <- 0..7 do %>
<%= for file <- 0..7 do %> - <%= render "_square.html", + <%= render ChessWeb.SquareView, + "square.html", rank: rank, file: file, - piece: @game.board["#{file},#{rank}"] %> + piece: @game.board["#{file},#{rank}"], + selected: {file, rank} == @selected, + available: {file, rank} in @available %> <% end %>
<% end %>
+
diff --git a/lib/chess_web/templates/game/index.html.eex b/lib/chess_web/templates/game/index.html.eex index fe3c7cb..2ee3982 100644 --- a/lib/chess_web/templates/game/index.html.eex +++ b/lib/chess_web/templates/game/index.html.eex @@ -6,7 +6,7 @@
- - - - + <%= for {move_pair, i} <- @game.moves |> + Enum.chunk_every(2) |> Enum.with_index do %> + + + <%= case move_pair do %> + <% [white_move, black_move] -> %> + + + <% [white_move] -> %> + + + <% end %> + + <% end %>
- + <%= link gettext( "Game with %{name}", diff --git a/lib/chess_web/templates/game/show.html.eex b/lib/chess_web/templates/game/show.html.eex index 2e4b490..2a9b0b4 100644 --- a/lib/chess_web/templates/game/show.html.eex +++ b/lib/chess_web/templates/game/show.html.eex @@ -1,6 +1,11 @@
- <%= render "_board.html", conn: @conn, game: @game %> + <%= live_render( + @conn, + ChessWeb.BoardLive, + session: %{"user_id" => current_user(@conn).id, "game_id" => @game.id} + ) %> +

Playing <%= opponent(@game, current_user(@conn).id).name %> diff --git a/lib/chess_web/templates/square/square.html.leex b/lib/chess_web/templates/square/square.html.leex new file mode 100644 index 0000000..abcbaf8 --- /dev/null +++ b/lib/chess_web/templates/square/square.html.leex @@ -0,0 +1,7 @@ +

diff --git a/lib/chess_web/views/game_view.ex b/lib/chess_web/views/game_view.ex index 04c21a8..1d99066 100644 --- a/lib/chess_web/views/game_view.ex +++ b/lib/chess_web/views/game_view.ex @@ -46,7 +46,7 @@ defmodule ChessWeb.GameView do def files(conn, game) do ranks(conn, game) - |> Enum.reverse + |> Enum.reverse() end def ranks(conn, game) do diff --git a/lib/chess_web/views/live/board_live.ex b/lib/chess_web/views/live/board_live.ex new file mode 100644 index 0000000..5636895 --- /dev/null +++ b/lib/chess_web/views/live/board_live.ex @@ -0,0 +1,51 @@ +defmodule ChessWeb.BoardLive do + use Phoenix.LiveView + + alias Chess.Store.User + alias Chess.Store.Game + alias Chess.Repo + alias Chess.Board + + def render(assigns) do + Phoenix.View.render(ChessWeb.GameView, "board.html", assigns) + end + + def mount(_params, %{"user_id" => user_id, "game_id" => game_id}, socket) do + user = Repo.get!(User, user_id) + game = + Game.for_user(user) + |> Repo.get!(game_id) + + {:ok, assign(socket, game: game, user: user, selected: nil, available: [])} + end + + def handle_event("click", %{"rank" => rank, "file" => file}, socket) do + {:noreply, socket |> handle_click(file, rank)} + end + + defp handle_click(socket, file, rank) do + board = socket.assigns[:game].board + + assigns = + case socket.assigns do + %{:selected => nil} -> + case Board.piece(board, {file, rank}) do + %{"colour" => "white"} -> + [{:selected, selected(file, rank)}] + _ -> + [] + end + _ -> + [] + end + + assign(socket, assigns) + end + + defp selected(file, rank) do + { + String.to_integer(file), + String.to_integer(rank), + } + end +end diff --git a/lib/chess_web/views/square_view.ex b/lib/chess_web/views/square_view.ex new file mode 100644 index 0000000..574376b --- /dev/null +++ b/lib/chess_web/views/square_view.ex @@ -0,0 +1,39 @@ +defmodule ChessWeb.SquareView do + use ChessWeb, :view + + def classes(file, rank, piece, selected, available) do + square_class() + |> add_piece_classes(piece) + |> add_selected_class(selected) + |> add_available_class(available) + |> Enum.join(" ") + end + + defp square_class do + ["square"] + end + + defp add_piece_classes(classes, piece) do + if piece != nil do + classes ++ ["square--#{piece["type"]}", "square--#{piece["colour"]}"] + else + classes + end + end + + defp add_selected_class(classes, selected) do + if selected do + classes ++ ["square--selected"] + else + classes + end + end + + defp add_available_class(classes, available) do + if available do + classes ++ ["square--available"] + else + classes + end + end +end From b01403cbe4593e7dee4ae9c154ddd708d87b6080 Mon Sep 17 00:00:00 2001 From: Dan Barber Date: Sun, 11 Jul 2021 17:37:52 -0500 Subject: [PATCH 05/24] These variables aren't used --- lib/chess_web/views/square_view.ex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/chess_web/views/square_view.ex b/lib/chess_web/views/square_view.ex index 574376b..7afc532 100644 --- a/lib/chess_web/views/square_view.ex +++ b/lib/chess_web/views/square_view.ex @@ -1,7 +1,7 @@ defmodule ChessWeb.SquareView do use ChessWeb, :view - def classes(file, rank, piece, selected, available) do + def classes(_file, _rank, piece, selected, available) do square_class() |> add_piece_classes(piece) |> add_selected_class(selected) From 7e2c841b59e7a3893e7850bca349b8a34906e32d Mon Sep 17 00:00:00 2001 From: Dan Barber Date: Mon, 12 Jul 2021 12:29:41 -0500 Subject: [PATCH 06/24] Correctly choose pieces --- lib/chess_web/templates/game/show.html.eex | 1 + lib/chess_web/views/live/board_live.ex | 17 +++++++++++++---- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/lib/chess_web/templates/game/show.html.eex b/lib/chess_web/templates/game/show.html.eex index 2a9b0b4..560399e 100644 --- a/lib/chess_web/templates/game/show.html.eex +++ b/lib/chess_web/templates/game/show.html.eex @@ -12,6 +12,7 @@ offline

+
diff --git a/lib/chess_web/views/live/board_live.ex b/lib/chess_web/views/live/board_live.ex index 5636895..ff7612d 100644 --- a/lib/chess_web/views/live/board_live.ex +++ b/lib/chess_web/views/live/board_live.ex @@ -6,12 +6,15 @@ defmodule ChessWeb.BoardLive do alias Chess.Repo alias Chess.Board + import Chess.Auth, only: [get_user!: 1] + def render(assigns) do Phoenix.View.render(ChessWeb.GameView, "board.html", assigns) end def mount(_params, %{"user_id" => user_id, "game_id" => game_id}, socket) do user = Repo.get!(User, user_id) + game = Game.for_user(user) |> Repo.get!(game_id) @@ -24,19 +27,25 @@ defmodule ChessWeb.BoardLive do end defp handle_click(socket, file, rank) do - board = socket.assigns[:game].board + game = socket.assigns[:game] + board = game.board + user = socket.assigns[:user] + + colour = ChessWeb.GameView.player_colour(user, game) assigns = case socket.assigns do %{:selected => nil} -> case Board.piece(board, {file, rank}) do - %{"colour" => "white"} -> + %{"colour" => ^colour} -> [{:selected, selected(file, rank)}] + _ -> [] end + _ -> - [] + [{:selected, nil}] end assign(socket, assigns) @@ -45,7 +54,7 @@ defmodule ChessWeb.BoardLive do defp selected(file, rank) do { String.to_integer(file), - String.to_integer(rank), + String.to_integer(rank) } end end From 04e00e530bffd8093c03c7f791a313b3013cdaa2 Mon Sep 17 00:00:00 2001 From: Dan Barber Date: Tue, 13 Jul 2021 18:21:12 -0500 Subject: [PATCH 07/24] Now we're correctly handling moves --- lib/chess/board.ex | 6 +- lib/chess/game_state.ex | 2 +- lib/chess/moves/pieces/king/castling.ex | 4 +- lib/chess_web/templates/game/board.html.leex | 8 +- lib/chess_web/views/live/board_live.ex | 79 +++++++++++++++----- test/chess/store/game_test.exs | 2 +- 6 files changed, 72 insertions(+), 29 deletions(-) diff --git a/lib/chess/board.ex b/lib/chess/board.ex index 8dc8d65..b34026a 100644 --- a/lib/chess/board.ex +++ b/lib/chess/board.ex @@ -42,8 +42,8 @@ defmodule Chess.Board do if castling_move?(piece, from_file, to_file) do board |> castling_move(%{ - "from" => [from_file, from_rank], - "to" => [to_file, to_rank] + from: {from_file, from_rank}, + to: {to_file, to_rank} }) |> Map.get(:board) else @@ -65,7 +65,7 @@ defmodule Chess.Board do def castling_move?(_, _, _), do: false - def castling_move(board, %{"from" => [4, rank], "to" => [2, _rank]}) do + def castling_move(board, %{from: {4, rank}, to: {2, _rank}}) do move_piece(board, %{ "from" => [0, rank], "to" => [3, rank] diff --git a/lib/chess/game_state.ex b/lib/chess/game_state.ex index a220de2..76fa64f 100644 --- a/lib/chess/game_state.ex +++ b/lib/chess/game_state.ex @@ -68,7 +68,7 @@ defmodule Chess.GameState do |> Moves.available({file, rank}) |> Enum.all?(fn {to_file, to_rank} -> board - |> Board.move_piece(%{"from" => [file, rank], "to" => [to_file, to_rank]}) + |> Board.move_piece(%{from: {file, rank}, to: {to_file, to_rank}}) |> Map.get(:board) |> king_in_check?(piece["colour"]) end) diff --git a/lib/chess/moves/pieces/king/castling.ex b/lib/chess/moves/pieces/king/castling.ex index 52ec48b..4aafa3d 100644 --- a/lib/chess/moves/pieces/king/castling.ex +++ b/lib/chess/moves/pieces/king/castling.ex @@ -79,7 +79,7 @@ defmodule Chess.Moves.Pieces.King.Castling do [{2, rank}, {3, rank}] |> Enum.any?(fn {to_file, to_rank} -> board - |> Board.move_piece(%{"from" => [4, rank], "to" => [to_file, to_rank]}) + |> Board.move_piece(%{from: {4, rank}, to: {to_file, to_rank}}) |> Map.get(:board) |> GameState.king_in_check?(colour) end) @@ -89,7 +89,7 @@ defmodule Chess.Moves.Pieces.King.Castling do [{5, rank}, {6, rank}] |> Enum.any?(fn {to_file, to_rank} -> board - |> Board.move_piece(%{"from" => [4, rank], "to" => [to_file, to_rank]}) + |> Board.move_piece(%{from: {4, rank}, to: {to_file, to_rank}}) |> Map.get(:board) |> GameState.king_in_check?(colour) end) diff --git a/lib/chess_web/templates/game/board.html.leex b/lib/chess_web/templates/game/board.html.leex index 437d2e6..c5d3ede 100644 --- a/lib/chess_web/templates/game/board.html.leex +++ b/lib/chess_web/templates/game/board.html.leex @@ -1,4 +1,4 @@ -
+
1
2
@@ -22,14 +22,14 @@
- <%= for rank <- 0..7 do %> + <%= for {rank, row} <- @board do %>
- <%= for file <- 0..7 do %> + <%= for {file, piece} <- row do %> <%= render ChessWeb.SquareView, "square.html", rank: rank, file: file, - piece: @game.board["#{file},#{rank}"], + piece: piece, selected: {file, rank} == @selected, available: {file, rank} in @available %> <% end %> diff --git a/lib/chess_web/views/live/board_live.ex b/lib/chess_web/views/live/board_live.ex index ff7612d..c834bb2 100644 --- a/lib/chess_web/views/live/board_live.ex +++ b/lib/chess_web/views/live/board_live.ex @@ -5,6 +5,7 @@ defmodule ChessWeb.BoardLive do alias Chess.Store.Game alias Chess.Repo alias Chess.Board + alias Chess.Moves import Chess.Auth, only: [get_user!: 1] @@ -19,11 +20,24 @@ defmodule ChessWeb.BoardLive do Game.for_user(user) |> Repo.get!(game_id) - {:ok, assign(socket, game: game, user: user, selected: nil, available: [])} + {:ok, assign(socket, default_assigns(game, user))} end def handle_event("click", %{"rank" => rank, "file" => file}, socket) do - {:noreply, socket |> handle_click(file, rank)} + { + :noreply, + socket |> handle_click(String.to_integer(file), String.to_integer(rank)) + } + end + + defp default_assigns(game, user) do + %{ + board: Board.transform(game.board), + game: game, + user: user, + selected: nil, + available: [] + } end defp handle_click(socket, file, rank) do @@ -34,27 +48,56 @@ defmodule ChessWeb.BoardLive do colour = ChessWeb.GameView.player_colour(user, game) assigns = - case socket.assigns do - %{:selected => nil} -> - case Board.piece(board, {file, rank}) do - %{"colour" => ^colour} -> - [{:selected, selected(file, rank)}] + if colour == game.turn do + case socket.assigns do + %{selected: nil} -> + handle_selection(board, colour, file, rank) - _ -> - [] - end - - _ -> - [{:selected, nil}] + _ -> + handle_move(socket.assigns, file, rank) + end end assign(socket, assigns) end - defp selected(file, rank) do - { - String.to_integer(file), - String.to_integer(rank) - } + defp handle_selection(board, colour, file, rank) do + case Board.piece(board, {file, rank}) do + %{"colour" => ^colour} -> + [ + {:selected, {file, rank}}, + {:available, Moves.available(board, {file, rank})} + ] + + _ -> + [] + end + end + + defp handle_move( + %{game: game, available: available, selected: selected}, + file, + rank + ) do + if {file, rank} in available do + new_game = + game + |> Moves.make_move(%{from: selected, to: {file, rank}}) + |> case do + {:ok, %{game: new_game}} -> + new_game + end + + new_board = Board.transform(new_game.board) + + [ + {:selected, nil}, + {:available, []}, + {:board, new_board}, + {:game, new_game} + ] + else + [{:selected, nil}, {:available, []}] + end end end diff --git a/test/chess/store/game_test.exs b/test/chess/store/game_test.exs index 47de511..a841b37 100644 --- a/test/chess/store/game_test.exs +++ b/test/chess/store/game_test.exs @@ -90,7 +90,7 @@ defmodule Chess.Store.GameTest do opponent_id: opponent.id }) - move_params = %{"from" => [4, 1], "to" => [4, 3]} + move_params = %{from: {4, 1}, to: {4, 3}} changeset = Game.move_changeset( From bbc1838d7eb4faa58823d414d940508e4efd5201 Mon Sep 17 00:00:00 2001 From: Dan Barber Date: Tue, 13 Jul 2021 18:29:10 -0500 Subject: [PATCH 08/24] Tidy --- lib/chess_web/views/live/board_live.ex | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/lib/chess_web/views/live/board_live.ex b/lib/chess_web/views/live/board_live.ex index c834bb2..1c122e7 100644 --- a/lib/chess_web/views/live/board_live.ex +++ b/lib/chess_web/views/live/board_live.ex @@ -84,18 +84,16 @@ defmodule ChessWeb.BoardLive do game |> Moves.make_move(%{from: selected, to: {file, rank}}) |> case do - {:ok, %{game: new_game}} -> - new_game + {:ok, %{game: game}} -> + board = Board.transform(game.board) + + [ + {:selected, nil}, + {:available, []}, + {:board, board}, + {:game, game} + ] end - - new_board = Board.transform(new_game.board) - - [ - {:selected, nil}, - {:available, []}, - {:board, new_board}, - {:game, new_game} - ] else [{:selected, nil}, {:available, []}] end From f5c35de8d8a44640fc5936b6be9e22adfed2f3cd Mon Sep 17 00:00:00 2001 From: Dan Barber Date: Tue, 13 Jul 2021 19:28:19 -0500 Subject: [PATCH 09/24] Clients subscribe to the game to get updates --- lib/chess_web/views/live/board_live.ex | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/lib/chess_web/views/live/board_live.ex b/lib/chess_web/views/live/board_live.ex index 1c122e7..ad8f03f 100644 --- a/lib/chess_web/views/live/board_live.ex +++ b/lib/chess_web/views/live/board_live.ex @@ -14,6 +14,8 @@ defmodule ChessWeb.BoardLive do end def mount(_params, %{"user_id" => user_id, "game_id" => game_id}, socket) do + ChessWeb.Endpoint.subscribe("game:#{game_id}") + user = Repo.get!(User, user_id) game = @@ -40,6 +42,10 @@ defmodule ChessWeb.BoardLive do } end + def handle_info(%{event: "move", payload: state}, socket) do + {:noreply, assign(socket, state)} + end + defp handle_click(socket, file, rank) do game = socket.assigns[:game] board = game.board @@ -87,6 +93,8 @@ defmodule ChessWeb.BoardLive do {:ok, %{game: game}} -> board = Board.transform(game.board) + broadcast_move(game, board) + [ {:selected, nil}, {:available, []}, @@ -98,4 +106,13 @@ defmodule ChessWeb.BoardLive do [{:selected, nil}, {:available, []}] end end + + defp broadcast_move(game, board) do + ChessWeb.Endpoint.broadcast_from( + self(), + "game:#{game.id}", + "move", + %{game: game, board: board} + ) + end end From 1ea842d0ab5900e6d315f65a31b767c2dd5b6a27 Mon Sep 17 00:00:00 2001 From: Dan Barber Date: Wed, 14 Jul 2021 18:12:16 -0500 Subject: [PATCH 10/24] Bunch of fixes --- lib/chess_web/templates/game/board.html.leex | 4 +++- lib/chess_web/templates/password/edit.html.eex | 2 +- lib/chess_web/templates/profile/edit.html.eex | 2 +- lib/chess_web/views/game_view.ex | 4 +++- test/chess_web/controllers/game_controller_test.exs | 2 +- 5 files changed, 9 insertions(+), 5 deletions(-) diff --git a/lib/chess_web/templates/game/board.html.leex b/lib/chess_web/templates/game/board.html.leex index c5d3ede..caa9f78 100644 --- a/lib/chess_web/templates/game/board.html.leex +++ b/lib/chess_web/templates/game/board.html.leex @@ -37,5 +37,7 @@ <% end %>
-
+
+ <%= states[@game.state] %> +
diff --git a/lib/chess_web/templates/password/edit.html.eex b/lib/chess_web/templates/password/edit.html.eex index 24e985b..35d1eb8 100644 --- a/lib/chess_web/templates/password/edit.html.eex +++ b/lib/chess_web/templates/password/edit.html.eex @@ -1,7 +1,7 @@

<%= gettext "Password" %>

- <%= form_for @changeset, password_path(@conn, :update), [class: "update-password"], fn f -> %> + <%= form_for @changeset, password_path(@conn, :update), [class: "update-password", novalidate: true], fn f -> %> <%= if @changeset.action do %>

diff --git a/lib/chess_web/templates/profile/edit.html.eex b/lib/chess_web/templates/profile/edit.html.eex index a8b335a..94cad6c 100644 --- a/lib/chess_web/templates/profile/edit.html.eex +++ b/lib/chess_web/templates/profile/edit.html.eex @@ -1,7 +1,7 @@

<%= gettext "Profile" %>

- <%= form_for @changeset, profile_path(@conn, :update), [class: "update-profile"], fn f -> %> + <%= form_for @changeset, profile_path(@conn, :update), [class: "update-profile", novalidate: true], fn f -> %> <%= if @changeset.action do %>

diff --git a/lib/chess_web/views/game_view.ex b/lib/chess_web/views/game_view.ex index 1d99066..f16e365 100644 --- a/lib/chess_web/views/game_view.ex +++ b/lib/chess_web/views/game_view.ex @@ -37,7 +37,9 @@ defmodule ChessWeb.GameView do end def your_turn?(conn, game) do - player_colour(conn, game) == game.turn + conn + |> current_user() + |> player_colour(game) == game.turn end def player_colour(conn, game) do diff --git a/test/chess_web/controllers/game_controller_test.exs b/test/chess_web/controllers/game_controller_test.exs index 4815394..59b290f 100644 --- a/test/chess_web/controllers/game_controller_test.exs +++ b/test/chess_web/controllers/game_controller_test.exs @@ -60,7 +60,7 @@ defmodule ChessWeb.GameControllerTest do |> login(user) |> get(game_path(conn, :show, game)) - assert html_response(conn, 200) =~ "

" + assert html_response(conn, 200) =~ "
" end test "does not show a game if the user is not a player", %{conn: conn} do From 3543ccdcae95b865fdfd8a234b19bcc02fde22c3 Mon Sep 17 00:00:00 2001 From: Dan Barber Date: Wed, 14 Jul 2021 18:23:47 -0500 Subject: [PATCH 11/24] Fix layout issue caused by live component container --- assets/css/components/_board.scss | 5 ++++- lib/chess_web/views/live/board_live.ex | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/assets/css/components/_board.scss b/assets/css/components/_board.scss index 211da09..c9fac3c 100644 --- a/assets/css/components/_board.scss +++ b/assets/css/components/_board.scss @@ -8,13 +8,16 @@ width: 1.5%; } +.board__container { + grid-area: board; +} + .board { background: $background-color; border-collapse: unset; border-radius: 2.8%; border-spacing: 1px; color: $foreground-color; - grid-area: board; height: var(--board-size); padding: calc(var(--board-size) / 20); position: relative; diff --git a/lib/chess_web/views/live/board_live.ex b/lib/chess_web/views/live/board_live.ex index ad8f03f..8bd39bd 100644 --- a/lib/chess_web/views/live/board_live.ex +++ b/lib/chess_web/views/live/board_live.ex @@ -1,5 +1,5 @@ defmodule ChessWeb.BoardLive do - use Phoenix.LiveView + use Phoenix.LiveView, container: {:div, class: "board__container"} alias Chess.Store.User alias Chess.Store.Game From 87504064e713f807d1db257fff54e62d48d0c5f6 Mon Sep 17 00:00:00 2001 From: Dan Barber Date: Sat, 17 Jul 2021 21:01:11 -0500 Subject: [PATCH 12/24] WIP: Game info --- .../templates/game/game_info.html.leex | 6 ++++++ lib/chess_web/templates/game/show.html.eex | 11 +++++----- lib/chess_web/views/live/game_info_live.ex | 21 +++++++++++++++++++ 3 files changed, 32 insertions(+), 6 deletions(-) create mode 100644 lib/chess_web/templates/game/game_info.html.leex create mode 100644 lib/chess_web/views/live/game_info_live.ex diff --git a/lib/chess_web/templates/game/game_info.html.leex b/lib/chess_web/templates/game/game_info.html.leex new file mode 100644 index 0000000..3a830b8 --- /dev/null +++ b/lib/chess_web/templates/game/game_info.html.leex @@ -0,0 +1,6 @@ +
+

+ Playing <%= opponent(@game, @user.id).name %> + offline +

+
diff --git a/lib/chess_web/templates/game/show.html.eex b/lib/chess_web/templates/game/show.html.eex index 560399e..19181e3 100644 --- a/lib/chess_web/templates/game/show.html.eex +++ b/lib/chess_web/templates/game/show.html.eex @@ -6,12 +6,11 @@ session: %{"user_id" => current_user(@conn).id, "game_id" => @game.id} ) %> -
-

- Playing <%= opponent(@game, current_user(@conn).id).name %> - offline -

-
+ <%= live_render( + @conn, + ChessWeb.GameInfoLive, + session: %{"user_id" => current_user(@conn).id, "game_id" => @game.id} + ) %>
diff --git a/lib/chess_web/views/live/game_info_live.ex b/lib/chess_web/views/live/game_info_live.ex new file mode 100644 index 0000000..642a805 --- /dev/null +++ b/lib/chess_web/views/live/game_info_live.ex @@ -0,0 +1,21 @@ +defmodule ChessWeb.GameInfoLive do + use Phoenix.LiveView + + alias Chess.Store.User + alias Chess.Store.Game + alias Chess.Repo + + def render(assigns) do + Phoenix.View.render(ChessWeb.GameView, "game_info.html", assigns) + end + + def mount(_params, %{"game_id" => game_id, "user_id" => user_id}, socket) do + user = Repo.get!(User, user_id) + + game = + Game.for_user(user) + |> Repo.get!(game_id) + + {:ok, assign(socket, game: game, user: user)} + end +end From 205d5a5a2485f3cd20e9f1bc20acbdbc80191356 Mon Sep 17 00:00:00 2001 From: Dan Barber Date: Wed, 4 Oct 2023 15:33:52 -0500 Subject: [PATCH 13/24] Add back @session_options --- lib/chess_web/endpoint.ex | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/chess_web/endpoint.ex b/lib/chess_web/endpoint.ex index e418114..9a5b77a 100644 --- a/lib/chess_web/endpoint.ex +++ b/lib/chess_web/endpoint.ex @@ -1,6 +1,12 @@ defmodule ChessWeb.Endpoint do use Phoenix.Endpoint, otp_app: :chess + @session_options [ + store: :cookie, + key: "_chess_key", + signing_salt: "9LqUhZTU" + ] + if sandbox = Application.compile_env(:chess, :sandbox) do plug(Phoenix.Ecto.SQL.Sandbox, sandbox: sandbox) end From 55f0af78a093ce33c32dbb356d35be5bb07fc2ea Mon Sep 17 00:00:00 2001 From: Dan Barber Date: Mon, 9 Oct 2023 18:31:05 -0500 Subject: [PATCH 14/24] Upgrade Erlang to OTP 26 --- .tool-versions | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.tool-versions b/.tool-versions index 7483aa9..9a4f0ca 100644 --- a/.tool-versions +++ b/.tool-versions @@ -1,4 +1,4 @@ elixir 1.14.1 python 3.9.1 nodejs 16.14.0 -erlang 24.2.1 +erlang 26.1.1 From b960dd668caf86abc89ac936a6c4031180995920 Mon Sep 17 00:00:00 2001 From: Dan Barber Date: Mon, 9 Oct 2023 18:31:20 -0500 Subject: [PATCH 15/24] Get the board rendering --- lib/chess/board.ex | 13 ----- lib/chess_web/templates/game/board.html.leex | 24 ++++----- .../templates/game/game_info.html.leex | 30 ++++++++--- lib/chess_web/templates/game/index.html.eex | 6 +-- lib/chess_web/templates/game/show.html.eex | 18 ------- lib/chess_web/views/game_view.ex | 51 +++++++++++-------- lib/chess_web/views/live/board_live.ex | 31 +++++------ lib/chess_web/views/live/game_info_live.ex | 4 ++ mix.lock | 6 +-- 9 files changed, 88 insertions(+), 95 deletions(-) diff --git a/lib/chess/board.ex b/lib/chess/board.ex index b34026a..e533e99 100644 --- a/lib/chess/board.ex +++ b/lib/chess/board.ex @@ -1,15 +1,6 @@ defmodule Chess.Board do @moduledoc false - def transform(board) do - Enum.map(0..7, fn rank -> - Enum.map(0..7, fn file -> - board - |> piece({file, rank}) - end) - end) - end - def search(board, %{"type" => type, "colour" => colour}) do board |> Enum.filter(fn {_index, piece} -> @@ -26,10 +17,6 @@ defmodule Chess.Board do |> indexes_to_tuples end - def piece(board, {file, rank}) do - board["#{file},#{rank}"] - end - def move_piece(board, %{ "from" => [from_file, from_rank], "to" => [to_file, to_rank] diff --git a/lib/chess_web/templates/game/board.html.leex b/lib/chess_web/templates/game/board.html.leex index caa9f78..d11be6e 100644 --- a/lib/chess_web/templates/game/board.html.leex +++ b/lib/chess_web/templates/game/board.html.leex @@ -22,22 +22,20 @@
- <%= for {rank, row} <- @board do %> -
- <%= for {file, piece} <- row do %> - <%= render ChessWeb.SquareView, - "square.html", - rank: rank, - file: file, - piece: piece, - selected: {file, rank} == @selected, - available: {file, rank} in @available %> - <% end %> -
+ <%= for rank <- 0..7 do %> + <%= for file <- 0..7 do %> + <%= render ChessWeb.SquareView, + "square.html", + rank: rank, + file: file, + piece: piece(@board, {file, rank}), + selected: {file, rank} == @selected, + available: {file, rank} in @available %> + <% end %> <% end %>
- <%= states[@game.state] %> + <%= states(@game.state) %>
diff --git a/lib/chess_web/templates/game/game_info.html.leex b/lib/chess_web/templates/game/game_info.html.leex index 3a830b8..8c2c50a 100644 --- a/lib/chess_web/templates/game/game_info.html.leex +++ b/lib/chess_web/templates/game/game_info.html.leex @@ -1,6 +1,24 @@ -
-

- Playing <%= opponent(@game, @user.id).name %> - offline -

-
+
+

+ Playing <%= opponent(@game, @user.id).name %> + offline +

+
+ +
+
+ + + + + + + + + + + + + +
Move no.WhiteBlack
1.e4
+
diff --git a/lib/chess_web/templates/game/index.html.eex b/lib/chess_web/templates/game/index.html.eex index 2ee3982..125d1d6 100644 --- a/lib/chess_web/templates/game/index.html.eex +++ b/lib/chess_web/templates/game/index.html.eex @@ -3,7 +3,7 @@ <%= for game <- @games do %> - + - ); - } -}; - -const renderMoves = (moves) => { - let lineNumber = 1; - - return _.map(moves, (move) => { - return ( - - - {renderMove(move[0])} - {renderMove(move[1])} - - ); - }); -}; - -const MoveList = (props) => { - return ( -
-
@@ -16,10 +16,10 @@ class: "btn btn-default btn-xs" %> - <%= state(@conn, game) %> + <%= state(current_user(@conn), game) %> - <%= won_lost(@conn, game) %> + <%= won_lost(current_user(@conn), game) %> <%= link gettext("Delete"), diff --git a/lib/chess_web/templates/game/show.html.eex b/lib/chess_web/templates/game/show.html.eex index 19181e3..afaf9a6 100644 --- a/lib/chess_web/templates/game/show.html.eex +++ b/lib/chess_web/templates/game/show.html.eex @@ -11,23 +11,5 @@ ChessWeb.GameInfoLive, session: %{"user_id" => current_user(@conn).id, "game_id" => @game.id} ) %> - -
- - - - - - - - - - - - - - -
Move no.WhiteBlack
1.e4
-
diff --git a/lib/chess_web/views/game_view.ex b/lib/chess_web/views/game_view.ex index f16e365..2be10d8 100644 --- a/lib/chess_web/views/game_view.ex +++ b/lib/chess_web/views/game_view.ex @@ -3,11 +3,12 @@ defmodule ChessWeb.GameView do alias Chess.GameState + import Phoenix.Component import Chess.Auth, only: [current_user: 1] - def won_lost(conn, game) do + def won_lost(user, game) do if game_over?(game) && game.state == "checkmate" do - (your_turn?(conn, game) && + (your_turn?(user, game) && gettext("You lost")) || gettext("You won") end @@ -17,12 +18,12 @@ defmodule ChessWeb.GameView do GameState.game_over?(game) end - def state(conn, game) do + def state(user, game) do cond do GameState.game_over?(game) -> - states()[game.state] + states(game.state) - your_turn?(conn, game) -> + your_turn?(user, game) -> gettext("Your turn") true -> @@ -30,29 +31,32 @@ defmodule ChessWeb.GameView do end end - def turn_class(conn, game) do - if your_turn?(conn, game) && !GameState.game_over?(game) do + def turn_class(user, game) do + if your_turn?(user, game) && !GameState.game_over?(game) do "games-list__your-turn" end end - def your_turn?(conn, game) do - conn - |> current_user() + def your_turn?(user, game) do + user |> player_colour(game) == game.turn end - def player_colour(conn, game) do - (current_user(conn).id == game.user_id && "white") || "black" + def player_colour(user, game) do + (user.id == game.user_id && "white") || "black" end - def files(conn, game) do - ranks(conn, game) + def piece(board, {file, rank}) do + board["#{file},#{rank}"] + end + + def files(user, game) do + ranks(user, game) |> Enum.reverse() end - def ranks(conn, game) do - if game.user_id == current_user(conn).id do + def ranks(user, game) do + if game.user_id == user.id do 7..0 else 0..7 @@ -75,11 +79,14 @@ defmodule ChessWeb.GameView do end end - defp states do - %{ - "checkmate" => gettext("Checkmate!"), - "stalemate" => gettext("Stalemate"), - "check" => gettext("Check") - } + def states(state) do + Map.get( + %{ + "checkmate" => gettext("Checkmate!"), + "stalemate" => gettext("Stalemate"), + "check" => gettext("Check") + }, + state + ) end end diff --git a/lib/chess_web/views/live/board_live.ex b/lib/chess_web/views/live/board_live.ex index 8bd39bd..e58d732 100644 --- a/lib/chess_web/views/live/board_live.ex +++ b/lib/chess_web/views/live/board_live.ex @@ -7,8 +7,6 @@ defmodule ChessWeb.BoardLive do alias Chess.Board alias Chess.Moves - import Chess.Auth, only: [get_user!: 1] - def render(assigns) do Phoenix.View.render(ChessWeb.GameView, "board.html", assigns) end @@ -34,7 +32,7 @@ defmodule ChessWeb.BoardLive do defp default_assigns(game, user) do %{ - board: Board.transform(game.board), + board: game.board, game: game, user: user, selected: nil, @@ -86,22 +84,21 @@ defmodule ChessWeb.BoardLive do rank ) do if {file, rank} in available do - new_game = - game - |> Moves.make_move(%{from: selected, to: {file, rank}}) - |> case do - {:ok, %{game: game}} -> - board = Board.transform(game.board) + game + |> Moves.make_move(%{from: selected, to: {file, rank}}) + |> case do + {:ok, %{game: game}} -> + board = Board.transform(game.board) - broadcast_move(game, board) + broadcast_move(game, board) - [ - {:selected, nil}, - {:available, []}, - {:board, board}, - {:game, game} - ] - end + [ + {:selected, nil}, + {:available, []}, + {:board, board}, + {:game, game} + ] + end else [{:selected, nil}, {:available, []}] end diff --git a/lib/chess_web/views/live/game_info_live.ex b/lib/chess_web/views/live/game_info_live.ex index 642a805..f4447db 100644 --- a/lib/chess_web/views/live/game_info_live.ex +++ b/lib/chess_web/views/live/game_info_live.ex @@ -5,6 +5,8 @@ defmodule ChessWeb.GameInfoLive do alias Chess.Store.Game alias Chess.Repo + import Ecto.Query + def render(assigns) do Phoenix.View.render(ChessWeb.GameView, "game_info.html", assigns) end @@ -14,6 +16,8 @@ defmodule ChessWeb.GameInfoLive do game = Game.for_user(user) + |> preload(:user) + |> preload(:opponent) |> Repo.get!(game_id) {:ok, assign(socket, game: game, user: user)} diff --git a/mix.lock b/mix.lock index f999a84..d11eb94 100644 --- a/mix.lock +++ b/mix.lock @@ -13,8 +13,8 @@ "credo": {:hex, :credo, "1.6.7", "323f5734350fd23a456f2688b9430e7d517afb313fbd38671b8a4449798a7854", [:mix], [{:bunt, "~> 0.2.1", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2.8", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "41e110bfb007f7eda7f897c10bf019ceab9a0b269ce79f015d54b0dcf4fc7dd3"}, "dart_sass": {:hex, :dart_sass, "0.5.1", "d45f20a8e324313689fb83287d4702352793ce8c9644bc254155d12656ade8b6", [:mix], [{:castore, ">= 0.0.0", [hex: :castore, repo: "hexpm", optional: false]}], "hexpm", "24f8a1c67e8b5267c51a33cbe6c0b5ebf12c2c83ace88b5ac04947d676b4ec81"}, "db_connection": {:hex, :db_connection, "2.4.3", "3b9aac9f27347ec65b271847e6baeb4443d8474289bd18c1d6f4de655b70c94d", [:mix], [{:connection, "~> 1.0", [hex: :connection, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "c127c15b0fa6cfb32eed07465e05da6c815b032508d4ed7c116122871df73c12"}, - "decimal": {:hex, :decimal, "2.0.0", "a78296e617b0f5dd4c6caf57c714431347912ffb1d0842e998e9792b5642d697", [:mix], [], "hexpm", "34666e9c55dea81013e77d9d87370fe6cb6291d1ef32f46a1600230b1d44f577"}, - "ecto": {:hex, :ecto, "3.9.4", "3ee68e25dbe0c36f980f1ba5dd41ee0d3eb0873bccae8aeaf1a2647242bffa35", [:mix], [{:decimal, "~> 1.6 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "de5f988c142a3aa4ec18b85a4ec34a2390b65b24f02385c1144252ff6ff8ee75"}, + "decimal": {:hex, :decimal, "2.1.1", "5611dca5d4b2c3dd497dec8f68751f1f1a54755e8ed2a966c2633cf885973ad6", [:mix], [], "hexpm", "53cfe5f497ed0e7771ae1a475575603d77425099ba5faef9394932b35020ffcc"}, + "ecto": {:hex, :ecto, "3.9.6", "2f420c173efcb2e22fa4f8fc41e75e02b3c5bd4cffef12085cae5418c12e530d", [:mix], [{:decimal, "~> 1.6 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "df17bc06ba6f78a7b764e4a14ef877fe5f4499332c5a105ace11fe7013b72c84"}, "ecto_sql": {:hex, :ecto_sql, "3.9.2", "34227501abe92dba10d9c3495ab6770e75e79b836d114c41108a4bf2ce200ad5", [:mix], [{:db_connection, "~> 2.5 or ~> 2.4.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.9.2", [hex: :ecto, repo: "hexpm", optional: false]}, {:myxql, "~> 0.6.0", [hex: :myxql, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.16.0 or ~> 1.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:tds, "~> 2.1.1 or ~> 2.2", [hex: :tds, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "1eb5eeb4358fdbcd42eac11c1fbd87e3affd7904e639d77903c1358b2abd3f70"}, "elixir_make": {:hex, :elixir_make, "0.7.3", "c37fdae1b52d2cc51069713a58c2314877c1ad40800a57efb213f77b078a460d", [:mix], [{:castore, "~> 0.1", [hex: :castore, repo: "hexpm", optional: true]}], "hexpm", "24ada3e3996adbed1fa024ca14995ef2ba3d0d17b678b0f3f2b1f66e6ce2b274"}, "esbuild": {:hex, :esbuild, "0.6.0", "9ba6ead054abd43cb3d7b14946a0cdd1493698ccd8e054e0e5d6286d7f0f509c", [:mix], [{:castore, ">= 0.0.0", [hex: :castore, repo: "hexpm", optional: false]}], "hexpm", "30f9a05d4a5bab0d3e37398f312f80864e1ee1a081ca09149d06d474318fd040"}, @@ -27,7 +27,7 @@ "hackney": {:hex, :hackney, "1.18.1", "f48bf88f521f2a229fc7bae88cf4f85adc9cd9bcf23b5dc8eb6a1788c662c4f6", [:rebar3], [{:certifi, "~>2.9.0", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "~>6.1.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "~>1.0.0", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~>1.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:parse_trans, "3.3.1", [hex: :parse_trans, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "~>1.1.0", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}, {:unicode_util_compat, "~>0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "a4ecdaff44297e9b5894ae499e9a070ea1888c84afdd1fd9b7b2bc384950128e"}, "httpoison": {:hex, :httpoison, "1.8.2", "9eb9c63ae289296a544842ef816a85d881d4a31f518a0fec089aaa744beae290", [:mix], [{:hackney, "~> 1.17", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "2bb350d26972e30c96e2ca74a1aaf8293d61d0742ff17f01e0279fef11599921"}, "idna": {:hex, :idna, "6.1.1", "8a63070e9f7d0c62eb9d9fcb360a7de382448200fbbd1b106cc96d3d8099df8d", [:rebar3], [{:unicode_util_compat, "~>0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "92376eb7894412ed19ac475e4a86f7b413c1b9fbb5bd16dccd57934157944cea"}, - "jason": {:hex, :jason, "1.4.0", "e855647bc964a44e2f67df589ccf49105ae039d4179db7f6271dfd3843dc27e6", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "79a3791085b2a0f743ca04cec0f7be26443738779d09302e01318f97bdb82121"}, + "jason": {:hex, :jason, "1.4.1", "af1504e35f629ddcdd6addb3513c3853991f694921b1b9368b0bd32beb9f1b63", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "fbb01ecdfd565b56261302f7e1fcc27c4fb8f32d56eab74db621fc154604a7a1"}, "jose": {:hex, :jose, "1.11.5", "3bc2d75ffa5e2c941ca93e5696b54978323191988eb8d225c2e663ddfefd515e", [:mix, :rebar3], [], "hexpm", "dcd3b215bafe02ea7c5b23dafd3eb8062a5cd8f2d904fd9caa323d37034ab384"}, "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm", "69b09adddc4f74a40716ae54d140f93beb0fb8978d8636eaded0c31b6f099f16"}, "mime": {:hex, :mime, "2.0.3", "3676436d3d1f7b81b5a2d2bd8405f412c677558c81b1c92be58c00562bb59095", [:mix], [], "hexpm", "27a30bf0db44d25eecba73755acf4068cbfe26a4372f9eb3e4ea3a45956bff6b"}, From 32cf90d70c93c8ea4a25af99bf66451e3a87b103 Mon Sep 17 00:00:00 2001 From: Dan Barber Date: Wed, 25 Oct 2023 16:14:23 -0500 Subject: [PATCH 16/24] Switch to NPM and remove old React code --- assets/js/app.js | 45 +- assets/js/components/chess-board-square.js | 99 --- assets/js/components/chess-board.js | 114 ---- assets/js/components/file-labels.js | 22 - assets/js/components/game-info.js | 41 -- assets/js/components/game-state.js | 26 - assets/js/components/game.js | 65 -- assets/js/components/move-list.js | 78 --- assets/js/components/opponent-finder.js | 168 ----- assets/js/components/rank-labels.js | 22 - assets/js/reducers/chess-board.js | 56 -- assets/js/services/api.js | 9 - assets/js/services/channel.js | 85 --- assets/js/services/notifications.js | 26 - assets/js/services/presences.js | 24 - assets/js/services/socket.js | 58 -- assets/js/store/actions.js | 62 -- assets/js/store/default-state.js | 30 - assets/js/store/listeners.js | 27 - assets/package-lock.json | 578 ++++++++++++++++ assets/package.json | 21 +- assets/yarn-error.log | 734 --------------------- assets/yarn.lock | 654 ------------------ bin/setup | 4 +- 24 files changed, 594 insertions(+), 2454 deletions(-) delete mode 100644 assets/js/components/chess-board-square.js delete mode 100644 assets/js/components/chess-board.js delete mode 100644 assets/js/components/file-labels.js delete mode 100644 assets/js/components/game-info.js delete mode 100644 assets/js/components/game-state.js delete mode 100644 assets/js/components/game.js delete mode 100644 assets/js/components/move-list.js delete mode 100644 assets/js/components/opponent-finder.js delete mode 100644 assets/js/components/rank-labels.js delete mode 100644 assets/js/reducers/chess-board.js delete mode 100644 assets/js/services/api.js delete mode 100644 assets/js/services/channel.js delete mode 100644 assets/js/services/notifications.js delete mode 100644 assets/js/services/presences.js delete mode 100644 assets/js/services/socket.js delete mode 100644 assets/js/store/actions.js delete mode 100644 assets/js/store/default-state.js delete mode 100644 assets/js/store/listeners.js create mode 100644 assets/package-lock.json delete mode 100644 assets/yarn-error.log delete mode 100644 assets/yarn.lock diff --git a/assets/js/app.js b/assets/js/app.js index 1f4f342..2f2961d 100644 --- a/assets/js/app.js +++ b/assets/js/app.js @@ -1,43 +1,22 @@ "use strict"; -import {Socket} from "phoenix"; -import LiveSocket from "phoenix_live_view"; +import "phoenix_html"; -let csrfToken = document - .querySelector("meta[name='csrf-token']").getAttribute("content"); -let liveSocket = new LiveSocket( +import { Socket } from "phoenix"; +import { LiveSocket } from "phoenix_live_view"; + +const csrfToken = document + .querySelector("meta[name='csrf-token']") + .getAttribute("content"); + +const liveSocket = new LiveSocket( "/live", Socket, {params: {_csrf_token: csrfToken}} ); -liveSocket.connect() +liveSocket.connect(); -window.liveSocket = liveSocket +liveSocket.enableDebug(); -import "@babel/polyfill"; -import "phoenix_html"; - -import React from "react"; -import ReactDOM from "react-dom"; -import { createStore } from "redux"; - -import Game from "./components/game"; -import OpponentFinder from "./components/opponent-finder"; -import chessBoardReducer from "./reducers/chess-board"; - -const store = createStore(chessBoardReducer); - -const gameContainer = document.getElementById("game"); - -if (gameContainer != undefined) { - const gameId = gameContainer.getAttribute("data-game-id"); - - ReactDOM.render(, gameContainer); -} - -const opponentFinderContainer = document.getElementById("opponent-finder"); - -if (opponentFinderContainer != undefined) { - ReactDOM.render(, opponentFinderContainer); -} +window.liveSocket = liveSocket; diff --git a/assets/js/components/chess-board-square.js b/assets/js/components/chess-board-square.js deleted file mode 100644 index 661f056..0000000 --- a/assets/js/components/chess-board-square.js +++ /dev/null @@ -1,99 +0,0 @@ -import React from "react"; -import _ from "lodash"; -import classNames from "classnames"; - -import API from "../services/api"; - -import { selectPiece } from "../store/actions"; - -class ChessBoardSquare extends React.Component { - constructor(props) { - super(props); - } - - get squareCoords() { - return [this.props.file, this.props.rank]; - } - - get squareId() { - return `f${this.props.file}-r${this.props.rank}`; - } - - get squareClass() { - if (this.props.piece == undefined) { - return classNames( - "square", - { "square--available": this.isAvailableSquare() } - ); - } else { - return classNames( - "square", - `square--${this.props.piece.type}`, - `square--${this.props.piece.colour}`, - { "square--selected": this.isSelectedSquare() }, - { "square--available": this.isAvailableSquare() } - ); - } - } - - selectSquare() { - const { piece, store, channel } = this.props; - const { gameId, selectedSquare, player } = store.getState(); - - if (this.moveIsValid(selectedSquare)) { - channel.sendMove({ - from: selectedSquare, - to: this.squareCoords, - }); - } else if (selectedSquare != null) { - store.dispatch(selectPiece(null)); - } else if (this.playerCanSelectPiece(player, piece)) { - store.dispatch(selectPiece(this.squareCoords)); - channel.getAvailableMoves(this.squareCoords); - } - } - - moveIsValid(selectedSquare) { - return selectedSquare != null && - !this.isSelectedSquare() && - this.isAvailableSquare(); - } - - playerCanSelectPiece(player, piece) { - const { store } = this.props; - const { turn } = store.getState(); - - return piece !== undefined && - piece.colour == player && - player == turn; - } - - isSelectedSquare() { - const { store } = this.props; - - if (store.getState().selectedSquare == null) { - return false; - } else { - return _.isEqual(this.squareCoords, store.getState().selectedSquare); - } - } - - isAvailableSquare() { - const { store } = this.props; - const availableMoves = store.getState().availableMoves; - - return _.find(availableMoves, (square) => { - return square.join() == this.squareCoords.join(); - }); - } - - render() { - return
; - } -} - -export default ChessBoardSquare; diff --git a/assets/js/components/chess-board.js b/assets/js/components/chess-board.js deleted file mode 100644 index b5b1d8c..0000000 --- a/assets/js/components/chess-board.js +++ /dev/null @@ -1,114 +0,0 @@ -import React from "react"; -import _ from "lodash"; -import { connect } from "react-redux"; -import classNames from "classnames"; - -import ChessBoardSquare from "./chess-board-square"; -import RankLabels from "./rank-labels"; -import FileLabels from "./file-labels"; -import GameState from "./game-state"; - -class ChessBoard extends React.Component { - componentWillMount() { - const { gameId, store } = this.props; - } - - get turn() { - const { store } = this.props; - return store.getState().turn; - } - - get board() { - const { store } = this.props; - return store.getState().board; - } - - get player() { - const { store } = this.props; - return store.getState().player; - } - - get gameState() { - const { store } = this.props; - return store.getState().state; - } - - files(rank) { - switch (this.player) { - case "white": - return Object.keys(rank).sort(); - case "black": - return Object.keys(rank) - .sort() - .reverse(); - } - } - - ranks() { - const board = this.board; - const player = this.player; - - switch (player) { - case "white": - return Object.keys(board).reverse(); - case "black": - return Object.keys(board); - } - } - - renderSquares() { - const { store, channel } = this.props; - - return _.map(this.ranks(), (rankId) => { - const rank = this.board[rankId]; - - return _.map(this.files(rank), (fileId) => { - return ( - - ); - }); - }); - } - - get boardClass() { - const turn = this.turn; - const player = this.player; - - return classNames( - "board", - `board--${turn}-to-move`, - `board--player-is-${player}` - ); - } - - render() { - return ( -
- - - -
- {this.renderSquares()} -
- - -
- ); - } -} - -function mapStateToProps(state) { - return { - board: state.board, - selectedSquare: state.selectedSquare, - }; -} - -export default connect(mapStateToProps)(ChessBoard); diff --git a/assets/js/components/file-labels.js b/assets/js/components/file-labels.js deleted file mode 100644 index 0f89ca7..0000000 --- a/assets/js/components/file-labels.js +++ /dev/null @@ -1,22 +0,0 @@ -import React from "react"; -import _ from "lodash"; - -const FILE_LABELS = ["a", "b", "c", "d", "e", "f", "g", "h"]; - -const renderFileLabels = () => { - return _.map(FILE_LABELS, (fileLabel) => { - return ( -
{fileLabel}
- ); - }); -}; - -const FileLabels = () => { - return ( -
- {renderFileLabels()} -
- ); -}; - -export default FileLabels; diff --git a/assets/js/components/game-info.js b/assets/js/components/game-info.js deleted file mode 100644 index a153d1b..0000000 --- a/assets/js/components/game-info.js +++ /dev/null @@ -1,41 +0,0 @@ -import React from "react"; -import { connect } from "react-redux"; - -const renderStatus = status => { - if (status == "viewing") { - return ( - viewing - ); - } else { - return ( - offline - ); - } -}; - -const GameInfo = props => { - return ( -
-

- Playing {props.opponent} {renderStatus(props.opponentStatus)} -

-
- ); -}; - -const mapStateToProps = state => { - return { - opponent: state.opponent, - opponentStatus: state.opponentStatus, - }; -}; - -export default connect(mapStateToProps)(GameInfo); diff --git a/assets/js/components/game-state.js b/assets/js/components/game-state.js deleted file mode 100644 index c3e39fa..0000000 --- a/assets/js/components/game-state.js +++ /dev/null @@ -1,26 +0,0 @@ -import React from "react"; -import classNames from "classnames"; - -const GAME_STATES = { - checkmate: "Checkmate!", - stalemate: "Stalemate", - check: "Check", -}; - -const friendlyGameState = (state) => { - return GAME_STATES[state]; -}; - -const gameStateClass = (state) => { - return classNames("game-state", `game-state--${state}`); -}; - -const GameState = (props) => { - return ( -
- {friendlyGameState(props.gameState)} -
- ); -}; - -export default GameState; diff --git a/assets/js/components/game.js b/assets/js/components/game.js deleted file mode 100644 index d2cb8cb..0000000 --- a/assets/js/components/game.js +++ /dev/null @@ -1,65 +0,0 @@ -"use strict"; - -import "phoenix_html"; - -import React from "react"; -import ReactDOM from "react-dom"; - -import Channel from "../services/channel"; -import Notifications from "../services/notifications"; - -import { setGameId } from "../store/actions"; -import Listeners from "../store/listeners"; - -import ChessBoard from "./chess-board"; -import MoveList from "./move-list"; -import GameInfo from "./game-info"; - -const notifications = new Notifications(); - -class Game extends React.Component { - componentWillMount() { - const { gameId, store } = this.props; - - store.dispatch(setGameId(gameId)); - - this.listeners = new Listeners(store); - this.listeners.setListeners(notifications); - - this.channel = new Channel(store, gameId); - } - - componentWillUnmount() { - this.channel.leave(); - } - - get moves() { - const { store } = this.props; - return store.getState().moves; - } - - get opponent() { - const { store } = this.props; - return store.getState().opponent; - } - - render() { - const { store, gameId } = this.props; - - return ( -
- - - - - -
- ); - } -} - -export default Game; diff --git a/assets/js/components/move-list.js b/assets/js/components/move-list.js deleted file mode 100644 index b1b2c9a..0000000 --- a/assets/js/components/move-list.js +++ /dev/null @@ -1,78 +0,0 @@ -import React from "react"; -import _ from "lodash"; -import { connect } from "react-redux"; -import classNames from "classnames"; - -const pieceToNotation = (piece) => { - const pieces = { - pawn: "", - knight: "N", - bishop: "B", - rook: "R", - queen: "Q", - king: "K", - }; - - return pieces[piece.type]; -}; - -const moveClass = (move) => { - return classNames("move-list__move", "move-list__move--" + move.piece.colour); -}; - -const renderMove = (move) => { - if (move != undefined) { - return ( -
- {pieceToNotation(move.piece)} - {move.piece_captured ? "x" : ""} - {move.to} -
{lineNumber++}.
- - - - - - - - - - - {renderMoves(props.moves)} - -
- Move no. - WhiteBlack
-
- ); -}; - -const mapStateToProps = (state) => { - return { - moves: state.moves, - }; -}; - -export default connect(mapStateToProps)(MoveList); diff --git a/assets/js/components/opponent-finder.js b/assets/js/components/opponent-finder.js deleted file mode 100644 index 96995d8..0000000 --- a/assets/js/components/opponent-finder.js +++ /dev/null @@ -1,168 +0,0 @@ -"use strict"; - -import "phoenix_html"; - -import React from "react"; -import ReactDOM from "react-dom"; -import _ from "lodash"; - -import API from "../services/api"; - -class OpponentFinder extends React.Component { - constructor(props) { - super(props); - - this.state = { - queryString: "", - foundOpponents: [], - selectedOpponent: "", - selectedOpponentId: "", - focusedOpponent: null, - }; - - this.opponentResults = []; - - this.debouncedSearch = _.debounce(this.search.bind(this), 250); - } - - componentDidUpdate() { - if (this.state.focusedOpponent !== null) { - this.opponentResults[this.state.focusedOpponent].focus(); - } - } - - search() { - if (this.state.queryString != "") { - API.findOpponent(this.state.queryString) - .then((response) => { - this.setState({ foundOpponents: response.data.opponents }); - }); - } else { - this.setState({ foundOpponents: [] }); - } - } - - handleChange(event) { - this.setState({ queryString: event.target.value }); - this.debouncedSearch(); - } - - handleFocus(event) { - if (this.state.selectedOpponent) { - this.setState({ queryString: "" }); - } - } - - handleBlur(event) { - if (this.state.selectedOpponent) { - this.setState({ queryString: this.state.selectedOpponent.name }); - } - } - - handleKeyPress(event) { - if (this.isKeyingDown(event)) { this.focusNextOpponent(); } - if (this.isKeyingUp(event)) { this.focusPreviousOpponent(); } - } - - isKeyingDown(event) { - return event.key === "ArrowDown" || (event.key === "Tab" && !event.shiftKey); - } - - isKeyingUp(event) { - return event.key === "ArrowUp" || (event.key === "Tab" && event.shiftKey); - } - - focusNextOpponent() { - if (this.state.focusedOpponent === null) { - this.setState({ focusedOpponent: 0 }); - } else if (this.state.focusedOpponent < this.state.foundOpponents.length - 1) { - this.setState({ focusedOpponent: this.state.focusedOpponent + 1 }); - } - } - - focusPreviousOpponent() { - if (this.state.focusedOpponent > 0) { - this.setState({ focusedOpponent: this.state.focusedOpponent - 1 }); - } else { - this.setState({ focusedOpponent: null }); - this.queryStringInput.select(); - } - } - - selectOpponent(event) { - event.preventDefault(); - - const selectedOpponentId = event.target.attributes["data-id"].value; - const selectedOpponent = _.find(this.state.foundOpponents, (opponent) => { - return opponent.id == selectedOpponentId; - }); - - this.setState({ - selectedOpponentId, - selectedOpponent, - foundOpponents: [], - queryString: selectedOpponent.name, - focusedOpponent: null, - }); - } - - renderOpponents() { - return _.map(this.state.foundOpponents, (opponent, index) => { - return ( -
  • - { this.opponentResults[index] = link; }} - data-id={opponent.id} - href="#" - onClick={this.selectOpponent.bind(this)} - >{opponent.name} -
  • - ); - }); - } - - renderOpponentsResult() { - if (this.state.foundOpponents.length) { - return ( -
      - {this.renderOpponents()} -
    - ); - } - } - - render() { - const { store, gameId } = this.props; - - return ( -
    - - { this.queryStringInput = input; }} - className="search-input" - name="q" - value={this.state.queryString} - onChange={this.handleChange.bind(this)} - onFocus={this.handleFocus.bind(this)} - onBlur={this.handleBlur.bind(this)} - type="text" - autoComplete="off" - /> - - - {this.renderOpponentsResult()} -
    - ); - } -} - -export default OpponentFinder; diff --git a/assets/js/components/rank-labels.js b/assets/js/components/rank-labels.js deleted file mode 100644 index c8abc97..0000000 --- a/assets/js/components/rank-labels.js +++ /dev/null @@ -1,22 +0,0 @@ -import React from "react"; -import _ from "lodash"; - -const RANK_LABELS = [1, 2, 3, 4, 5, 6, 7, 8]; - -const renderRankLabels = () => { - return _.map(RANK_LABELS, (rankLabel) => { - return ( -
    {rankLabel}
    - ); - }); -}; - -const RankLabels = () => { - return ( -
    - {renderRankLabels()} -
    - ); -}; - -export default RankLabels; diff --git a/assets/js/reducers/chess-board.js b/assets/js/reducers/chess-board.js deleted file mode 100644 index 0b4f130..0000000 --- a/assets/js/reducers/chess-board.js +++ /dev/null @@ -1,56 +0,0 @@ -import Immutable from "immutable"; - -import defaultState from "../store/default-state"; - -const chessBoardReducer = (state = defaultState, action) => { - switch (action.type) { - case "SET_USER_ID": - return Immutable.fromJS(state) - .set("userId", action.user_id) - .toJS(); - - case "SET_PLAYERS": - return Immutable.fromJS(state) - .set("player", action.player) - .set("playerId", action.player_id) - .set("opponent", action.opponent) - .set("opponentId", action.opponent_id) - .toJS(); - - case "SET_GAME": - return Immutable.fromJS(state) - .set("board", action.board) - .set("turn", action.turn) - .set("state", action.state) - .set("selectedSquare", null) - .set("availableMoves", []) - .set("moves", action.moves) - .toJS(); - - case "SET_AVAILABLE_MOVES": - return Immutable.fromJS(state) - .set("availableMoves", action.availableMoves) - .toJS(); - - case "SET_GAME_ID": - return Immutable.fromJS(state) - .set("gameId", action.gameId) - .toJS(); - - case "SELECT_PIECE": - return Immutable.fromJS(state) - .set("selectedSquare", action.coords) - .set("availableMoves", []) - .toJS(); - - case "SET_OPPONENT_STATUS": - return Immutable.fromJS(state) - .set("opponentStatus", action.opponentStatus) - .toJS(); - - default: - return state; - } -}; - -export default chessBoardReducer; diff --git a/assets/js/services/api.js b/assets/js/services/api.js deleted file mode 100644 index b4c2fdd..0000000 --- a/assets/js/services/api.js +++ /dev/null @@ -1,9 +0,0 @@ -import axios from "axios"; - -const API = { - findOpponent: (queryString) => { - return axios.get("/api/opponents", { params: { q: queryString } }); - }, -}; - -export default API; diff --git a/assets/js/services/channel.js b/assets/js/services/channel.js deleted file mode 100644 index 8119d62..0000000 --- a/assets/js/services/channel.js +++ /dev/null @@ -1,85 +0,0 @@ -import _ from "lodash"; -import socket from "./socket"; -import Presences from "./presences"; -import { - setUserId, - setPlayers, - setGame, - setAvailableMoves, - setOpponentStatus, -} from "../store/actions"; - -class Channel { - constructor(store, gameId) { - this.store = store; - this.channel = socket.channel(`game:${gameId}`, {}); - this.presences = new Presences(); - - this.join(); - this.subscribe(); - } - - get opponentId() { - return this.store.getState().opponentId; - } - - join() { - this.channel - .join() - .receive("error", resp => { - console.log("Unable to join", resp); - }); - } - - leave() { - this.channel.leave(); - } - - subscribe() { - this.channel.on("game:update", this.updateGame.bind(this)); - - this.channel.on("presence_state", data => { - this.presences.syncState(data); - this.setOpponentStatus(); - }); - - this.channel.on("presence_diff", data => { - this.presences.syncDiff(data); - this.setOpponentStatus(); - }); - } - - updateGame(data) { - if (data.player != undefined) { - this.store.dispatch(setUserId(data.user_id)); - this.store.dispatch(setPlayers(data)); - } - this.store.dispatch(setGame(data)); - } - - setOpponentStatus() { - this.store.dispatch( - setOpponentStatus( - this.presences.opponentOnline(this.opponentId) ? "viewing" : "offline" - ) - ); - } - - getAvailableMoves(square) { - this.channel - .push("game:get_available_moves", { square }) - .receive("ok", data => { - this.store.dispatch(setAvailableMoves(data.moves)); - }); - } - - sendMove(move) { - this.channel - .push("game:move", move) - .receive("error", resp => { - alert(resp.message); - }); - } -} - -export default Channel; diff --git a/assets/js/services/notifications.js b/assets/js/services/notifications.js deleted file mode 100644 index bec9df9..0000000 --- a/assets/js/services/notifications.js +++ /dev/null @@ -1,26 +0,0 @@ -class Notifications { - constructor() { - if (this.notifications_available) { - Notification.requestPermission(); - } - } - - notifyTurn(player) { - this.notify({ - body: "Your opponent has moved.", - icon: `/images/king_${player}.svg`, - }); - } - - notify(options) { - if (this.notifications_available && !document.hasFocus()) { - new Notification("Chess", options); - } - } - - get notifications_available() { - window.Notification != undefined; - } -} - -export default Notifications; diff --git a/assets/js/services/presences.js b/assets/js/services/presences.js deleted file mode 100644 index 4d88833..0000000 --- a/assets/js/services/presences.js +++ /dev/null @@ -1,24 +0,0 @@ -import _ from "lodash"; -import { Presence } from "phoenix"; - -class Presences { - constructor() { - this.presences = {}; - } - - syncState(data) { - this.presences = Presence.syncState(this.presences, data); - } - - syncDiff(data) { - this.presences = Presence.syncDiff(this.presences, data); - } - - opponentOnline(opponentId) { - return _.find(this.presences, (value, id) => { - return parseInt(id) == opponentId; - }); - } -} - -export default Presences; diff --git a/assets/js/services/socket.js b/assets/js/services/socket.js deleted file mode 100644 index 617ea09..0000000 --- a/assets/js/services/socket.js +++ /dev/null @@ -1,58 +0,0 @@ -// NOTE: The contents of this file will only be executed if -// you uncomment its entry in "web/static/js/app.js". - -// To use Phoenix channels, the first step is to import Socket -// and connect at the socket path in "lib/my_app/endpoint.ex": -import { Socket } from "phoenix"; - -let socket = new Socket("/socket", { params: { token: window.userToken } }); - -// When you connect, you'll often need to authenticate the client. -// For example, imagine you have an authentication plug, `MyAuth`, -// which authenticates the session and assigns a `:current_user`. -// If the current user exists you can assign the user's token in -// the connection for use in the layout. -// -// In your "web/router.ex": -// -// pipeline :browser do -// ... -// plug MyAuth -// plug :put_user_token -// end -// -// defp put_user_token(conn, _) do -// if current_user = conn.assigns[:current_user] do -// token = Phoenix.Token.sign(conn, "user socket", current_user.id) -// assign(conn, :user_token, token) -// else -// conn -// end -// end -// -// Now you need to pass this token to JavaScript. You can do so -// inside a script tag in "web/templates/layout/app.html.eex": -// -// -// -// You will need to verify the user token in the "connect/2" function -// in "web/channels/user_socket.ex": -// -// def connect(%{"token" => token}, socket) do -// # max_age: 1209600 is equivalent to two weeks in seconds -// case Phoenix.Token.verify(socket, "user socket", token, max_age: 1209600) do -// {:ok, user_id} -> -// {:ok, assign(socket, :user, user_id)} -// {:error, reason} -> -// :error -// end -// end -// -// Finally, pass the token on connect as below. Or remove it -// from connect if you don't care about authentication. - -if (window.userToken) { - socket.connect(); -} - -export default socket; diff --git a/assets/js/store/actions.js b/assets/js/store/actions.js deleted file mode 100644 index 152e9f7..0000000 --- a/assets/js/store/actions.js +++ /dev/null @@ -1,62 +0,0 @@ -const SET_USER_ID = "SET_USER_ID"; -const SET_PLAYERS = "SET_PLAYERS"; -const SET_GAME = "SET_GAME"; -const SET_AVAILABLE_MOVES = "SET_AVAILABLE_MOVES"; -const SET_GAME_ID = "SET_GAME_ID"; -const SELECT_PIECE = "SELECT_PIECE"; -const SET_OPPONENT_STATUS = "SET_OPPONENT_STATUS"; - -export const setUserId = (user_id) => { - return { - type: SET_USER_ID, - user_id, - }; -}; - -export const setPlayers = (data) => { - return { - type: SET_PLAYERS, - player: data.player, - player_id: data.player_id, - opponent: data.opponent, - opponent_id: data.opponent_id, - }; -}; - -export const setGame = (data) => { - return { - type: SET_GAME, - board: data.board, - turn: data.turn, - moves: data.moves, - state: data.state, - }; -}; - -export const setAvailableMoves = (availableMoves) => { - return { - type: SET_AVAILABLE_MOVES, - availableMoves, - }; -}; - -export const setGameId = (gameId) => { - return { - type: SET_GAME_ID, - gameId, - }; -}; - -export const selectPiece = (coords) => { - return { - type: SELECT_PIECE, - coords, - }; -}; - -export const setOpponentStatus = (opponentStatus) => { - return { - type: SET_OPPONENT_STATUS, - opponentStatus, - }; -}; diff --git a/assets/js/store/default-state.js b/assets/js/store/default-state.js deleted file mode 100644 index 801d13c..0000000 --- a/assets/js/store/default-state.js +++ /dev/null @@ -1,30 +0,0 @@ -const defaultState = { - selectedSquare: null, - - playerId: null, - opponentId: null, - - player: null, - opponent: null, - turn: null, - state: null, - - opponentStatus: "offline", - - availableMoves: [], - - moves: [], - - board: { - 8: { a: null, b: null, c: null, d: null, e: null, f: null, g: null, h: null }, - 7: { a: null, b: null, c: null, d: null, e: null, f: null, g: null, h: null }, - 6: { a: null, b: null, c: null, d: null, e: null, f: null, g: null, h: null }, - 5: { a: null, b: null, c: null, d: null, e: null, f: null, g: null, h: null }, - 4: { a: null, b: null, c: null, d: null, e: null, f: null, g: null, h: null }, - 3: { a: null, b: null, c: null, d: null, e: null, f: null, g: null, h: null }, - 2: { a: null, b: null, c: null, d: null, e: null, f: null, g: null, h: null }, - 1: { a: null, b: null, c: null, d: null, e: null, f: null, g: null, h: null }, - }, -}; - -export default defaultState; diff --git a/assets/js/store/listeners.js b/assets/js/store/listeners.js deleted file mode 100644 index d3f58c0..0000000 --- a/assets/js/store/listeners.js +++ /dev/null @@ -1,27 +0,0 @@ -import watch from "redux-watch"; - -class Listeners { - constructor(store) { - this.store = store; - } - - setListeners(notifications) { - this.notifications = notifications; - - let watcher = watch(this.store.getState, "turn"); - - this.store.subscribe( - watcher(this.notifyTurn.bind(this)) - ); - } - - notifyTurn(newVal, oldVal) { - const player = this.store.getState().player; - - if (oldVal != null && newVal == player) { - this.notifications.notifyTurn(player); - } - } -}; - -export default Listeners; diff --git a/assets/package-lock.json b/assets/package-lock.json new file mode 100644 index 0000000..2f36c38 --- /dev/null +++ b/assets/package-lock.json @@ -0,0 +1,578 @@ +{ + "name": "assets", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "license": "MIT", + "dependencies": { + "esbuild": "^0.19", + "phoenix": "file:../deps/phoenix", + "phoenix_html": "file:../deps/phoenix_html", + "phoenix_live_view": "file:../deps/phoenix_live_view" + }, + "devDependencies": {} + }, + "../deps/phoenix": { + "version": "1.7.9", + "license": "MIT" + }, + "../deps/phoenix_html": { + "version": "3.3.3" + }, + "../deps/phoenix_live_view": { + "version": "0.20.1", + "license": "MIT" + }, + "node_modules/@esbuild/android-arm": { + "version": "0.19.4", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.4.tgz", + "integrity": "sha512-uBIbiYMeSsy2U0XQoOGVVcpIktjLMEKa7ryz2RLr7L/vTnANNEsPVAh4xOv7ondGz6ac1zVb0F8Jx20rQikffQ==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.19.4", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.4.tgz", + "integrity": "sha512-mRsi2vJsk4Bx/AFsNBqOH2fqedxn5L/moT58xgg51DjX1la64Z3Npicut2VbhvDFO26qjWtPMsVxCd80YTFVeg==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.19.4", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.4.tgz", + "integrity": "sha512-4iPufZ1TMOD3oBlGFqHXBpa3KFT46aLl6Vy7gwed0ZSYgHaZ/mihbYb4t7Z9etjkC9Al3ZYIoOaHrU60gcMy7g==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.19.4", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.4.tgz", + "integrity": "sha512-Lviw8EzxsVQKpbS+rSt6/6zjn9ashUZ7Tbuvc2YENgRl0yZTktGlachZ9KMJUsVjZEGFVu336kl5lBgDN6PmpA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.19.4", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.4.tgz", + "integrity": "sha512-YHbSFlLgDwglFn0lAO3Zsdrife9jcQXQhgRp77YiTDja23FrC2uwnhXMNkAucthsf+Psr7sTwYEryxz6FPAVqw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.19.4", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.4.tgz", + "integrity": "sha512-vz59ijyrTG22Hshaj620e5yhs2dU1WJy723ofc+KUgxVCM6zxQESmWdMuVmUzxtGqtj5heHyB44PjV/HKsEmuQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.19.4", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.4.tgz", + "integrity": "sha512-3sRbQ6W5kAiVQRBWREGJNd1YE7OgzS0AmOGjDmX/qZZecq8NFlQsQH0IfXjjmD0XtUYqr64e0EKNFjMUlPL3Cw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.19.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.4.tgz", + "integrity": "sha512-z/4ArqOo9EImzTi4b6Vq+pthLnepFzJ92BnofU1jgNlcVb+UqynVFdoXMCFreTK7FdhqAzH0vmdwW5373Hm9pg==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.19.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.4.tgz", + "integrity": "sha512-ZWmWORaPbsPwmyu7eIEATFlaqm0QGt+joRE9sKcnVUG3oBbr/KYdNE2TnkzdQwX6EDRdg/x8Q4EZQTXoClUqqA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.19.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.4.tgz", + "integrity": "sha512-EGc4vYM7i1GRUIMqRZNCTzJh25MHePYsnQfKDexD8uPTCm9mK56NIL04LUfX2aaJ+C9vyEp2fJ7jbqFEYgO9lQ==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.19.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.4.tgz", + "integrity": "sha512-WVhIKO26kmm8lPmNrUikxSpXcgd6HDog0cx12BUfA2PkmURHSgx9G6vA19lrlQOMw+UjMZ+l3PpbtzffCxFDRg==", + "cpu": [ + "loong64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.19.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.4.tgz", + "integrity": "sha512-keYY+Hlj5w86hNp5JJPuZNbvW4jql7c1eXdBUHIJGTeN/+0QFutU3GrS+c27L+NTmzi73yhtojHk+lr2+502Mw==", + "cpu": [ + "mips64el" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.19.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.4.tgz", + "integrity": "sha512-tQ92n0WMXyEsCH4m32S21fND8VxNiVazUbU4IUGVXQpWiaAxOBvtOtbEt3cXIV3GEBydYsY8pyeRMJx9kn3rvw==", + "cpu": [ + "ppc64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.19.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.4.tgz", + "integrity": "sha512-tRRBey6fG9tqGH6V75xH3lFPpj9E8BH+N+zjSUCnFOX93kEzqS0WdyJHkta/mmJHn7MBaa++9P4ARiU4ykjhig==", + "cpu": [ + "riscv64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.19.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.4.tgz", + "integrity": "sha512-152aLpQqKZYhThiJ+uAM4PcuLCAOxDsCekIbnGzPKVBRUDlgaaAfaUl5NYkB1hgY6WN4sPkejxKlANgVcGl9Qg==", + "cpu": [ + "s390x" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.19.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.4.tgz", + "integrity": "sha512-Mi4aNA3rz1BNFtB7aGadMD0MavmzuuXNTaYL6/uiYIs08U7YMPETpgNn5oue3ICr+inKwItOwSsJDYkrE9ekVg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.19.4", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.4.tgz", + "integrity": "sha512-9+Wxx1i5N/CYo505CTT7T+ix4lVzEdz0uCoYGxM5JDVlP2YdDC1Bdz+Khv6IbqmisT0Si928eAxbmGkcbiuM/A==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.19.4", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.4.tgz", + "integrity": "sha512-MFsHleM5/rWRW9EivFssop+OulYVUoVcqkyOkjiynKBCGBj9Lihl7kh9IzrreDyXa4sNkquei5/DTP4uCk25xw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.19.4", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.4.tgz", + "integrity": "sha512-6Xq8SpK46yLvrGxjp6HftkDwPP49puU4OF0hEL4dTxqCbfx09LyrbUj/D7tmIRMj5D5FCUPksBbxyQhp8tmHzw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.19.4", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.4.tgz", + "integrity": "sha512-PkIl7Jq4mP6ke7QKwyg4fD4Xvn8PXisagV/+HntWoDEdmerB2LTukRZg728Yd1Fj+LuEX75t/hKXE2Ppk8Hh1w==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.19.4", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.4.tgz", + "integrity": "sha512-ga676Hnvw7/ycdKB53qPusvsKdwrWzEyJ+AtItHGoARszIqvjffTwaaW3b2L6l90i7MO9i+dlAW415INuRhSGg==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.19.4", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.4.tgz", + "integrity": "sha512-HP0GDNla1T3ZL8Ko/SHAS2GgtjOg+VmWnnYLhuTksr++EnduYB0f3Y2LzHsUwb2iQ13JGoY6G3R8h6Du/WG6uA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild": { + "version": "0.19.4", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.4.tgz", + "integrity": "sha512-x7jL0tbRRpv4QUyuDMjONtWFciygUxWaUM1kMX2zWxI0X2YWOt7MSA0g4UdeSiHM8fcYVzpQhKYOycZwxTdZkA==", + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/android-arm": "0.19.4", + "@esbuild/android-arm64": "0.19.4", + "@esbuild/android-x64": "0.19.4", + "@esbuild/darwin-arm64": "0.19.4", + "@esbuild/darwin-x64": "0.19.4", + "@esbuild/freebsd-arm64": "0.19.4", + "@esbuild/freebsd-x64": "0.19.4", + "@esbuild/linux-arm": "0.19.4", + "@esbuild/linux-arm64": "0.19.4", + "@esbuild/linux-ia32": "0.19.4", + "@esbuild/linux-loong64": "0.19.4", + "@esbuild/linux-mips64el": "0.19.4", + "@esbuild/linux-ppc64": "0.19.4", + "@esbuild/linux-riscv64": "0.19.4", + "@esbuild/linux-s390x": "0.19.4", + "@esbuild/linux-x64": "0.19.4", + "@esbuild/netbsd-x64": "0.19.4", + "@esbuild/openbsd-x64": "0.19.4", + "@esbuild/sunos-x64": "0.19.4", + "@esbuild/win32-arm64": "0.19.4", + "@esbuild/win32-ia32": "0.19.4", + "@esbuild/win32-x64": "0.19.4" + } + }, + "node_modules/phoenix": { + "resolved": "../deps/phoenix", + "link": true + }, + "node_modules/phoenix_html": { + "resolved": "../deps/phoenix_html", + "link": true + }, + "node_modules/phoenix_live_view": { + "resolved": "../deps/phoenix_live_view", + "link": true + } + }, + "dependencies": { + "@esbuild/android-arm": { + "version": "0.19.4", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.4.tgz", + "integrity": "sha512-uBIbiYMeSsy2U0XQoOGVVcpIktjLMEKa7ryz2RLr7L/vTnANNEsPVAh4xOv7ondGz6ac1zVb0F8Jx20rQikffQ==", + "optional": true + }, + "@esbuild/android-arm64": { + "version": "0.19.4", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.4.tgz", + "integrity": "sha512-mRsi2vJsk4Bx/AFsNBqOH2fqedxn5L/moT58xgg51DjX1la64Z3Npicut2VbhvDFO26qjWtPMsVxCd80YTFVeg==", + "optional": true + }, + "@esbuild/android-x64": { + "version": "0.19.4", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.4.tgz", + "integrity": "sha512-4iPufZ1TMOD3oBlGFqHXBpa3KFT46aLl6Vy7gwed0ZSYgHaZ/mihbYb4t7Z9etjkC9Al3ZYIoOaHrU60gcMy7g==", + "optional": true + }, + "@esbuild/darwin-arm64": { + "version": "0.19.4", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.4.tgz", + "integrity": "sha512-Lviw8EzxsVQKpbS+rSt6/6zjn9ashUZ7Tbuvc2YENgRl0yZTktGlachZ9KMJUsVjZEGFVu336kl5lBgDN6PmpA==", + "optional": true + }, + "@esbuild/darwin-x64": { + "version": "0.19.4", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.4.tgz", + "integrity": "sha512-YHbSFlLgDwglFn0lAO3Zsdrife9jcQXQhgRp77YiTDja23FrC2uwnhXMNkAucthsf+Psr7sTwYEryxz6FPAVqw==", + "optional": true + }, + "@esbuild/freebsd-arm64": { + "version": "0.19.4", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.4.tgz", + "integrity": "sha512-vz59ijyrTG22Hshaj620e5yhs2dU1WJy723ofc+KUgxVCM6zxQESmWdMuVmUzxtGqtj5heHyB44PjV/HKsEmuQ==", + "optional": true + }, + "@esbuild/freebsd-x64": { + "version": "0.19.4", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.4.tgz", + "integrity": "sha512-3sRbQ6W5kAiVQRBWREGJNd1YE7OgzS0AmOGjDmX/qZZecq8NFlQsQH0IfXjjmD0XtUYqr64e0EKNFjMUlPL3Cw==", + "optional": true + }, + "@esbuild/linux-arm": { + "version": "0.19.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.4.tgz", + "integrity": "sha512-z/4ArqOo9EImzTi4b6Vq+pthLnepFzJ92BnofU1jgNlcVb+UqynVFdoXMCFreTK7FdhqAzH0vmdwW5373Hm9pg==", + "optional": true + }, + "@esbuild/linux-arm64": { + "version": "0.19.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.4.tgz", + "integrity": "sha512-ZWmWORaPbsPwmyu7eIEATFlaqm0QGt+joRE9sKcnVUG3oBbr/KYdNE2TnkzdQwX6EDRdg/x8Q4EZQTXoClUqqA==", + "optional": true + }, + "@esbuild/linux-ia32": { + "version": "0.19.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.4.tgz", + "integrity": "sha512-EGc4vYM7i1GRUIMqRZNCTzJh25MHePYsnQfKDexD8uPTCm9mK56NIL04LUfX2aaJ+C9vyEp2fJ7jbqFEYgO9lQ==", + "optional": true + }, + "@esbuild/linux-loong64": { + "version": "0.19.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.4.tgz", + "integrity": "sha512-WVhIKO26kmm8lPmNrUikxSpXcgd6HDog0cx12BUfA2PkmURHSgx9G6vA19lrlQOMw+UjMZ+l3PpbtzffCxFDRg==", + "optional": true + }, + "@esbuild/linux-mips64el": { + "version": "0.19.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.4.tgz", + "integrity": "sha512-keYY+Hlj5w86hNp5JJPuZNbvW4jql7c1eXdBUHIJGTeN/+0QFutU3GrS+c27L+NTmzi73yhtojHk+lr2+502Mw==", + "optional": true + }, + "@esbuild/linux-ppc64": { + "version": "0.19.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.4.tgz", + "integrity": "sha512-tQ92n0WMXyEsCH4m32S21fND8VxNiVazUbU4IUGVXQpWiaAxOBvtOtbEt3cXIV3GEBydYsY8pyeRMJx9kn3rvw==", + "optional": true + }, + "@esbuild/linux-riscv64": { + "version": "0.19.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.4.tgz", + "integrity": "sha512-tRRBey6fG9tqGH6V75xH3lFPpj9E8BH+N+zjSUCnFOX93kEzqS0WdyJHkta/mmJHn7MBaa++9P4ARiU4ykjhig==", + "optional": true + }, + "@esbuild/linux-s390x": { + "version": "0.19.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.4.tgz", + "integrity": "sha512-152aLpQqKZYhThiJ+uAM4PcuLCAOxDsCekIbnGzPKVBRUDlgaaAfaUl5NYkB1hgY6WN4sPkejxKlANgVcGl9Qg==", + "optional": true + }, + "@esbuild/linux-x64": { + "version": "0.19.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.4.tgz", + "integrity": "sha512-Mi4aNA3rz1BNFtB7aGadMD0MavmzuuXNTaYL6/uiYIs08U7YMPETpgNn5oue3ICr+inKwItOwSsJDYkrE9ekVg==", + "optional": true + }, + "@esbuild/netbsd-x64": { + "version": "0.19.4", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.4.tgz", + "integrity": "sha512-9+Wxx1i5N/CYo505CTT7T+ix4lVzEdz0uCoYGxM5JDVlP2YdDC1Bdz+Khv6IbqmisT0Si928eAxbmGkcbiuM/A==", + "optional": true + }, + "@esbuild/openbsd-x64": { + "version": "0.19.4", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.4.tgz", + "integrity": "sha512-MFsHleM5/rWRW9EivFssop+OulYVUoVcqkyOkjiynKBCGBj9Lihl7kh9IzrreDyXa4sNkquei5/DTP4uCk25xw==", + "optional": true + }, + "@esbuild/sunos-x64": { + "version": "0.19.4", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.4.tgz", + "integrity": "sha512-6Xq8SpK46yLvrGxjp6HftkDwPP49puU4OF0hEL4dTxqCbfx09LyrbUj/D7tmIRMj5D5FCUPksBbxyQhp8tmHzw==", + "optional": true + }, + "@esbuild/win32-arm64": { + "version": "0.19.4", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.4.tgz", + "integrity": "sha512-PkIl7Jq4mP6ke7QKwyg4fD4Xvn8PXisagV/+HntWoDEdmerB2LTukRZg728Yd1Fj+LuEX75t/hKXE2Ppk8Hh1w==", + "optional": true + }, + "@esbuild/win32-ia32": { + "version": "0.19.4", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.4.tgz", + "integrity": "sha512-ga676Hnvw7/ycdKB53qPusvsKdwrWzEyJ+AtItHGoARszIqvjffTwaaW3b2L6l90i7MO9i+dlAW415INuRhSGg==", + "optional": true + }, + "@esbuild/win32-x64": { + "version": "0.19.4", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.4.tgz", + "integrity": "sha512-HP0GDNla1T3ZL8Ko/SHAS2GgtjOg+VmWnnYLhuTksr++EnduYB0f3Y2LzHsUwb2iQ13JGoY6G3R8h6Du/WG6uA==", + "optional": true + }, + "esbuild": { + "version": "0.19.4", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.4.tgz", + "integrity": "sha512-x7jL0tbRRpv4QUyuDMjONtWFciygUxWaUM1kMX2zWxI0X2YWOt7MSA0g4UdeSiHM8fcYVzpQhKYOycZwxTdZkA==", + "requires": { + "@esbuild/android-arm": "0.19.4", + "@esbuild/android-arm64": "0.19.4", + "@esbuild/android-x64": "0.19.4", + "@esbuild/darwin-arm64": "0.19.4", + "@esbuild/darwin-x64": "0.19.4", + "@esbuild/freebsd-arm64": "0.19.4", + "@esbuild/freebsd-x64": "0.19.4", + "@esbuild/linux-arm": "0.19.4", + "@esbuild/linux-arm64": "0.19.4", + "@esbuild/linux-ia32": "0.19.4", + "@esbuild/linux-loong64": "0.19.4", + "@esbuild/linux-mips64el": "0.19.4", + "@esbuild/linux-ppc64": "0.19.4", + "@esbuild/linux-riscv64": "0.19.4", + "@esbuild/linux-s390x": "0.19.4", + "@esbuild/linux-x64": "0.19.4", + "@esbuild/netbsd-x64": "0.19.4", + "@esbuild/openbsd-x64": "0.19.4", + "@esbuild/sunos-x64": "0.19.4", + "@esbuild/win32-arm64": "0.19.4", + "@esbuild/win32-ia32": "0.19.4", + "@esbuild/win32-x64": "0.19.4" + } + }, + "phoenix": { + "version": "file:../deps/phoenix" + }, + "phoenix_html": { + "version": "file:../deps/phoenix_html" + }, + "phoenix_live_view": { + "version": "file:../deps/phoenix_live_view" + } + } +} diff --git a/assets/package.json b/assets/package.json index 522a7cc..02ba74d 100644 --- a/assets/package.json +++ b/assets/package.json @@ -6,25 +6,10 @@ "deploy": "cd .. && mix assets.deploy && rm -f _build/esbuild" }, "dependencies": { - "@babel/polyfill": "^7.12.1", - "axios": "^0.21.0", - "classnames": "^2.3.1", - "esbuild": "^0.14.21", - "gettext.js": "^1.0.0", - "immutable": "^3.8.2", - "lodash": "^4.17.21", - "phoenix": "^1.7.0-rc.2", - "phoenix_html": "^3.2.0", - "phoenix_live_view": "^0.18.11", - "react": "^17.0.2", - "react-dom": "^17.0.2", - "react-redux": "^7.2.4", - "redux": "^4.1.0", - "redux-watch": "^1.2.0", - "url-loader": "^4.1.1" + "phoenix": "file:../deps/phoenix", + "phoenix_html": "file:../deps/phoenix_html", + "phoenix_live_view": "file:../deps/phoenix_live_view" }, "devDependencies": { - "css-loader": "^5.2.6", - "mini-css-extract-plugin": "^1.6.0" } } diff --git a/assets/yarn-error.log b/assets/yarn-error.log deleted file mode 100644 index 67c9606..0000000 --- a/assets/yarn-error.log +++ /dev/null @@ -1,734 +0,0 @@ -Arguments: - /Users/danbarber/.asdf/installs/nodejs/16.14.0/bin/node /Users/danbarber/.asdf/installs/yarn/1.22.10/bin/yarn.js add phoenix phoenix_html phoenix_live_view - -PATH: - /Users/danbarber/.asdf/plugins/nodejs/shims:/Users/danbarber/.asdf/installs/nodejs/16.14.0/bin:/Users/danbarber/.asdf/installs/yarn/1.22.10/bin:/Users/danbarber/.bin:/usr/local/share/npm/bin:.git/safe/../../bin:/Users/danbarber/.asdf/shims:/opt/homebrew/bin/../opt/asdf/libexec/bin:/usr/local/sbin:/opt/homebrew/bin:/opt/homebrew/sbin:/usr/local/bin:/System/Cryptexes/App/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Applications/VMware Fusion.app/Contents/Public:/usr/local/zfs/bin:/opt/X11/bin:/Library/Apple/usr/bin:/Applications/Wireshark.app/Contents/MacOS:/Applications/kitty.app/Contents/MacOS:/Users/danbarber/.fzf/bin - -Yarn version: - 1.22.10 - -Node version: - 16.14.0 - -Platform: - darwin arm64 - -Trace: - Error: ENOENT: no such file or directory, open '/Users/danbarber/Library/Caches/Yarn/v6/npm-esbuild-linux-arm64-0.14.21-e05599ea6253b58394157da162d856f3ead62f9e-integrity/node_modules/esbuild-linux-arm64/.yarn-metadata.json' - -npm manifest: - { - "repository": {}, - "description": " ", - "license": "MIT", - "scripts": { - "deploy": "cd .. && mix assets.deploy && rm -f _build/esbuild" - }, - "dependencies": { - "@babel/polyfill": "^7.12.1", - "axios": "^0.21.0", - "classnames": "^2.3.1", - "esbuild": "^0.14.21", - "gettext.js": "^1.0.0", - "immutable": "^3.8.2", - "lodash": "^4.17.21", - "react": "^17.0.2", - "react-dom": "^17.0.2", - "react-redux": "^7.2.4", - "redux": "^4.1.0", - "redux-watch": "^1.2.0", - "url-loader": "^4.1.1" - }, - "devDependencies": { - "css-loader": "^5.2.6", - "mini-css-extract-plugin": "^1.6.0" - } - } - -yarn manifest: - No manifest - -Lockfile: - # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. - # yarn lockfile v1 - - - "@babel/polyfill@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/polyfill/-/polyfill-7.12.1.tgz#1f2d6371d1261bbd961f3c5d5909150e12d0bd96" - integrity sha512-X0pi0V6gxLi6lFZpGmeNa4zxtwEmCs42isWLNjZZDE0Y8yVfgu0T2OAHlzBbdYlqbW/YXVvoBHpATEM+goCj8g== - dependencies: - core-js "^2.6.5" - regenerator-runtime "^0.13.4" - - "@babel/runtime@^7.12.1", "@babel/runtime@^7.9.2": - version "7.14.6" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.14.6.tgz#535203bc0892efc7dec60bdc27b2ecf6e409062d" - integrity sha512-/PCB2uJ7oM44tz8YhC4Z/6PeOKXp4K588f+5M3clr1M4zbqztlo0XEfJ2LEzj/FgwfgGcIdl8n7YYjTCI0BYwg== - dependencies: - regenerator-runtime "^0.13.4" - - "@types/hoist-non-react-statics@^3.3.0": - version "3.3.1" - resolved "https://registry.yarnpkg.com/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz#1124aafe5118cb591977aeb1ceaaed1070eb039f" - integrity sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA== - dependencies: - "@types/react" "*" - hoist-non-react-statics "^3.3.0" - - "@types/json-schema@^7.0.6": - version "7.0.7" - resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.7.tgz#98a993516c859eb0d5c4c8f098317a9ea68db9ad" - integrity sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA== - - "@types/prop-types@*": - version "15.7.3" - resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.3.tgz#2ab0d5da2e5815f94b0b9d4b95d1e5f243ab2ca7" - integrity sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw== - - "@types/react-redux@^7.1.16": - version "7.1.16" - resolved "https://registry.yarnpkg.com/@types/react-redux/-/react-redux-7.1.16.tgz#0fbd04c2500c12105494c83d4a3e45c084e3cb21" - integrity sha512-f/FKzIrZwZk7YEO9E1yoxIuDNRiDducxkFlkw/GNMGEnK9n4K8wJzlJBghpSuOVDgEUHoDkDF7Gi9lHNQR4siw== - dependencies: - "@types/hoist-non-react-statics" "^3.3.0" - "@types/react" "*" - hoist-non-react-statics "^3.3.0" - redux "^4.0.0" - - "@types/react@*": - version "17.0.11" - resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.11.tgz#67fcd0ddbf5a0b083a0f94e926c7d63f3b836451" - integrity sha512-yFRQbD+whVonItSk7ZzP/L+gPTJVBkL/7shLEF+i9GC/1cV3JmUxEQz6+9ylhUpWSDuqo1N9qEvqS6vTj4USUA== - dependencies: - "@types/prop-types" "*" - "@types/scheduler" "*" - csstype "^3.0.2" - - "@types/scheduler@*": - version "0.16.1" - resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.1.tgz#18845205e86ff0038517aab7a18a62a6b9f71275" - integrity sha512-EaCxbanVeyxDRTQBkdLb3Bvl/HK7PBK6UJjsSixB0iHKoWxE5uu2Q/DgtpOhPIojN0Zl1whvOd7PoHs2P0s5eA== - - ajv-keywords@^3.5.2: - version "3.5.2" - resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" - integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== - - ajv@^6.12.5: - version "6.12.6" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" - integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== - 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" - - ansi-styles@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-1.0.0.tgz#cb102df1c56f5123eab8b67cd7b98027a0279178" - integrity sha1-yxAt8cVvUSPquLZ817mAJ6AnkXg= - - axios@^0.21.0: - version "0.21.1" - resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.1.tgz#22563481962f4d6bde9a76d516ef0e5d3c09b2b8" - integrity sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA== - dependencies: - follow-redirects "^1.10.0" - - big.js@^5.2.2: - version "5.2.2" - resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" - integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ== - - chalk@~0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-0.4.0.tgz#5199a3ddcd0c1efe23bc08c1b027b06176e0c64f" - integrity sha1-UZmj3c0MHv4jvAjBsCewYXbgxk8= - dependencies: - ansi-styles "~1.0.0" - has-color "~0.1.0" - strip-ansi "~0.1.0" - - classnames@^2.3.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.3.1.tgz#dfcfa3891e306ec1dad105d0e88f4417b8535e8e" - integrity sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA== - - colorette@^1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.2.2.tgz#cbcc79d5e99caea2dbf10eb3a26fd8b3e6acfa94" - integrity sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w== - - core-js@^2.6.5: - version "2.6.12" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.12.tgz#d9333dfa7b065e347cc5682219d6f690859cc2ec" - integrity sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ== - - css-loader@^5.2.6: - version "5.2.6" - resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-5.2.6.tgz#c3c82ab77fea1f360e587d871a6811f4450cc8d1" - integrity sha512-0wyN5vXMQZu6BvjbrPdUJvkCzGEO24HC7IS7nW4llc6BBFC+zwR9CKtYGv63Puzsg10L/o12inMY5/2ByzfD6w== - dependencies: - icss-utils "^5.1.0" - loader-utils "^2.0.0" - postcss "^8.2.15" - postcss-modules-extract-imports "^3.0.0" - postcss-modules-local-by-default "^4.0.0" - postcss-modules-scope "^3.0.0" - postcss-modules-values "^4.0.0" - postcss-value-parser "^4.1.0" - schema-utils "^3.0.0" - semver "^7.3.5" - - cssesc@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" - integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== - - csstype@^3.0.2: - version "3.0.8" - resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.0.8.tgz#d2266a792729fb227cd216fb572f43728e1ad340" - integrity sha512-jXKhWqXPmlUeoQnF/EhTtTl4C9SnrxSH/jZUih3jmO6lBKr99rP3/+FmrMj4EFpOXzMtXHAZkd3x0E6h6Fgflw== - - emojis-list@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78" - integrity sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q== - - encoding@^0.1.11: - version "0.1.13" - resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.13.tgz#56574afdd791f54a8e9b2785c0582a2d26210fa9" - integrity sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A== - dependencies: - iconv-lite "^0.6.2" - - esbuild-android-arm64@0.14.21: - version "0.14.21" - resolved "https://registry.yarnpkg.com/esbuild-android-arm64/-/esbuild-android-arm64-0.14.21.tgz#8842d0c3b7c81fbe2dc46ddb416ffd6eb822184b" - integrity sha512-Bqgld1TY0wZv8TqiQmVxQFgYzz8ZmyzT7clXBDZFkOOdRybzsnj8AZuK1pwcLVA7Ya6XncHgJqIao7NFd3s0RQ== - - esbuild-darwin-64@0.14.21: - version "0.14.21" - resolved "https://registry.yarnpkg.com/esbuild-darwin-64/-/esbuild-darwin-64-0.14.21.tgz#ec7df02ad88ecf7f8fc23a3ed7917e07dea0c9c9" - integrity sha512-j+Eg+e13djzyYINVvAbOo2/zvZ2DivuJJTaBrJnJHSD7kUNuGHRkHoSfFjbI80KHkn091w350wdmXDNSgRjfYQ== - - esbuild-darwin-arm64@0.14.21: - version "0.14.21" - resolved "https://registry.yarnpkg.com/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.21.tgz#0c2a977edec1ef54097ee56a911518c820d4e5e4" - integrity sha512-nDNTKWDPI0RuoPj5BhcSB2z5EmZJJAyRtZLIjyXSqSpAyoB8eyAKXl4lB8U2P78Fnh4Lh1le/fmpewXE04JhBQ== - - esbuild-freebsd-64@0.14.21: - version "0.14.21" - resolved "https://registry.yarnpkg.com/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.21.tgz#f5b5fc1d031286c3a0949d1bda7db774b7d0404e" - integrity sha512-zIurkCHXhxELiDZtLGiexi8t8onQc2LtuE+S7457H/pP0g0MLRKMrsn/IN4LDkNe6lvBjuoZZi2OfelOHn831g== - - esbuild-freebsd-arm64@0.14.21: - version "0.14.21" - resolved "https://registry.yarnpkg.com/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.21.tgz#a05cab908013e4992b31a675850b8c44eb468c0c" - integrity sha512-wdxMmkJfbwcN+q85MpeUEamVZ40FNsBa9mPq8tAszDn8TRT2HoJvVRADPIIBa9SWWwlDChIMjkDKAnS3KS/sPA== - - esbuild-linux-32@0.14.21: - version "0.14.21" - resolved "https://registry.yarnpkg.com/esbuild-linux-32/-/esbuild-linux-32-0.14.21.tgz#638d244cc58b951f447addb4bade628d126ef84b" - integrity sha512-fmxvyzOPPh2xiEHojpCeIQP6pXcoKsWbz3ryDDIKLOsk4xp3GbpHIEAWP0xTeuhEbendmvBDVKbAVv3PnODXLg== - - esbuild-linux-64@0.14.21: - version "0.14.21" - resolved "https://registry.yarnpkg.com/esbuild-linux-64/-/esbuild-linux-64-0.14.21.tgz#8eb634abee928be7e35b985fafbfef2f2e31397f" - integrity sha512-edZyNOv1ql+kpmlzdqzzDjRQYls+tSyi4QFi+PdBhATJFUqHsnNELWA9vMSzAaInPOEaVUTA5Ml28XFChcy4DA== - - esbuild-linux-arm64@0.14.21: - version "0.14.21" - resolved "https://registry.yarnpkg.com/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.21.tgz#e05599ea6253b58394157da162d856f3ead62f9e" - integrity sha512-t5qxRkq4zdQC0zXpzSB2bTtfLgOvR0C6BXYaRE/6/k8/4SrkZcTZBeNu+xGvwCU4b5dU9ST9pwIWkK6T1grS8g== - - esbuild-linux-arm@0.14.21: - version "0.14.21" - resolved "https://registry.yarnpkg.com/esbuild-linux-arm/-/esbuild-linux-arm-0.14.21.tgz#1ae1078231cf689d3ba894a32d3723c0be9b91fd" - integrity sha512-aSU5pUueK6afqmLQsbU+QcFBT62L+4G9hHMJDHWfxgid6hzhSmfRH9U/f+ymvxsSTr/HFRU4y7ox8ZyhlVl98w== - - esbuild-linux-mips64le@0.14.21: - version "0.14.21" - resolved "https://registry.yarnpkg.com/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.21.tgz#f05be62d126764e99b37edcac5bb49b78c7a8890" - integrity sha512-jLZLQGCNlUsmIHtGqNvBs3zN+7a4D9ckf0JZ+jQTwHdZJ1SgV9mAjbB980OFo66LoY+WeM7t3WEnq3FjI1zw4A== - - esbuild-linux-ppc64le@0.14.21: - version "0.14.21" - resolved "https://registry.yarnpkg.com/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.21.tgz#592c98d82dad7982268ef8deed858c4566f07ab1" - integrity sha512-4TWxpK391en2UBUw6GSrukToTDu6lL9vkm3Ll40HrI08WG3qcnJu7bl8e1+GzelDsiw1QmfAY/nNvJ6iaHRpCQ== - - esbuild-linux-riscv64@0.14.21: - version "0.14.21" - resolved "https://registry.yarnpkg.com/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.21.tgz#0db7bd6f10d8f9afea973a7d6bf87b449b864b7b" - integrity sha512-fElngqOaOfTsF+u+oetDLHsPG74vB2ZaGZUqmGefAJn3a5z9Z2pNa4WpVbbKgHpaAAy5tWM1m1sbGohj6Ki6+Q== - - esbuild-linux-s390x@0.14.21: - version "0.14.21" - resolved "https://registry.yarnpkg.com/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.21.tgz#254a9354d34c9d1b41a3e21d2ec9269cbbb2c5df" - integrity sha512-brleZ6R5fYv0qQ7ZBwenQmP6i9TdvJCB092c/3D3pTLQHBGHJb5zWgKxOeS7bdHzmLy6a6W7GbFk6QKpjyD6QA== - - esbuild-netbsd-64@0.14.21: - version "0.14.21" - resolved "https://registry.yarnpkg.com/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.21.tgz#4cb783d060b02bf3b897a9a12cce2b3b547726f8" - integrity sha512-nCEgsLCQ8RoFWVV8pVI+kX66ICwbPP/M9vEa0NJGIEB/Vs5sVGMqkf67oln90XNSkbc0bPBDuo4G6FxlF7PN8g== - - esbuild-openbsd-64@0.14.21: - version "0.14.21" - resolved "https://registry.yarnpkg.com/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.21.tgz#f886b93feefddbe573528fa4b421c9c6e2bc969b" - integrity sha512-h9zLMyVD0T73MDTVYIb/qUTokwI6EJH9O6wESuTNq6+XpMSr6C5aYZ4fvFKdNELW+Xsod+yDS2hV2JTUAbFrLA== - - esbuild-sunos-64@0.14.21: - version "0.14.21" - resolved "https://registry.yarnpkg.com/esbuild-sunos-64/-/esbuild-sunos-64-0.14.21.tgz#3829e4d57d4cb6950837fe90b0b67cdfb37cf13a" - integrity sha512-Kl+7Cot32qd9oqpLdB1tEGXEkjBlijrIxMJ0+vlDFaqsODutif25on0IZlFxEBtL2Gosd4p5WCV1U7UskNQfXA== - - esbuild-windows-32@0.14.21: - version "0.14.21" - resolved "https://registry.yarnpkg.com/esbuild-windows-32/-/esbuild-windows-32-0.14.21.tgz#b858a22d1a82e53cdc59310cd56294133f7a95e7" - integrity sha512-V7vnTq67xPBUCk/9UtlolmQ798Ecjdr1ZoI1vcSgw7M82aSSt0eZdP6bh5KAFZU8pxDcx3qoHyWQfHYr11f22A== - - esbuild-windows-64@0.14.21: - version "0.14.21" - resolved "https://registry.yarnpkg.com/esbuild-windows-64/-/esbuild-windows-64-0.14.21.tgz#7bb5a027d5720cf9caf18a4bedd11327208f1f12" - integrity sha512-kDgHjKOHwjfJDCyRGELzVxiP/RBJBTA+wyspf78MTTJQkyPuxH2vChReNdWc+dU2S4gIZFHMdP1Qrl/k22ZmaA== - - esbuild-windows-arm64@0.14.21: - version "0.14.21" - resolved "https://registry.yarnpkg.com/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.21.tgz#25df54521ad602c826b262ea2e7cc1fe80f5c2f5" - integrity sha512-8Sbo0zpzgwWrwjQYLmHF78f7E2xg5Ve63bjB2ng3V2aManilnnTGaliq2snYg+NOX60+hEvJHRdVnuIAHW0lVw== - - esbuild@^0.14.21: - version "0.14.21" - resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.14.21.tgz#b3e05f900f1c4394f596d60d63d9816468f0f671" - integrity sha512-7WEoNMBJdLN993dr9h0CpFHPRc3yFZD+EAVY9lg6syJJ12gc5fHq8d75QRExuhnMkT2DaRiIKFThRvDWP+fO+A== - optionalDependencies: - esbuild-android-arm64 "0.14.21" - esbuild-darwin-64 "0.14.21" - esbuild-darwin-arm64 "0.14.21" - esbuild-freebsd-64 "0.14.21" - esbuild-freebsd-arm64 "0.14.21" - esbuild-linux-32 "0.14.21" - esbuild-linux-64 "0.14.21" - esbuild-linux-arm "0.14.21" - esbuild-linux-arm64 "0.14.21" - esbuild-linux-mips64le "0.14.21" - esbuild-linux-ppc64le "0.14.21" - esbuild-linux-riscv64 "0.14.21" - esbuild-linux-s390x "0.14.21" - esbuild-netbsd-64 "0.14.21" - esbuild-openbsd-64 "0.14.21" - esbuild-sunos-64 "0.14.21" - esbuild-windows-32 "0.14.21" - esbuild-windows-64 "0.14.21" - esbuild-windows-arm64 "0.14.21" - - fast-deep-equal@^3.1.1: - version "3.1.3" - resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" - integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== - - fast-json-stable-stringify@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" - integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== - - follow-redirects@^1.10.0: - version "1.14.1" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.1.tgz#d9114ded0a1cfdd334e164e6662ad02bfd91ff43" - integrity sha512-HWqDgT7ZEkqRzBvc2s64vSZ/hfOceEol3ac/7tKwzuvEyWx3/4UegXh5oBOIotkGsObyk3xznnSRVADBgWSQVg== - - gettext-parser@1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/gettext-parser/-/gettext-parser-1.1.0.tgz#2c5a6638d893934b9b55037d0ad82cb7004b2679" - integrity sha1-LFpmONiTk0ubVQN9CtgstwBLJnk= - dependencies: - encoding "^0.1.11" - - gettext.js@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/gettext.js/-/gettext.js-1.0.0.tgz#7fefb01512c134759c51166ab4d3db26a585ae1a" - integrity sha512-cpnxNL5C9SlD7ms/NSCuGsQdaVQmwCYn9MILWpYjSPMAkX4aD/5/qC+QgH4GCRY0OMEcSiVBsqgWMEoTcETggQ== - dependencies: - po2json "^0.4.0" - - has-color@~0.1.0: - version "0.1.7" - resolved "https://registry.yarnpkg.com/has-color/-/has-color-0.1.7.tgz#67144a5260c34fc3cca677d041daf52fe7b78b2f" - integrity sha1-ZxRKUmDDT8PMpnfQQdr1L+e3iy8= - - hoist-non-react-statics@^3.3.0, hoist-non-react-statics@^3.3.2: - version "3.3.2" - resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45" - integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw== - dependencies: - react-is "^16.7.0" - - iconv-lite@^0.6.2: - version "0.6.3" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501" - integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== - dependencies: - safer-buffer ">= 2.1.2 < 3.0.0" - - icss-utils@^5.0.0, icss-utils@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-5.1.0.tgz#c6be6858abd013d768e98366ae47e25d5887b1ae" - integrity sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA== - - immutable@^3.8.2: - version "3.8.2" - resolved "https://registry.yarnpkg.com/immutable/-/immutable-3.8.2.tgz#c2439951455bb39913daf281376f1530e104adf3" - integrity sha1-wkOZUUVbs5kT2vKBN28VMOEErfM= - - "js-tokens@^3.0.0 || ^4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" - integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== - - json-schema-traverse@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" - integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== - - json5@^2.1.2: - version "2.2.0" - resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.0.tgz#2dfefe720c6ba525d9ebd909950f0515316c89a3" - integrity sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA== - dependencies: - minimist "^1.2.5" - - loader-utils@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.0.tgz#e4cace5b816d425a166b5f097e10cd12b36064b0" - integrity sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ== - dependencies: - big.js "^5.2.2" - emojis-list "^3.0.0" - json5 "^2.1.2" - - lodash@^4.17.21: - version "4.17.21" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" - integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== - - loose-envify@^1.1.0, loose-envify@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" - integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== - dependencies: - js-tokens "^3.0.0 || ^4.0.0" - - lru-cache@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" - integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== - dependencies: - yallist "^4.0.0" - - mime-db@1.48.0: - version "1.48.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.48.0.tgz#e35b31045dd7eada3aaad537ed88a33afbef2d1d" - integrity sha512-FM3QwxV+TnZYQ2aRqhlKBMHxk10lTbMt3bBkMAp54ddrNeVSfcQYOOKuGuy3Ddrm38I04If834fOUSq1yzslJQ== - - mime-types@^2.1.27: - version "2.1.31" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.31.tgz#a00d76b74317c61f9c2db2218b8e9f8e9c5c9e6b" - integrity sha512-XGZnNzm3QvgKxa8dpzyhFTHmpP3l5YNusmne07VUOXxou9CqUqYa/HBy124RqtVh/O2pECas/MOcsDgpilPOPg== - dependencies: - mime-db "1.48.0" - - mini-css-extract-plugin@^1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-1.6.0.tgz#b4db2525af2624899ed64a23b0016e0036411893" - integrity sha512-nPFKI7NSy6uONUo9yn2hIfb9vyYvkFu95qki0e21DQ9uaqNKDP15DGpK0KnV6wDroWxPHtExrdEwx/yDQ8nVRw== - dependencies: - loader-utils "^2.0.0" - schema-utils "^3.0.0" - webpack-sources "^1.1.0" - - minimist@^1.2.5: - version "1.2.5" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" - integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== - - nanoid@^3.1.23: - version "3.1.23" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.23.tgz#f744086ce7c2bc47ee0a8472574d5c78e4183a81" - integrity sha512-FiB0kzdP0FFVGDKlRLEQ1BgDzU87dy5NnzjeW9YZNt+/c3+q82EQDUwniSAUxp/F0gFNI1ZhKU1FqYsMuqZVnw== - - nomnom@1.8.1: - version "1.8.1" - resolved "https://registry.yarnpkg.com/nomnom/-/nomnom-1.8.1.tgz#2151f722472ba79e50a76fc125bb8c8f2e4dc2a7" - integrity sha1-IVH3Ikcrp55Qp2/BJbuMjy5Nwqc= - dependencies: - chalk "~0.4.0" - underscore "~1.6.0" - - object-assign@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" - integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= - - object-path@^0.11.5: - version "0.11.5" - resolved "https://registry.yarnpkg.com/object-path/-/object-path-0.11.5.tgz#d4e3cf19601a5140a55a16ad712019a9c50b577a" - integrity sha512-jgSbThcoR/s+XumvGMTMf81QVBmah+/Q7K7YduKeKVWL7N111unR2d6pZZarSk6kY/caeNxUDyxOvMWyzoU2eg== - - "phoenix@file:../deps/phoenix": - version "1.6.6" - - "phoenix_html@file:../deps/phoenix_html": - <<<<<<< HEAD - version "3.2.0" - ======= - version "2.14.3" - - "phoenix_live_view@file:../deps/phoenix_live_view": - version "0.15.3" - - picomatch@^2.2.1, picomatch@^2.2.3: - version "2.3.0" - resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.0.tgz#f1f061de8f6a4bf022892e2d128234fb98302972" - integrity sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw== - "phoenix_live_view@file:../deps/phoenix_live_view": - version "0.15.3" - - pify@^2.0.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" - integrity sha1-7RQaasBDqEnqWISY59yosVMw6Qw= - - pinkie-promise@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" - integrity sha1-ITXW36ejWMBprJsXh3YogihFD/o= - dependencies: - pinkie "^2.0.0" - - pinkie@^2.0.0: - version "2.0.4" - resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" - integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA= - - pkg-dir@^4.1.0, pkg-dir@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" - integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== - dependencies: - find-up "^4.0.0" - >>>>>>> 7af5f8c (Install LiveView) - - po2json@^0.4.0: - version "0.4.5" - resolved "https://registry.yarnpkg.com/po2json/-/po2json-0.4.5.tgz#47bb2952da32d58a1be2f256a598eebc0b745118" - integrity sha1-R7spUtoy1Yob4vJWpZjuvAt0URg= - dependencies: - gettext-parser "1.1.0" - nomnom "1.8.1" - - postcss-modules-extract-imports@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz#cda1f047c0ae80c97dbe28c3e76a43b88025741d" - integrity sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw== - - postcss-modules-local-by-default@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.0.tgz#ebbb54fae1598eecfdf691a02b3ff3b390a5a51c" - integrity sha512-sT7ihtmGSF9yhm6ggikHdV0hlziDTX7oFoXtuVWeDd3hHObNkcHRo9V3yg7vCAY7cONyxJC/XXCmmiHHcvX7bQ== - dependencies: - icss-utils "^5.0.0" - postcss-selector-parser "^6.0.2" - postcss-value-parser "^4.1.0" - - postcss-modules-scope@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz#9ef3151456d3bbfa120ca44898dfca6f2fa01f06" - integrity sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg== - dependencies: - postcss-selector-parser "^6.0.4" - - postcss-modules-values@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz#d7c5e7e68c3bb3c9b27cbf48ca0bb3ffb4602c9c" - integrity sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ== - dependencies: - icss-utils "^5.0.0" - - postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4: - version "6.0.6" - resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.6.tgz#2c5bba8174ac2f6981ab631a42ab0ee54af332ea" - integrity sha512-9LXrvaaX3+mcv5xkg5kFwqSzSH1JIObIx51PrndZwlmznwXRfxMddDvo9gve3gVR8ZTKgoFDdWkbRFmEhT4PMg== - dependencies: - cssesc "^3.0.0" - util-deprecate "^1.0.2" - - postcss-value-parser@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz#443f6a20ced6481a2bda4fa8532a6e55d789a2cb" - integrity sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ== - - postcss@^8.2.15: - version "8.3.5" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.3.5.tgz#982216b113412bc20a86289e91eb994952a5b709" - integrity sha512-NxTuJocUhYGsMiMFHDUkmjSKT3EdH4/WbGF6GCi1NDGk+vbcUTun4fpbOqaPtD8IIsztA2ilZm2DhYCuyN58gA== - dependencies: - colorette "^1.2.2" - nanoid "^3.1.23" - source-map-js "^0.6.2" - - prop-types@^15.7.2: - version "15.7.2" - resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5" - integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ== - dependencies: - loose-envify "^1.4.0" - object-assign "^4.1.1" - react-is "^16.8.1" - - punycode@^2.1.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" - integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== - - react-dom@^17.0.2: - version "17.0.2" - resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-17.0.2.tgz#ecffb6845e3ad8dbfcdc498f0d0a939736502c23" - integrity sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA== - dependencies: - loose-envify "^1.1.0" - object-assign "^4.1.1" - scheduler "^0.20.2" - - react-is@^16.13.1, react-is@^16.7.0, react-is@^16.8.1: - version "16.13.1" - resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" - integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== - - react-redux@^7.2.4: - version "7.2.4" - resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-7.2.4.tgz#1ebb474032b72d806de2e0519cd07761e222e225" - integrity sha512-hOQ5eOSkEJEXdpIKbnRyl04LhaWabkDPV+Ix97wqQX3T3d2NQ8DUblNXXtNMavc7DpswyQM6xfaN4HQDKNY2JA== - dependencies: - "@babel/runtime" "^7.12.1" - "@types/react-redux" "^7.1.16" - hoist-non-react-statics "^3.3.2" - loose-envify "^1.4.0" - prop-types "^15.7.2" - react-is "^16.13.1" - - react@^17.0.2: - version "17.0.2" - resolved "https://registry.yarnpkg.com/react/-/react-17.0.2.tgz#d0b5cc516d29eb3eee383f75b62864cfb6800037" - integrity sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA== - dependencies: - loose-envify "^1.1.0" - object-assign "^4.1.1" - - redux-watch@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/redux-watch/-/redux-watch-1.2.0.tgz#b3a745e15855ef72db0e06a60a4b2fe3676d79a7" - integrity sha512-Ws4Q+e5zFGMyy1H709c1Ws8apSd6MqoJRIzBDHbI4nikome/IZWVTYXdQNz+VJxPjyX/h2E+lYEo41fXgjCF8g== - dependencies: - object-path "^0.11.5" - - redux@^4.0.0, redux@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/redux/-/redux-4.1.0.tgz#eb049679f2f523c379f1aff345c8612f294c88d4" - integrity sha512-uI2dQN43zqLWCt6B/BMGRMY6db7TTY4qeHHfGeKb3EOhmOKjU3KdWvNLJyqaHRksv/ErdNH7cFZWg9jXtewy4g== - dependencies: - "@babel/runtime" "^7.9.2" - - regenerator-runtime@^0.13.4: - version "0.13.7" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz#cac2dacc8a1ea675feaabaeb8ae833898ae46f55" - integrity sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew== - - "safer-buffer@>= 2.1.2 < 3.0.0": - version "2.1.2" - resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" - integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== - - scheduler@^0.20.2: - version "0.20.2" - resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.20.2.tgz#4baee39436e34aa93b4874bddcbf0fe8b8b50e91" - integrity sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ== - dependencies: - loose-envify "^1.1.0" - object-assign "^4.1.1" - - schema-utils@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.0.0.tgz#67502f6aa2b66a2d4032b4279a2944978a0913ef" - integrity sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA== - dependencies: - "@types/json-schema" "^7.0.6" - ajv "^6.12.5" - ajv-keywords "^3.5.2" - - semver@^7.3.5: - version "7.3.5" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" - integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ== - dependencies: - lru-cache "^6.0.0" - - source-list-map@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34" - integrity sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw== - - source-map-js@^0.6.2: - version "0.6.2" - resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-0.6.2.tgz#0bb5de631b41cfbda6cfba8bd05a80efdfd2385e" - integrity sha512-/3GptzWzu0+0MBQFrDKzw/DvvMTUORvgY6k6jd/VS6iCR4RDTKWH6v6WPwQoUO8667uQEf9Oe38DxAYWY5F/Ug== - - source-map@~0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" - integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== - - strip-ansi@~0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-0.1.1.tgz#39e8a98d044d150660abe4a6808acf70bb7bc991" - integrity sha1-OeipjQRNFQZgq+SmgIrPcLt7yZE= - - underscore@~1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.6.0.tgz#8b38b10cacdef63337b8b24e4ff86d45aea529a8" - integrity sha1-izixDKze9jM3uLJOT/htRa6lKag= - - uri-js@^4.2.2: - version "4.4.1" - resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" - integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== - dependencies: - punycode "^2.1.0" - - url-loader@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/url-loader/-/url-loader-4.1.1.tgz#28505e905cae158cf07c92ca622d7f237e70a4e2" - integrity sha512-3BTV812+AVHHOJQO8O5MkWgZ5aosP7GnROJwvzLS9hWDj00lZ6Z0wNak423Lp9PBZN05N+Jk/N5Si8jRAlGyWA== - dependencies: - loader-utils "^2.0.0" - mime-types "^2.1.27" - schema-utils "^3.0.0" - - util-deprecate@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" - integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= - - webpack-sources@^1.1.0: - version "1.4.3" - resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.4.3.tgz#eedd8ec0b928fbf1cbfe994e22d2d890f330a933" - integrity sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ== - dependencies: - source-list-map "^2.0.0" - source-map "~0.6.1" - - yallist@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" - integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== diff --git a/assets/yarn.lock b/assets/yarn.lock deleted file mode 100644 index 0383dc6..0000000 --- a/assets/yarn.lock +++ /dev/null @@ -1,654 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -"@babel/polyfill@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/polyfill/-/polyfill-7.12.1.tgz#1f2d6371d1261bbd961f3c5d5909150e12d0bd96" - integrity sha512-X0pi0V6gxLi6lFZpGmeNa4zxtwEmCs42isWLNjZZDE0Y8yVfgu0T2OAHlzBbdYlqbW/YXVvoBHpATEM+goCj8g== - dependencies: - core-js "^2.6.5" - regenerator-runtime "^0.13.4" - -"@babel/runtime@^7.12.1", "@babel/runtime@^7.9.2": - version "7.14.6" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.14.6.tgz#535203bc0892efc7dec60bdc27b2ecf6e409062d" - integrity sha512-/PCB2uJ7oM44tz8YhC4Z/6PeOKXp4K588f+5M3clr1M4zbqztlo0XEfJ2LEzj/FgwfgGcIdl8n7YYjTCI0BYwg== - dependencies: - regenerator-runtime "^0.13.4" - -"@types/hoist-non-react-statics@^3.3.0": - version "3.3.1" - resolved "https://registry.yarnpkg.com/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz#1124aafe5118cb591977aeb1ceaaed1070eb039f" - integrity sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA== - dependencies: - "@types/react" "*" - hoist-non-react-statics "^3.3.0" - -"@types/json-schema@^7.0.6": - version "7.0.7" - resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.7.tgz#98a993516c859eb0d5c4c8f098317a9ea68db9ad" - integrity sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA== - -"@types/prop-types@*": - version "15.7.3" - resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.3.tgz#2ab0d5da2e5815f94b0b9d4b95d1e5f243ab2ca7" - integrity sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw== - -"@types/react-redux@^7.1.16": - version "7.1.16" - resolved "https://registry.yarnpkg.com/@types/react-redux/-/react-redux-7.1.16.tgz#0fbd04c2500c12105494c83d4a3e45c084e3cb21" - integrity sha512-f/FKzIrZwZk7YEO9E1yoxIuDNRiDducxkFlkw/GNMGEnK9n4K8wJzlJBghpSuOVDgEUHoDkDF7Gi9lHNQR4siw== - dependencies: - "@types/hoist-non-react-statics" "^3.3.0" - "@types/react" "*" - hoist-non-react-statics "^3.3.0" - redux "^4.0.0" - -"@types/react@*": - version "17.0.11" - resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.11.tgz#67fcd0ddbf5a0b083a0f94e926c7d63f3b836451" - integrity sha512-yFRQbD+whVonItSk7ZzP/L+gPTJVBkL/7shLEF+i9GC/1cV3JmUxEQz6+9ylhUpWSDuqo1N9qEvqS6vTj4USUA== - dependencies: - "@types/prop-types" "*" - "@types/scheduler" "*" - csstype "^3.0.2" - -"@types/scheduler@*": - version "0.16.1" - resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.1.tgz#18845205e86ff0038517aab7a18a62a6b9f71275" - integrity sha512-EaCxbanVeyxDRTQBkdLb3Bvl/HK7PBK6UJjsSixB0iHKoWxE5uu2Q/DgtpOhPIojN0Zl1whvOd7PoHs2P0s5eA== - -ajv-keywords@^3.5.2: - version "3.5.2" - resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" - integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== - -ajv@^6.12.5: - version "6.12.6" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" - integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== - 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" - -ansi-styles@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-1.0.0.tgz#cb102df1c56f5123eab8b67cd7b98027a0279178" - integrity sha1-yxAt8cVvUSPquLZ817mAJ6AnkXg= - -axios@^0.21.0: - version "0.21.1" - resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.1.tgz#22563481962f4d6bde9a76d516ef0e5d3c09b2b8" - integrity sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA== - dependencies: - follow-redirects "^1.10.0" - -big.js@^5.2.2: - version "5.2.2" - resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" - integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ== - -chalk@~0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-0.4.0.tgz#5199a3ddcd0c1efe23bc08c1b027b06176e0c64f" - integrity sha1-UZmj3c0MHv4jvAjBsCewYXbgxk8= - dependencies: - ansi-styles "~1.0.0" - has-color "~0.1.0" - strip-ansi "~0.1.0" - -classnames@^2.3.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.3.1.tgz#dfcfa3891e306ec1dad105d0e88f4417b8535e8e" - integrity sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA== - -colorette@^1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.2.2.tgz#cbcc79d5e99caea2dbf10eb3a26fd8b3e6acfa94" - integrity sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w== - -core-js@^2.6.5: - version "2.6.12" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.12.tgz#d9333dfa7b065e347cc5682219d6f690859cc2ec" - integrity sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ== - -css-loader@^5.2.6: - version "5.2.6" - resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-5.2.6.tgz#c3c82ab77fea1f360e587d871a6811f4450cc8d1" - integrity sha512-0wyN5vXMQZu6BvjbrPdUJvkCzGEO24HC7IS7nW4llc6BBFC+zwR9CKtYGv63Puzsg10L/o12inMY5/2ByzfD6w== - dependencies: - icss-utils "^5.1.0" - loader-utils "^2.0.0" - postcss "^8.2.15" - postcss-modules-extract-imports "^3.0.0" - postcss-modules-local-by-default "^4.0.0" - postcss-modules-scope "^3.0.0" - postcss-modules-values "^4.0.0" - postcss-value-parser "^4.1.0" - schema-utils "^3.0.0" - semver "^7.3.5" - -cssesc@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" - integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== - -csstype@^3.0.2: - version "3.0.8" - resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.0.8.tgz#d2266a792729fb227cd216fb572f43728e1ad340" - integrity sha512-jXKhWqXPmlUeoQnF/EhTtTl4C9SnrxSH/jZUih3jmO6lBKr99rP3/+FmrMj4EFpOXzMtXHAZkd3x0E6h6Fgflw== - -emojis-list@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78" - integrity sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q== - -encoding@^0.1.11: - version "0.1.13" - resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.13.tgz#56574afdd791f54a8e9b2785c0582a2d26210fa9" - integrity sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A== - dependencies: - iconv-lite "^0.6.2" - -esbuild-android-arm64@0.14.21: - version "0.14.21" - resolved "https://registry.yarnpkg.com/esbuild-android-arm64/-/esbuild-android-arm64-0.14.21.tgz#8842d0c3b7c81fbe2dc46ddb416ffd6eb822184b" - integrity sha512-Bqgld1TY0wZv8TqiQmVxQFgYzz8ZmyzT7clXBDZFkOOdRybzsnj8AZuK1pwcLVA7Ya6XncHgJqIao7NFd3s0RQ== - -esbuild-darwin-64@0.14.21: - version "0.14.21" - resolved "https://registry.yarnpkg.com/esbuild-darwin-64/-/esbuild-darwin-64-0.14.21.tgz#ec7df02ad88ecf7f8fc23a3ed7917e07dea0c9c9" - integrity sha512-j+Eg+e13djzyYINVvAbOo2/zvZ2DivuJJTaBrJnJHSD7kUNuGHRkHoSfFjbI80KHkn091w350wdmXDNSgRjfYQ== - -esbuild-darwin-arm64@0.14.21: - version "0.14.21" - resolved "https://registry.yarnpkg.com/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.21.tgz#0c2a977edec1ef54097ee56a911518c820d4e5e4" - integrity sha512-nDNTKWDPI0RuoPj5BhcSB2z5EmZJJAyRtZLIjyXSqSpAyoB8eyAKXl4lB8U2P78Fnh4Lh1le/fmpewXE04JhBQ== - -esbuild-freebsd-64@0.14.21: - version "0.14.21" - resolved "https://registry.yarnpkg.com/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.21.tgz#f5b5fc1d031286c3a0949d1bda7db774b7d0404e" - integrity sha512-zIurkCHXhxELiDZtLGiexi8t8onQc2LtuE+S7457H/pP0g0MLRKMrsn/IN4LDkNe6lvBjuoZZi2OfelOHn831g== - -esbuild-freebsd-arm64@0.14.21: - version "0.14.21" - resolved "https://registry.yarnpkg.com/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.21.tgz#a05cab908013e4992b31a675850b8c44eb468c0c" - integrity sha512-wdxMmkJfbwcN+q85MpeUEamVZ40FNsBa9mPq8tAszDn8TRT2HoJvVRADPIIBa9SWWwlDChIMjkDKAnS3KS/sPA== - -esbuild-linux-32@0.14.21: - version "0.14.21" - resolved "https://registry.yarnpkg.com/esbuild-linux-32/-/esbuild-linux-32-0.14.21.tgz#638d244cc58b951f447addb4bade628d126ef84b" - integrity sha512-fmxvyzOPPh2xiEHojpCeIQP6pXcoKsWbz3ryDDIKLOsk4xp3GbpHIEAWP0xTeuhEbendmvBDVKbAVv3PnODXLg== - -esbuild-linux-64@0.14.21: - version "0.14.21" - resolved "https://registry.yarnpkg.com/esbuild-linux-64/-/esbuild-linux-64-0.14.21.tgz#8eb634abee928be7e35b985fafbfef2f2e31397f" - integrity sha512-edZyNOv1ql+kpmlzdqzzDjRQYls+tSyi4QFi+PdBhATJFUqHsnNELWA9vMSzAaInPOEaVUTA5Ml28XFChcy4DA== - -esbuild-linux-arm64@0.14.21: - version "0.14.21" - resolved "https://registry.yarnpkg.com/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.21.tgz#e05599ea6253b58394157da162d856f3ead62f9e" - integrity sha512-t5qxRkq4zdQC0zXpzSB2bTtfLgOvR0C6BXYaRE/6/k8/4SrkZcTZBeNu+xGvwCU4b5dU9ST9pwIWkK6T1grS8g== - -esbuild-linux-arm@0.14.21: - version "0.14.21" - resolved "https://registry.yarnpkg.com/esbuild-linux-arm/-/esbuild-linux-arm-0.14.21.tgz#1ae1078231cf689d3ba894a32d3723c0be9b91fd" - integrity sha512-aSU5pUueK6afqmLQsbU+QcFBT62L+4G9hHMJDHWfxgid6hzhSmfRH9U/f+ymvxsSTr/HFRU4y7ox8ZyhlVl98w== - -esbuild-linux-mips64le@0.14.21: - version "0.14.21" - resolved "https://registry.yarnpkg.com/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.21.tgz#f05be62d126764e99b37edcac5bb49b78c7a8890" - integrity sha512-jLZLQGCNlUsmIHtGqNvBs3zN+7a4D9ckf0JZ+jQTwHdZJ1SgV9mAjbB980OFo66LoY+WeM7t3WEnq3FjI1zw4A== - -esbuild-linux-ppc64le@0.14.21: - version "0.14.21" - resolved "https://registry.yarnpkg.com/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.21.tgz#592c98d82dad7982268ef8deed858c4566f07ab1" - integrity sha512-4TWxpK391en2UBUw6GSrukToTDu6lL9vkm3Ll40HrI08WG3qcnJu7bl8e1+GzelDsiw1QmfAY/nNvJ6iaHRpCQ== - -esbuild-linux-riscv64@0.14.21: - version "0.14.21" - resolved "https://registry.yarnpkg.com/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.21.tgz#0db7bd6f10d8f9afea973a7d6bf87b449b864b7b" - integrity sha512-fElngqOaOfTsF+u+oetDLHsPG74vB2ZaGZUqmGefAJn3a5z9Z2pNa4WpVbbKgHpaAAy5tWM1m1sbGohj6Ki6+Q== - -esbuild-linux-s390x@0.14.21: - version "0.14.21" - resolved "https://registry.yarnpkg.com/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.21.tgz#254a9354d34c9d1b41a3e21d2ec9269cbbb2c5df" - integrity sha512-brleZ6R5fYv0qQ7ZBwenQmP6i9TdvJCB092c/3D3pTLQHBGHJb5zWgKxOeS7bdHzmLy6a6W7GbFk6QKpjyD6QA== - -esbuild-netbsd-64@0.14.21: - version "0.14.21" - resolved "https://registry.yarnpkg.com/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.21.tgz#4cb783d060b02bf3b897a9a12cce2b3b547726f8" - integrity sha512-nCEgsLCQ8RoFWVV8pVI+kX66ICwbPP/M9vEa0NJGIEB/Vs5sVGMqkf67oln90XNSkbc0bPBDuo4G6FxlF7PN8g== - -esbuild-openbsd-64@0.14.21: - version "0.14.21" - resolved "https://registry.yarnpkg.com/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.21.tgz#f886b93feefddbe573528fa4b421c9c6e2bc969b" - integrity sha512-h9zLMyVD0T73MDTVYIb/qUTokwI6EJH9O6wESuTNq6+XpMSr6C5aYZ4fvFKdNELW+Xsod+yDS2hV2JTUAbFrLA== - -esbuild-sunos-64@0.14.21: - version "0.14.21" - resolved "https://registry.yarnpkg.com/esbuild-sunos-64/-/esbuild-sunos-64-0.14.21.tgz#3829e4d57d4cb6950837fe90b0b67cdfb37cf13a" - integrity sha512-Kl+7Cot32qd9oqpLdB1tEGXEkjBlijrIxMJ0+vlDFaqsODutif25on0IZlFxEBtL2Gosd4p5WCV1U7UskNQfXA== - -esbuild-windows-32@0.14.21: - version "0.14.21" - resolved "https://registry.yarnpkg.com/esbuild-windows-32/-/esbuild-windows-32-0.14.21.tgz#b858a22d1a82e53cdc59310cd56294133f7a95e7" - integrity sha512-V7vnTq67xPBUCk/9UtlolmQ798Ecjdr1ZoI1vcSgw7M82aSSt0eZdP6bh5KAFZU8pxDcx3qoHyWQfHYr11f22A== - -esbuild-windows-64@0.14.21: - version "0.14.21" - resolved "https://registry.yarnpkg.com/esbuild-windows-64/-/esbuild-windows-64-0.14.21.tgz#7bb5a027d5720cf9caf18a4bedd11327208f1f12" - integrity sha512-kDgHjKOHwjfJDCyRGELzVxiP/RBJBTA+wyspf78MTTJQkyPuxH2vChReNdWc+dU2S4gIZFHMdP1Qrl/k22ZmaA== - -esbuild-windows-arm64@0.14.21: - version "0.14.21" - resolved "https://registry.yarnpkg.com/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.21.tgz#25df54521ad602c826b262ea2e7cc1fe80f5c2f5" - integrity sha512-8Sbo0zpzgwWrwjQYLmHF78f7E2xg5Ve63bjB2ng3V2aManilnnTGaliq2snYg+NOX60+hEvJHRdVnuIAHW0lVw== - -esbuild@^0.14.21: - version "0.14.21" - resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.14.21.tgz#b3e05f900f1c4394f596d60d63d9816468f0f671" - integrity sha512-7WEoNMBJdLN993dr9h0CpFHPRc3yFZD+EAVY9lg6syJJ12gc5fHq8d75QRExuhnMkT2DaRiIKFThRvDWP+fO+A== - optionalDependencies: - esbuild-android-arm64 "0.14.21" - esbuild-darwin-64 "0.14.21" - esbuild-darwin-arm64 "0.14.21" - esbuild-freebsd-64 "0.14.21" - esbuild-freebsd-arm64 "0.14.21" - esbuild-linux-32 "0.14.21" - esbuild-linux-64 "0.14.21" - esbuild-linux-arm "0.14.21" - esbuild-linux-arm64 "0.14.21" - esbuild-linux-mips64le "0.14.21" - esbuild-linux-ppc64le "0.14.21" - esbuild-linux-riscv64 "0.14.21" - esbuild-linux-s390x "0.14.21" - esbuild-netbsd-64 "0.14.21" - esbuild-openbsd-64 "0.14.21" - esbuild-sunos-64 "0.14.21" - esbuild-windows-32 "0.14.21" - esbuild-windows-64 "0.14.21" - esbuild-windows-arm64 "0.14.21" - -fast-deep-equal@^3.1.1: - version "3.1.3" - resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" - integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== - -fast-json-stable-stringify@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" - integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== - -follow-redirects@^1.10.0: - version "1.14.1" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.1.tgz#d9114ded0a1cfdd334e164e6662ad02bfd91ff43" - integrity sha512-HWqDgT7ZEkqRzBvc2s64vSZ/hfOceEol3ac/7tKwzuvEyWx3/4UegXh5oBOIotkGsObyk3xznnSRVADBgWSQVg== - -gettext-parser@1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/gettext-parser/-/gettext-parser-1.1.0.tgz#2c5a6638d893934b9b55037d0ad82cb7004b2679" - integrity sha1-LFpmONiTk0ubVQN9CtgstwBLJnk= - dependencies: - encoding "^0.1.11" - -gettext.js@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/gettext.js/-/gettext.js-1.0.0.tgz#7fefb01512c134759c51166ab4d3db26a585ae1a" - integrity sha512-cpnxNL5C9SlD7ms/NSCuGsQdaVQmwCYn9MILWpYjSPMAkX4aD/5/qC+QgH4GCRY0OMEcSiVBsqgWMEoTcETggQ== - dependencies: - po2json "^0.4.0" - -has-color@~0.1.0: - version "0.1.7" - resolved "https://registry.yarnpkg.com/has-color/-/has-color-0.1.7.tgz#67144a5260c34fc3cca677d041daf52fe7b78b2f" - integrity sha1-ZxRKUmDDT8PMpnfQQdr1L+e3iy8= - -hoist-non-react-statics@^3.3.0, hoist-non-react-statics@^3.3.2: - version "3.3.2" - resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45" - integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw== - dependencies: - react-is "^16.7.0" - -iconv-lite@^0.6.2: - version "0.6.3" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501" - integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== - dependencies: - safer-buffer ">= 2.1.2 < 3.0.0" - -icss-utils@^5.0.0, icss-utils@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-5.1.0.tgz#c6be6858abd013d768e98366ae47e25d5887b1ae" - integrity sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA== - -immutable@^3.8.2: - version "3.8.2" - resolved "https://registry.yarnpkg.com/immutable/-/immutable-3.8.2.tgz#c2439951455bb39913daf281376f1530e104adf3" - integrity sha1-wkOZUUVbs5kT2vKBN28VMOEErfM= - -"js-tokens@^3.0.0 || ^4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" - integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== - -json-schema-traverse@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" - integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== - -json5@^2.1.2: - version "2.2.0" - resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.0.tgz#2dfefe720c6ba525d9ebd909950f0515316c89a3" - integrity sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA== - dependencies: - minimist "^1.2.5" - -loader-utils@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.0.tgz#e4cace5b816d425a166b5f097e10cd12b36064b0" - integrity sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ== - dependencies: - big.js "^5.2.2" - emojis-list "^3.0.0" - json5 "^2.1.2" - -lodash@^4.17.21: - version "4.17.21" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" - integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== - -loose-envify@^1.1.0, loose-envify@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" - integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== - dependencies: - js-tokens "^3.0.0 || ^4.0.0" - -lru-cache@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" - integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== - dependencies: - yallist "^4.0.0" - -mime-db@1.48.0: - version "1.48.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.48.0.tgz#e35b31045dd7eada3aaad537ed88a33afbef2d1d" - integrity sha512-FM3QwxV+TnZYQ2aRqhlKBMHxk10lTbMt3bBkMAp54ddrNeVSfcQYOOKuGuy3Ddrm38I04If834fOUSq1yzslJQ== - -mime-types@^2.1.27: - version "2.1.31" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.31.tgz#a00d76b74317c61f9c2db2218b8e9f8e9c5c9e6b" - integrity sha512-XGZnNzm3QvgKxa8dpzyhFTHmpP3l5YNusmne07VUOXxou9CqUqYa/HBy124RqtVh/O2pECas/MOcsDgpilPOPg== - dependencies: - mime-db "1.48.0" - -mini-css-extract-plugin@^1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-1.6.0.tgz#b4db2525af2624899ed64a23b0016e0036411893" - integrity sha512-nPFKI7NSy6uONUo9yn2hIfb9vyYvkFu95qki0e21DQ9uaqNKDP15DGpK0KnV6wDroWxPHtExrdEwx/yDQ8nVRw== - dependencies: - loader-utils "^2.0.0" - schema-utils "^3.0.0" - webpack-sources "^1.1.0" - -minimist@^1.2.5: - version "1.2.5" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" - integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== - -nanoid@^3.1.23: - version "3.1.23" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.23.tgz#f744086ce7c2bc47ee0a8472574d5c78e4183a81" - integrity sha512-FiB0kzdP0FFVGDKlRLEQ1BgDzU87dy5NnzjeW9YZNt+/c3+q82EQDUwniSAUxp/F0gFNI1ZhKU1FqYsMuqZVnw== - -nomnom@1.8.1: - version "1.8.1" - resolved "https://registry.yarnpkg.com/nomnom/-/nomnom-1.8.1.tgz#2151f722472ba79e50a76fc125bb8c8f2e4dc2a7" - integrity sha1-IVH3Ikcrp55Qp2/BJbuMjy5Nwqc= - dependencies: - chalk "~0.4.0" - underscore "~1.6.0" - -object-assign@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" - integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= - -object-path@^0.11.5: - version "0.11.5" - resolved "https://registry.yarnpkg.com/object-path/-/object-path-0.11.5.tgz#d4e3cf19601a5140a55a16ad712019a9c50b577a" - integrity sha512-jgSbThcoR/s+XumvGMTMf81QVBmah+/Q7K7YduKeKVWL7N111unR2d6pZZarSk6kY/caeNxUDyxOvMWyzoU2eg== - -phoenix@^1.7.0-rc.2: - version "1.7.0-rc.2" - resolved "https://registry.yarnpkg.com/phoenix/-/phoenix-1.7.0-rc.2.tgz#aca2e5af35c94922fdfe6bb11e860937088af937" - integrity sha512-05DaSo/ws2VtieY3Z6CJVx36DyhTil6/KesK1a4JlQPxYgNHZn7swv7R/R7etoN8SGtEjMV/a9HBkPS5wF/Xdg== - -phoenix_html@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/phoenix_html/-/phoenix_html-3.2.0.tgz#4a30e5c331a72abababa1f3b81a9fe2c0e5a43d7" - integrity sha512-zv7PIZk0MPkF0ax8n465Q6w86+sGAy5cTem6KcbkUbdgxGc0y3WZmzkM2bSlYdSGbLEZfjXxos1G72xXsha6xA== - -phoenix_live_view@^0.18.11: - version "0.18.11" - resolved "https://registry.yarnpkg.com/phoenix_live_view/-/phoenix_live_view-0.18.11.tgz#5cc302df19372f516d7b90b939b85198649b55ef" - integrity sha512-p/mBu/O3iVLvAreUoDeSZ4/myQJJeR8BH7Yu9LVCMI2xe2IZ2mffxtDGJb0mxnJrUQa7p03HHNlKGXj7LSJDdg== - -po2json@^0.4.0: - version "0.4.5" - resolved "https://registry.yarnpkg.com/po2json/-/po2json-0.4.5.tgz#47bb2952da32d58a1be2f256a598eebc0b745118" - integrity sha1-R7spUtoy1Yob4vJWpZjuvAt0URg= - dependencies: - gettext-parser "1.1.0" - nomnom "1.8.1" - -postcss-modules-extract-imports@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz#cda1f047c0ae80c97dbe28c3e76a43b88025741d" - integrity sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw== - -postcss-modules-local-by-default@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.0.tgz#ebbb54fae1598eecfdf691a02b3ff3b390a5a51c" - integrity sha512-sT7ihtmGSF9yhm6ggikHdV0hlziDTX7oFoXtuVWeDd3hHObNkcHRo9V3yg7vCAY7cONyxJC/XXCmmiHHcvX7bQ== - dependencies: - icss-utils "^5.0.0" - postcss-selector-parser "^6.0.2" - postcss-value-parser "^4.1.0" - -postcss-modules-scope@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz#9ef3151456d3bbfa120ca44898dfca6f2fa01f06" - integrity sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg== - dependencies: - postcss-selector-parser "^6.0.4" - -postcss-modules-values@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz#d7c5e7e68c3bb3c9b27cbf48ca0bb3ffb4602c9c" - integrity sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ== - dependencies: - icss-utils "^5.0.0" - -postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4: - version "6.0.6" - resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.6.tgz#2c5bba8174ac2f6981ab631a42ab0ee54af332ea" - integrity sha512-9LXrvaaX3+mcv5xkg5kFwqSzSH1JIObIx51PrndZwlmznwXRfxMddDvo9gve3gVR8ZTKgoFDdWkbRFmEhT4PMg== - dependencies: - cssesc "^3.0.0" - util-deprecate "^1.0.2" - -postcss-value-parser@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz#443f6a20ced6481a2bda4fa8532a6e55d789a2cb" - integrity sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ== - -postcss@^8.2.15: - version "8.3.5" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.3.5.tgz#982216b113412bc20a86289e91eb994952a5b709" - integrity sha512-NxTuJocUhYGsMiMFHDUkmjSKT3EdH4/WbGF6GCi1NDGk+vbcUTun4fpbOqaPtD8IIsztA2ilZm2DhYCuyN58gA== - dependencies: - colorette "^1.2.2" - nanoid "^3.1.23" - source-map-js "^0.6.2" - -prop-types@^15.7.2: - version "15.7.2" - resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5" - integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ== - dependencies: - loose-envify "^1.4.0" - object-assign "^4.1.1" - react-is "^16.8.1" - -punycode@^2.1.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" - integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== - -react-dom@^17.0.2: - version "17.0.2" - resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-17.0.2.tgz#ecffb6845e3ad8dbfcdc498f0d0a939736502c23" - integrity sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA== - dependencies: - loose-envify "^1.1.0" - object-assign "^4.1.1" - scheduler "^0.20.2" - -react-is@^16.13.1, react-is@^16.7.0, react-is@^16.8.1: - version "16.13.1" - resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" - integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== - -react-redux@^7.2.4: - version "7.2.4" - resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-7.2.4.tgz#1ebb474032b72d806de2e0519cd07761e222e225" - integrity sha512-hOQ5eOSkEJEXdpIKbnRyl04LhaWabkDPV+Ix97wqQX3T3d2NQ8DUblNXXtNMavc7DpswyQM6xfaN4HQDKNY2JA== - dependencies: - "@babel/runtime" "^7.12.1" - "@types/react-redux" "^7.1.16" - hoist-non-react-statics "^3.3.2" - loose-envify "^1.4.0" - prop-types "^15.7.2" - react-is "^16.13.1" - -react@^17.0.2: - version "17.0.2" - resolved "https://registry.yarnpkg.com/react/-/react-17.0.2.tgz#d0b5cc516d29eb3eee383f75b62864cfb6800037" - integrity sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA== - dependencies: - loose-envify "^1.1.0" - object-assign "^4.1.1" - -redux-watch@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/redux-watch/-/redux-watch-1.2.0.tgz#b3a745e15855ef72db0e06a60a4b2fe3676d79a7" - integrity sha512-Ws4Q+e5zFGMyy1H709c1Ws8apSd6MqoJRIzBDHbI4nikome/IZWVTYXdQNz+VJxPjyX/h2E+lYEo41fXgjCF8g== - dependencies: - object-path "^0.11.5" - -redux@^4.0.0, redux@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/redux/-/redux-4.1.0.tgz#eb049679f2f523c379f1aff345c8612f294c88d4" - integrity sha512-uI2dQN43zqLWCt6B/BMGRMY6db7TTY4qeHHfGeKb3EOhmOKjU3KdWvNLJyqaHRksv/ErdNH7cFZWg9jXtewy4g== - dependencies: - "@babel/runtime" "^7.9.2" - -regenerator-runtime@^0.13.4: - version "0.13.7" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz#cac2dacc8a1ea675feaabaeb8ae833898ae46f55" - integrity sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew== - -"safer-buffer@>= 2.1.2 < 3.0.0": - version "2.1.2" - resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" - integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== - -scheduler@^0.20.2: - version "0.20.2" - resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.20.2.tgz#4baee39436e34aa93b4874bddcbf0fe8b8b50e91" - integrity sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ== - dependencies: - loose-envify "^1.1.0" - object-assign "^4.1.1" - -schema-utils@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.0.0.tgz#67502f6aa2b66a2d4032b4279a2944978a0913ef" - integrity sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA== - dependencies: - "@types/json-schema" "^7.0.6" - ajv "^6.12.5" - ajv-keywords "^3.5.2" - -semver@^7.3.5: - version "7.3.5" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" - integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ== - dependencies: - lru-cache "^6.0.0" - -source-list-map@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34" - integrity sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw== - -source-map-js@^0.6.2: - version "0.6.2" - resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-0.6.2.tgz#0bb5de631b41cfbda6cfba8bd05a80efdfd2385e" - integrity sha512-/3GptzWzu0+0MBQFrDKzw/DvvMTUORvgY6k6jd/VS6iCR4RDTKWH6v6WPwQoUO8667uQEf9Oe38DxAYWY5F/Ug== - -source-map@~0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" - integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== - -strip-ansi@~0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-0.1.1.tgz#39e8a98d044d150660abe4a6808acf70bb7bc991" - integrity sha1-OeipjQRNFQZgq+SmgIrPcLt7yZE= - -underscore@~1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.6.0.tgz#8b38b10cacdef63337b8b24e4ff86d45aea529a8" - integrity sha1-izixDKze9jM3uLJOT/htRa6lKag= - -uri-js@^4.2.2: - version "4.4.1" - resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" - integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== - dependencies: - punycode "^2.1.0" - -url-loader@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/url-loader/-/url-loader-4.1.1.tgz#28505e905cae158cf07c92ca622d7f237e70a4e2" - integrity sha512-3BTV812+AVHHOJQO8O5MkWgZ5aosP7GnROJwvzLS9hWDj00lZ6Z0wNak423Lp9PBZN05N+Jk/N5Si8jRAlGyWA== - dependencies: - loader-utils "^2.0.0" - mime-types "^2.1.27" - schema-utils "^3.0.0" - -util-deprecate@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" - integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= - -webpack-sources@^1.1.0: - version "1.4.3" - resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.4.3.tgz#eedd8ec0b928fbf1cbfe994e22d2d890f330a933" - integrity sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ== - dependencies: - source-list-map "^2.0.0" - source-map "~0.6.1" - -yallist@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" - integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== diff --git a/bin/setup b/bin/setup index 7281e17..a5e87bd 100755 --- a/bin/setup +++ b/bin/setup @@ -16,6 +16,4 @@ mix ecto.migrate # Grab JS dependencies from NPM echo "Installing js dependencies" -cd assets -yarn install -cd .. +npm install --prefix assets From 1e411e2e7376fc49d1f0f13e4f8caecc7d39d09d Mon Sep 17 00:00:00 2001 From: Dan Barber Date: Wed, 25 Oct 2023 16:15:21 -0500 Subject: [PATCH 17/24] Get ESBuild and Sass working again --- config/config.exs | 8 +-- config/dev.exs | 5 +- lib/chess_web/templates/layout/_head.html.eex | 2 +- .../templates/layout/_scripts.html.eex | 1 - mix.exs | 11 +-- mix.lock | 72 ++++++++++--------- 6 files changed, 52 insertions(+), 47 deletions(-) diff --git a/config/config.exs b/config/config.exs index 494e551..cc9aaad 100644 --- a/config/config.exs +++ b/config/config.exs @@ -36,19 +36,19 @@ config :formulator, # Configure esbuild (the version is required) config :esbuild, - version: "0.17.5", + version: "0.19.4", default: [ args: - ~w(js/app.js --bundle --target=es2017 --outdir=../priv/static/assets --external:/fonts/* --external:/images/* --loader:.js=jsx), + ~w(js/app.js --bundle --target=es2017 --outdir=../priv/static/js --external:/fonts/* --external:/images/* --loader:.js=jsx), cd: Path.expand("../assets", __DIR__), env: %{"NODE_PATH" => Path.expand("../deps", __DIR__)} ] # Configure dart_sass config :dart_sass, - version: "1.58.0", + version: "1.69.3", default: [ - args: ~w(css/app.scss ../priv/static/assets/app.css), + args: ~w(css/app.scss ../priv/static/css/app.css), cd: Path.expand("../assets", __DIR__) ] diff --git a/config/dev.exs b/config/dev.exs index e1d21d3..1a19f65 100644 --- a/config/dev.exs +++ b/config/dev.exs @@ -10,7 +10,10 @@ config :chess, ChessWeb.Endpoint, http: [port: 4000], debug_errors: true, code_reloader: true, - check_origin: false + check_origin: false, + watchers: [ + esbuild: {Esbuild, :install_and_run, [:default, ~w(--sourcemap=inline --watch)]} + ] # Watch static and templates for browser reloading. config :chess, ChessWeb.Endpoint, diff --git a/lib/chess_web/templates/layout/_head.html.eex b/lib/chess_web/templates/layout/_head.html.eex index 9524c8b..2f77b33 100644 --- a/lib/chess_web/templates/layout/_head.html.eex +++ b/lib/chess_web/templates/layout/_head.html.eex @@ -4,7 +4,7 @@ - <%= csrf_meta_tag() %> + <%= gettext "64squares" %> diff --git a/lib/chess_web/templates/layout/_scripts.html.eex b/lib/chess_web/templates/layout/_scripts.html.eex index 02735d8..11aad3a 100644 --- a/lib/chess_web/templates/layout/_scripts.html.eex +++ b/lib/chess_web/templates/layout/_scripts.html.eex @@ -1,3 +1,2 @@ - diff --git a/mix.exs b/mix.exs index c1b9208..98b06cc 100644 --- a/mix.exs +++ b/mix.exs @@ -7,7 +7,7 @@ defmodule Chess.Mixfile do version: "0.2.0", elixir: "~> 1.14.1", elixirc_paths: elixirc_paths(Mix.env()), - compilers: [:phoenix] ++ Mix.compilers(), + compilers: [] ++ Mix.compilers(), build_embedded: Mix.env() == :prod, start_permanent: Mix.env() == :prod, aliases: aliases(), @@ -42,16 +42,17 @@ defmodule Chess.Mixfile do {:dart_sass, "~> 0.5", runtime: Mix.env() == :dev}, {:ecto_sql, "~> 3.0"}, {:floki, "~> 0.34", only: :test}, - {:esbuild, "~> 0.6", runtime: Mix.env() == :dev}, + {:esbuild, "~> 0.7", runtime: Mix.env() == :dev}, {:formulator, "~> 0.4.0"}, {:gettext, "~> 0.22.0"}, {:guardian, "~> 2.0"}, {:jason, "~> 1.0"}, - {:phoenix, "~> 1.6.0"}, + {:phoenix, "~> 1.7.0"}, + {:phoenix_view, "~> 2.0"}, {:phoenix_ecto, "~> 4.0"}, - {:phoenix_html, "~> 3.2.0"}, + {:phoenix_html, "~> 3.3.0"}, {:phoenix_live_reload, "~> 1.0", only: :dev}, - {:phoenix_live_view, "~> 0.18"}, + {:phoenix_live_view, "~> 0.20"}, {:phoenix_pubsub, "~> 2.0"}, {:plug_cowboy, "~> 2.0"}, {:postgrex, "~> 0.16.0"}, diff --git a/mix.lock b/mix.lock index d11eb94..04adc81 100644 --- a/mix.lock +++ b/mix.lock @@ -1,61 +1,63 @@ %{ - "argon2_elixir": {:hex, :argon2_elixir, "3.0.0", "fd4405f593e77b525a5c667282172dd32772d7c4fa58cdecdaae79d2713b6c5f", [:make, :mix], [{:comeonin, "~> 5.3", [hex: :comeonin, repo: "hexpm", optional: false]}, {:elixir_make, "~> 0.6", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm", "8b753b270af557d51ba13fcdebc0f0ab27a2a6792df72fd5a6cf9cfaffcedc57"}, + "argon2_elixir": {:hex, :argon2_elixir, "3.2.1", "f47740bf9f2a39ffef79ba48eb25dea2ee37bcc7eadf91d49615591d1a6fce1a", [:make, :mix], [{:comeonin, "~> 5.3", [hex: :comeonin, repo: "hexpm", optional: false]}, {:elixir_make, "~> 0.6", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm", "a813b78217394530b5fcf4c8070feee43df03ffef938d044019169c766315690"}, "bamboo": {:hex, :bamboo, "2.3.0", "d2392a2cabe91edf488553d3c70638b532e8db7b76b84b0a39e3dfe492ffd6fc", [:mix], [{:hackney, ">= 1.15.2", [hex: :hackney, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:mime, "~> 1.4 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "dd0037e68e108fd04d0e8773921512c940e35d981e097b5793543e3b2f9cd3f6"}, "bunt": {:hex, :bunt, "0.2.1", "e2d4792f7bc0ced7583ab54922808919518d0e57ee162901a16a1b6664ef3b14", [:mix], [], "hexpm", "a330bfb4245239787b15005e66ae6845c9cd524a288f0d141c148b02603777a5"}, - "castore": {:hex, :castore, "0.1.22", "4127549e411bedd012ca3a308dede574f43819fe9394254ca55ab4895abfa1a2", [:mix], [], "hexpm", "c17576df47eb5aa1ee40cc4134316a99f5cad3e215d5c77b8dd3cfef12a22cac"}, - "certifi": {:hex, :certifi, "2.9.0", "6f2a475689dd47f19fb74334859d460a2dc4e3252a3324bd2111b8f0429e7e21", [:rebar3], [], "hexpm", "266da46bdb06d6c6d35fde799bcb28d36d985d424ad7c08b5bb48f5b5cdd4641"}, + "castore": {:hex, :castore, "1.0.4", "ff4d0fb2e6411c0479b1d965a814ea6d00e51eb2f58697446e9c41a97d940b28", [:mix], [], "hexpm", "9418c1b8144e11656f0be99943db4caf04612e3eaecefb5dae9a2a87565584f8"}, + "certifi": {:hex, :certifi, "2.12.0", "2d1cca2ec95f59643862af91f001478c9863c2ac9cb6e2f89780bfd8de987329", [:rebar3], [], "hexpm", "ee68d85df22e554040cdb4be100f33873ac6051387baf6a8f6ce82272340ff1c"}, "combine": {:hex, :combine, "0.10.0", "eff8224eeb56498a2af13011d142c5e7997a80c8f5b97c499f84c841032e429f", [:mix], [], "hexpm", "1b1dbc1790073076580d0d1d64e42eae2366583e7aecd455d1215b0d16f2451b"}, - "comeonin": {:hex, :comeonin, "5.3.3", "2c564dac95a35650e9b6acfe6d2952083d8a08e4a89b93a481acb552b325892e", [:mix], [], "hexpm", "3e38c9c2cb080828116597ca8807bb482618a315bfafd98c90bc22a821cc84df"}, + "comeonin": {:hex, :comeonin, "5.4.0", "246a56ca3f41d404380fc6465650ddaa532c7f98be4bda1b4656b3a37cc13abe", [:mix], [], "hexpm", "796393a9e50d01999d56b7b8420ab0481a7538d0caf80919da493b4a6e51faf1"}, "connection": {:hex, :connection, "1.1.0", "ff2a49c4b75b6fb3e674bfc5536451607270aac754ffd1bdfe175abe4a6d7a68", [:mix], [], "hexpm", "722c1eb0a418fbe91ba7bd59a47e28008a189d47e37e0e7bb85585a016b2869c"}, - "cowboy": {:hex, :cowboy, "2.9.0", "865dd8b6607e14cf03282e10e934023a1bd8be6f6bacf921a7e2a96d800cd452", [:make, :rebar3], [{:cowlib, "2.11.0", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "1.8.0", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm", "2c729f934b4e1aa149aff882f57c6372c15399a20d54f65c8d67bef583021bde"}, + "cowboy": {:hex, :cowboy, "2.10.0", "ff9ffeff91dae4ae270dd975642997afe2a1179d94b1887863e43f681a203e26", [:make, :rebar3], [{:cowlib, "2.12.1", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "1.8.0", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm", "3afdccb7183cc6f143cb14d3cf51fa00e53db9ec80cdcd525482f5e99bc41d6b"}, "cowboy_telemetry": {:hex, :cowboy_telemetry, "0.4.0", "f239f68b588efa7707abce16a84d0d2acf3a0f50571f8bb7f56a15865aae820c", [:rebar3], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "7d98bac1ee4565d31b62d59f8823dfd8356a169e7fcbb83831b8a5397404c9de"}, - "cowlib": {:hex, :cowlib, "2.11.0", "0b9ff9c346629256c42ebe1eeb769a83c6cb771a6ee5960bd110ab0b9b872063", [:make, :rebar3], [], "hexpm", "2b3e9da0b21c4565751a6d4901c20d1b4cc25cbb7fd50d91d2ab6dd287bc86a9"}, - "credo": {:hex, :credo, "1.6.7", "323f5734350fd23a456f2688b9430e7d517afb313fbd38671b8a4449798a7854", [:mix], [{:bunt, "~> 0.2.1", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2.8", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "41e110bfb007f7eda7f897c10bf019ceab9a0b269ce79f015d54b0dcf4fc7dd3"}, - "dart_sass": {:hex, :dart_sass, "0.5.1", "d45f20a8e324313689fb83287d4702352793ce8c9644bc254155d12656ade8b6", [:mix], [{:castore, ">= 0.0.0", [hex: :castore, repo: "hexpm", optional: false]}], "hexpm", "24f8a1c67e8b5267c51a33cbe6c0b5ebf12c2c83ace88b5ac04947d676b4ec81"}, - "db_connection": {:hex, :db_connection, "2.4.3", "3b9aac9f27347ec65b271847e6baeb4443d8474289bd18c1d6f4de655b70c94d", [:mix], [{:connection, "~> 1.0", [hex: :connection, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "c127c15b0fa6cfb32eed07465e05da6c815b032508d4ed7c116122871df73c12"}, + "cowlib": {:hex, :cowlib, "2.12.1", "a9fa9a625f1d2025fe6b462cb865881329b5caff8f1854d1cbc9f9533f00e1e1", [:make, :rebar3], [], "hexpm", "163b73f6367a7341b33c794c4e88e7dbfe6498ac42dcd69ef44c5bc5507c8db0"}, + "credo": {:hex, :credo, "1.7.1", "6e26bbcc9e22eefbff7e43188e69924e78818e2fe6282487d0703652bc20fd62", [:mix], [{:bunt, "~> 0.2.1", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2.8", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "e9871c6095a4c0381c89b6aa98bc6260a8ba6addccf7f6a53da8849c748a58a2"}, + "dart_sass": {:hex, :dart_sass, "0.7.0", "7979e056cb74fd6843e1c72db763cffc7726a9192a657735b7d24c0d9c26a1ce", [:mix], [{:castore, ">= 0.0.0", [hex: :castore, repo: "hexpm", optional: false]}], "hexpm", "4a8e70bca41aa00846398abdf5ad8a64d7907a0f7bf40145cd2e40d5971629f2"}, + "db_connection": {:hex, :db_connection, "2.5.0", "bb6d4f30d35ded97b29fe80d8bd6f928a1912ca1ff110831edcd238a1973652c", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "c92d5ba26cd69ead1ff7582dbb860adeedfff39774105a4f1c92cbb654b55aa2"}, "decimal": {:hex, :decimal, "2.1.1", "5611dca5d4b2c3dd497dec8f68751f1f1a54755e8ed2a966c2633cf885973ad6", [:mix], [], "hexpm", "53cfe5f497ed0e7771ae1a475575603d77425099ba5faef9394932b35020ffcc"}, - "ecto": {:hex, :ecto, "3.9.6", "2f420c173efcb2e22fa4f8fc41e75e02b3c5bd4cffef12085cae5418c12e530d", [:mix], [{:decimal, "~> 1.6 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "df17bc06ba6f78a7b764e4a14ef877fe5f4499332c5a105ace11fe7013b72c84"}, - "ecto_sql": {:hex, :ecto_sql, "3.9.2", "34227501abe92dba10d9c3495ab6770e75e79b836d114c41108a4bf2ce200ad5", [:mix], [{:db_connection, "~> 2.5 or ~> 2.4.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.9.2", [hex: :ecto, repo: "hexpm", optional: false]}, {:myxql, "~> 0.6.0", [hex: :myxql, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.16.0 or ~> 1.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:tds, "~> 2.1.1 or ~> 2.2", [hex: :tds, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "1eb5eeb4358fdbcd42eac11c1fbd87e3affd7904e639d77903c1358b2abd3f70"}, - "elixir_make": {:hex, :elixir_make, "0.7.3", "c37fdae1b52d2cc51069713a58c2314877c1ad40800a57efb213f77b078a460d", [:mix], [{:castore, "~> 0.1", [hex: :castore, repo: "hexpm", optional: true]}], "hexpm", "24ada3e3996adbed1fa024ca14995ef2ba3d0d17b678b0f3f2b1f66e6ce2b274"}, - "esbuild": {:hex, :esbuild, "0.6.0", "9ba6ead054abd43cb3d7b14946a0cdd1493698ccd8e054e0e5d6286d7f0f509c", [:mix], [{:castore, ">= 0.0.0", [hex: :castore, repo: "hexpm", optional: false]}], "hexpm", "30f9a05d4a5bab0d3e37398f312f80864e1ee1a081ca09149d06d474318fd040"}, - "expo": {:hex, :expo, "0.3.0", "13127c1d5f653b2927f2616a4c9ace5ae372efd67c7c2693b87fd0fdc30c6feb", [:mix], [], "hexpm", "fb3cd4bf012a77bc1608915497dae2ff684a06f0fa633c7afa90c4d72b881823"}, + "ecto": {:hex, :ecto, "3.10.3", "eb2ae2eecd210b4eb8bece1217b297ad4ff824b4384c0e3fdd28aaf96edd6135", [:mix], [{:decimal, "~> 1.6 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "44bec74e2364d491d70f7e42cd0d690922659d329f6465e89feb8a34e8cd3433"}, + "ecto_sql": {:hex, :ecto_sql, "3.10.2", "6b98b46534b5c2f8b8b5f03f126e75e2a73c64f3c071149d32987a5378b0fdbd", [:mix], [{:db_connection, "~> 2.4.1 or ~> 2.5", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.10.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:myxql, "~> 0.6.0", [hex: :myxql, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.16.0 or ~> 0.17.0 or ~> 1.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:tds, "~> 2.1.1 or ~> 2.2", [hex: :tds, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "68c018debca57cb9235e3889affdaec7a10616a4e3a80c99fa1d01fdafaa9007"}, + "elixir_make": {:hex, :elixir_make, "0.7.7", "7128c60c2476019ed978210c245badf08b03dbec4f24d05790ef791da11aa17c", [:mix], [{:castore, "~> 0.1 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}], "hexpm", "5bc19fff950fad52bbe5f211b12db9ec82c6b34a9647da0c2224b8b8464c7e6c"}, + "esbuild": {:hex, :esbuild, "0.7.1", "fa0947e8c3c3c2f86c9bf7e791a0a385007ccd42b86885e8e893bdb6631f5169", [:mix], [{:castore, ">= 0.0.0", [hex: :castore, repo: "hexpm", optional: false]}], "hexpm", "66661cdf70b1378ee4dc16573fcee67750b59761b2605a0207c267ab9d19f13c"}, + "expo": {:hex, :expo, "0.4.1", "1c61d18a5df197dfda38861673d392e642649a9cef7694d2f97a587b2cfb319b", [:mix], [], "hexpm", "2ff7ba7a798c8c543c12550fa0e2cbc81b95d4974c65855d8d15ba7b37a1ce47"}, "file_system": {:hex, :file_system, "0.2.10", "fb082005a9cd1711c05b5248710f8826b02d7d1784e7c3451f9c1231d4fc162d", [:mix], [], "hexpm", "41195edbfb562a593726eda3b3e8b103a309b733ad25f3d642ba49696bf715dc"}, - "floki": {:hex, :floki, "0.34.0", "002d0cc194b48794d74711731db004fafeb328fe676976f160685262d43706a8", [:mix], [], "hexpm", "9c3a9f43f40dde00332a589bd9d389b90c1f518aef500364d00636acc5ebc99c"}, + "floki": {:hex, :floki, "0.34.3", "5e2dcaec5d7c228ce5b1d3501502e308b2d79eb655e4191751a1fe491c37feac", [:mix], [], "hexpm", "9577440eea5b97924b4bf3c7ea55f7b8b6dce589f9b28b096cc294a8dc342341"}, "formulator": {:hex, :formulator, "0.4.0", "43094c3a63e1ee077a01e79425f823d46e031cf7bc9f74045edcda695601efed", [:mix], [{:gettext, ">= 0.11.0", [hex: :gettext, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.4 or ~> 3.0", [hex: :phoenix_html, repo: "hexpm", optional: false]}], "hexpm", "15c34113d6a797bb03d089a0b976b0cf918d64e24d2096986b61735fffaf1980"}, - "gettext": {:hex, :gettext, "0.22.0", "a25d71ec21b1848957d9207b81fd61cb25161688d282d58bdafef74c2270bdc4", [:mix], [{:expo, "~> 0.3.0", [hex: :expo, repo: "hexpm", optional: false]}], "hexpm", "cb0675141576f73720c8e49b4f0fd3f2c69f0cd8c218202724d4aebab8c70ace"}, - "guardian": {:hex, :guardian, "2.3.1", "2b2d78dc399a7df182d739ddc0e566d88723299bfac20be36255e2d052fd215d", [:mix], [{:jose, "~> 1.8", [hex: :jose, repo: "hexpm", optional: false]}, {:plug, "~> 1.3.3 or ~> 1.4", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "bbe241f9ca1b09fad916ad42d6049d2600bbc688aba5b3c4a6c82592a54274c3"}, - "hackney": {:hex, :hackney, "1.18.1", "f48bf88f521f2a229fc7bae88cf4f85adc9cd9bcf23b5dc8eb6a1788c662c4f6", [:rebar3], [{:certifi, "~>2.9.0", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "~>6.1.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "~>1.0.0", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~>1.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:parse_trans, "3.3.1", [hex: :parse_trans, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "~>1.1.0", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}, {:unicode_util_compat, "~>0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "a4ecdaff44297e9b5894ae499e9a070ea1888c84afdd1fd9b7b2bc384950128e"}, - "httpoison": {:hex, :httpoison, "1.8.2", "9eb9c63ae289296a544842ef816a85d881d4a31f518a0fec089aaa744beae290", [:mix], [{:hackney, "~> 1.17", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "2bb350d26972e30c96e2ca74a1aaf8293d61d0742ff17f01e0279fef11599921"}, - "idna": {:hex, :idna, "6.1.1", "8a63070e9f7d0c62eb9d9fcb360a7de382448200fbbd1b106cc96d3d8099df8d", [:rebar3], [{:unicode_util_compat, "~>0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "92376eb7894412ed19ac475e4a86f7b413c1b9fbb5bd16dccd57934157944cea"}, + "gettext": {:hex, :gettext, "0.22.3", "c8273e78db4a0bb6fba7e9f0fd881112f349a3117f7f7c598fa18c66c888e524", [:mix], [{:expo, "~> 0.4.0", [hex: :expo, repo: "hexpm", optional: false]}], "hexpm", "935f23447713954a6866f1bb28c3a878c4c011e802bcd68a726f5e558e4b64bd"}, + "guardian": {:hex, :guardian, "2.3.2", "78003504b987f2b189d76ccf9496ceaa6a454bb2763627702233f31eb7212881", [:mix], [{:jose, "~> 1.8", [hex: :jose, repo: "hexpm", optional: false]}, {:plug, "~> 1.3.3 or ~> 1.4", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "b189ff38cd46a22a8a824866a6867ca8722942347f13c33f7d23126af8821b52"}, + "hackney": {:hex, :hackney, "1.20.1", "8d97aec62ddddd757d128bfd1df6c5861093419f8f7a4223823537bad5d064e2", [:rebar3], [{:certifi, "~> 2.12.0", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "~> 6.1.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "~> 1.0.0", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~> 1.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:parse_trans, "3.4.1", [hex: :parse_trans, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "~> 1.1.0", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}, {:unicode_util_compat, "~> 0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "fe9094e5f1a2a2c0a7d10918fee36bfec0ec2a979994cff8cfe8058cd9af38e3"}, + "httpoison": {:hex, :httpoison, "2.1.0", "655fd9a7b0b95ee3e9a3b535cf7ac8e08ef5229bab187fa86ac4208b122d934b", [:mix], [{:hackney, "~> 1.17", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "fc455cb4306b43827def4f57299b2d5ac8ac331cb23f517e734a4b78210a160c"}, + "idna": {:hex, :idna, "6.1.1", "8a63070e9f7d0c62eb9d9fcb360a7de382448200fbbd1b106cc96d3d8099df8d", [:rebar3], [{:unicode_util_compat, "~> 0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "92376eb7894412ed19ac475e4a86f7b413c1b9fbb5bd16dccd57934157944cea"}, "jason": {:hex, :jason, "1.4.1", "af1504e35f629ddcdd6addb3513c3853991f694921b1b9368b0bd32beb9f1b63", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "fbb01ecdfd565b56261302f7e1fcc27c4fb8f32d56eab74db621fc154604a7a1"}, - "jose": {:hex, :jose, "1.11.5", "3bc2d75ffa5e2c941ca93e5696b54978323191988eb8d225c2e663ddfefd515e", [:mix, :rebar3], [], "hexpm", "dcd3b215bafe02ea7c5b23dafd3eb8062a5cd8f2d904fd9caa323d37034ab384"}, + "jose": {:hex, :jose, "1.11.6", "613fda82552128aa6fb804682e3a616f4bc15565a048dabd05b1ebd5827ed965", [:mix, :rebar3], [], "hexpm", "6275cb75504f9c1e60eeacb771adfeee4905a9e182103aa59b53fed651ff9738"}, "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm", "69b09adddc4f74a40716ae54d140f93beb0fb8978d8636eaded0c31b6f099f16"}, - "mime": {:hex, :mime, "2.0.3", "3676436d3d1f7b81b5a2d2bd8405f412c677558c81b1c92be58c00562bb59095", [:mix], [], "hexpm", "27a30bf0db44d25eecba73755acf4068cbfe26a4372f9eb3e4ea3a45956bff6b"}, + "mime": {:hex, :mime, "2.0.5", "dc34c8efd439abe6ae0343edbb8556f4d63f178594894720607772a041b04b02", [:mix], [], "hexpm", "da0d64a365c45bc9935cc5c8a7fc5e49a0e0f9932a761c55d6c52b142780a05c"}, "mimerl": {:hex, :mimerl, "1.2.0", "67e2d3f571088d5cfd3e550c383094b47159f3eee8ffa08e64106cdf5e981be3", [:rebar3], [], "hexpm", "f278585650aa581986264638ebf698f8bb19df297f66ad91b18910dfc6e19323"}, - "parse_trans": {:hex, :parse_trans, "3.3.1", "16328ab840cc09919bd10dab29e431da3af9e9e7e7e6f0089dd5a2d2820011d8", [:rebar3], [], "hexpm", "07cd9577885f56362d414e8c4c4e6bdf10d43a8767abb92d24cbe8b24c54888b"}, - "phoenix": {:hex, :phoenix, "1.6.15", "0a1d96bbc10747fd83525370d691953cdb6f3ccbac61aa01b4acb012474b047d", [:mix], [{:castore, ">= 0.0.0", [hex: :castore, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 2.0", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:phoenix_view, "~> 1.0 or ~> 2.0", [hex: :phoenix_view, repo: "hexpm", optional: false]}, {:plug, "~> 1.10", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 2.2", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:plug_crypto, "~> 1.2", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "d70ab9fbf6b394755ea88b644d34d79d8b146e490973151f248cacd122d20672"}, - "phoenix_ecto": {:hex, :phoenix_ecto, "4.4.0", "0672ed4e4808b3fbed494dded89958e22fb882de47a97634c0b13e7b0b5f7720", [:mix], [{:ecto, "~> 3.3", [hex: :ecto, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.14.2 or ~> 3.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:plug, "~> 1.9", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "09864e558ed31ee00bd48fcc1d4fc58ae9678c9e81649075431e69dbabb43cc1"}, - "phoenix_html": {:hex, :phoenix_html, "3.2.0", "1c1219d4b6cb22ac72f12f73dc5fad6c7563104d083f711c3fcd8551a1f4ae11", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "36ec97ba56d25c0136ef1992c37957e4246b649d620958a1f9fa86165f8bc54f"}, + "parse_trans": {:hex, :parse_trans, "3.4.1", "6e6aa8167cb44cc8f39441d05193be6e6f4e7c2946cb2759f015f8c56b76e5ff", [:rebar3], [], "hexpm", "620a406ce75dada827b82e453c19cf06776be266f5a67cff34e1ef2cbb60e49a"}, + "phoenix": {:hex, :phoenix, "1.7.9", "9a2b873e2cb3955efdd18ad050f1818af097fa3f5fc3a6aaba666da36bdd3f02", [:mix], [{:castore, ">= 0.0.0", [hex: :castore, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 2.1", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:phoenix_template, "~> 1.0", [hex: :phoenix_template, repo: "hexpm", optional: false]}, {:phoenix_view, "~> 2.0", [hex: :phoenix_view, repo: "hexpm", optional: true]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 2.6", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:plug_crypto, "~> 1.2 or ~> 2.0", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}, {:websock_adapter, "~> 0.5.3", [hex: :websock_adapter, repo: "hexpm", optional: false]}], "hexpm", "83e32da028272b4bfd076c61a964e6d2b9d988378df2f1276a0ed21b13b5e997"}, + "phoenix_ecto": {:hex, :phoenix_ecto, "4.4.2", "b21bd01fdeffcfe2fab49e4942aa938b6d3e89e93a480d4aee58085560a0bc0d", [:mix], [{:ecto, "~> 3.5", [hex: :ecto, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.14.2 or ~> 3.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:plug, "~> 1.9", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "70242edd4601d50b69273b057ecf7b684644c19ee750989fd555625ae4ce8f5d"}, + "phoenix_html": {:hex, :phoenix_html, "3.3.3", "380b8fb45912b5638d2f1d925a3771b4516b9a78587249cabe394e0a5d579dc9", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "923ebe6fec6e2e3b3e569dfbdc6560de932cd54b000ada0208b5f45024bdd76c"}, "phoenix_live_reload": {:hex, :phoenix_live_reload, "1.4.1", "2aff698f5e47369decde4357ba91fc9c37c6487a512b41732818f2204a8ef1d3", [:mix], [{:file_system, "~> 0.2.1 or ~> 0.3", [hex: :file_system, repo: "hexpm", optional: false]}, {:phoenix, "~> 1.4", [hex: :phoenix, repo: "hexpm", optional: false]}], "hexpm", "9bffb834e7ddf08467fe54ae58b5785507aaba6255568ae22b4d46e2bb3615ab"}, - "phoenix_live_view": {:hex, :phoenix_live_view, "0.18.11", "c50eac83dae6b5488859180422dfb27b2c609de87f4aa5b9c926ecd0501cd44f", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix, "~> 1.6.15 or ~> 1.7.0", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 3.1", [hex: :phoenix_html, repo: "hexpm", optional: false]}, {:phoenix_template, "~> 1.0", [hex: :phoenix_template, repo: "hexpm", optional: false]}, {:phoenix_view, "~> 2.0", [hex: :phoenix_view, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.2 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "76c99a0ffb47cd95bf06a917e74f282a603f3e77b00375f3c2dd95110971b102"}, - "phoenix_pubsub": {:hex, :phoenix_pubsub, "2.1.1", "ba04e489ef03763bf28a17eb2eaddc2c20c6d217e2150a61e3298b0f4c2012b5", [:mix], [], "hexpm", "81367c6d1eea5878ad726be80808eb5a787a23dee699f96e72b1109c57cdd8d9"}, - "phoenix_template": {:hex, :phoenix_template, "1.0.1", "85f79e3ad1b0180abb43f9725973e3b8c2c3354a87245f91431eec60553ed3ef", [:mix], [{:phoenix_html, "~> 2.14.2 or ~> 3.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}], "hexpm", "157dc078f6226334c91cb32c1865bf3911686f8bcd6bcff86736f6253e6993ee"}, + "phoenix_live_view": {:hex, :phoenix_live_view, "0.20.1", "92a37acf07afca67ac98bd326532ba8f44ad7d4bdf3e4361b03f7f02594e5ae9", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix, "~> 1.6.15 or ~> 1.7.0", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 3.3", [hex: :phoenix_html, repo: "hexpm", optional: false]}, {:phoenix_template, "~> 1.0", [hex: :phoenix_template, repo: "hexpm", optional: false]}, {:phoenix_view, "~> 2.0", [hex: :phoenix_view, repo: "hexpm", optional: true]}, {:plug, "~> 1.15", [hex: :plug, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.2 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "be494fd1215052729298b0e97d5c2ce8e719c00854b82cd8cf15c1cd7fcf6294"}, + "phoenix_pubsub": {:hex, :phoenix_pubsub, "2.1.3", "3168d78ba41835aecad272d5e8cd51aa87a7ac9eb836eabc42f6e57538e3731d", [:mix], [], "hexpm", "bba06bc1dcfd8cb086759f0edc94a8ba2bc8896d5331a1e2c2902bf8e36ee502"}, + "phoenix_template": {:hex, :phoenix_template, "1.0.3", "32de561eefcefa951aead30a1f94f1b5f0379bc9e340bb5c667f65f1edfa4326", [:mix], [{:phoenix_html, "~> 2.14.2 or ~> 3.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}], "hexpm", "16f4b6588a4152f3cc057b9d0c0ba7e82ee23afa65543da535313ad8d25d8e2c"}, "phoenix_view": {:hex, :phoenix_view, "2.0.2", "6bd4d2fd595ef80d33b439ede6a19326b78f0f1d8d62b9a318e3d9c1af351098", [:mix], [{:phoenix_html, "~> 2.14.2 or ~> 3.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:phoenix_template, "~> 1.0", [hex: :phoenix_template, repo: "hexpm", optional: false]}], "hexpm", "a929e7230ea5c7ee0e149ffcf44ce7cf7f4b6d2bfe1752dd7c084cdff152d36f"}, - "plug": {:hex, :plug, "1.14.0", "ba4f558468f69cbd9f6b356d25443d0b796fbdc887e03fa89001384a9cac638f", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.1.1 or ~> 1.2", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.3 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "bf020432c7d4feb7b3af16a0c2701455cbbbb95e5b6866132cb09eb0c29adc14"}, - "plug_cowboy": {:hex, :plug_cowboy, "2.6.0", "d1cf12ff96a1ca4f52207c5271a6c351a4733f413803488d75b70ccf44aebec2", [:mix], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:cowboy_telemetry, "~> 0.3", [hex: :cowboy_telemetry, repo: "hexpm", optional: false]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "073cf20b753ce6682ed72905cd62a2d4bd9bad1bf9f7feb02a1b8e525bd94fa6"}, - "plug_crypto": {:hex, :plug_crypto, "1.2.3", "8f77d13aeb32bfd9e654cb68f0af517b371fb34c56c9f2b58fe3df1235c1251a", [:mix], [], "hexpm", "b5672099c6ad5c202c45f5a403f21a3411247f164e4a8fab056e5cd8a290f4a2"}, + "plug": {:hex, :plug, "1.15.1", "b7efd81c1a1286f13efb3f769de343236bd8b7d23b4a9f40d3002fc39ad8f74c", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.1.1 or ~> 1.2 or ~> 2.0", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.3 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "459497bd94d041d98d948054ec6c0b76feacd28eec38b219ca04c0de13c79d30"}, + "plug_cowboy": {:hex, :plug_cowboy, "2.6.1", "9a3bbfceeb65eff5f39dab529e5cd79137ac36e913c02067dba3963a26efe9b2", [:mix], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:cowboy_telemetry, "~> 0.3", [hex: :cowboy_telemetry, repo: "hexpm", optional: false]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "de36e1a21f451a18b790f37765db198075c25875c64834bcc82d90b309eb6613"}, + "plug_crypto": {:hex, :plug_crypto, "2.0.0", "77515cc10af06645abbfb5e6ad7a3e9714f805ae118fa1a70205f80d2d70fe73", [:mix], [], "hexpm", "53695bae57cc4e54566d993eb01074e4d894b65a3766f1c43e2c61a1b0f45ea9"}, "poison": {:hex, :poison, "4.0.1", "bcb755a16fac91cad79bfe9fc3585bb07b9331e50cfe3420a24bcc2d735709ae", [:mix], [], "hexpm", "ba8836feea4b394bb718a161fc59a288fe0109b5006d6bdf97b6badfcf6f0f25"}, "poolboy": {:hex, :poolboy, "1.5.2", "392b007a1693a64540cead79830443abf5762f5d30cf50bc95cb2c1aaafa006b", [:rebar3], [], "hexpm", "dad79704ce5440f3d5a3681c8590b9dc25d1a561e8f5a9c995281012860901e3"}, "postgrex": {:hex, :postgrex, "0.16.5", "fcc4035cc90e23933c5d69a9cd686e329469446ef7abba2cf70f08e2c4b69810", [:mix], [{:connection, "~> 1.1", [hex: :connection, repo: "hexpm", optional: false]}, {:db_connection, "~> 2.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "edead639dc6e882618c01d8fc891214c481ab9a3788dfe38dd5e37fd1d5fb2e8"}, "ranch": {:hex, :ranch, "1.8.0", "8c7a100a139fd57f17327b6413e4167ac559fbc04ca7448e9be9057311597a1d", [:make, :rebar3], [], "hexpm", "49fbcfd3682fab1f5d109351b61257676da1a2fdbe295904176d5e521a2ddfe5"}, "secure_random": {:hex, :secure_random, "0.5.1", "c5532b37c89d175c328f5196a0c2a5680b15ebce3e654da37129a9fe40ebf51b", [:mix], [], "hexpm", "1b9754f15e3940a143baafd19da12293f100044df69ea12db5d72878312ae6ab"}, - "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.6", "cf344f5692c82d2cd7554f5ec8fd961548d4fd09e7d22f5b62482e5aeaebd4b0", [:make, :mix, :rebar3], [], "hexpm", "bdb0d2471f453c88ff3908e7686f86f9be327d065cc1ec16fa4540197ea04680"}, + "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.7", "354c321cf377240c7b8716899e182ce4890c5938111a1296add3ec74cf1715df", [:make, :mix, :rebar3], [], "hexpm", "fe4c190e8f37401d30167c8c405eda19469f34577987c76dde613e838bbc67f8"}, "telemetry": {:hex, :telemetry, "1.2.1", "68fdfe8d8f05a8428483a97d7aab2f268aaff24b49e0f599faa091f1d4e7f61c", [:rebar3], [], "hexpm", "dad9ce9d8effc621708f99eac538ef1cbe05d6a874dd741de2e689c47feafed5"}, - "tesla": {:hex, :tesla, "1.5.0", "7ee3616be87024a2b7231ae14474310c9b999c3abb1f4f8dbc70f86bd9678eef", [:mix], [{:castore, "~> 0.1", [hex: :castore, repo: "hexpm", optional: true]}, {:exjsx, ">= 3.0.0", [hex: :exjsx, repo: "hexpm", optional: true]}, {:finch, "~> 0.13", [hex: :finch, repo: "hexpm", optional: true]}, {:fuse, "~> 2.4", [hex: :fuse, repo: "hexpm", optional: true]}, {:gun, "~> 1.3", [hex: :gun, repo: "hexpm", optional: true]}, {:hackney, "~> 1.6", [hex: :hackney, repo: "hexpm", optional: true]}, {:ibrowse, "4.4.0", [hex: :ibrowse, repo: "hexpm", optional: true]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: true]}, {:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mint, "~> 1.0", [hex: :mint, repo: "hexpm", optional: true]}, {:msgpax, "~> 2.3", [hex: :msgpax, repo: "hexpm", optional: true]}, {:poison, ">= 1.0.0", [hex: :poison, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: true]}], "hexpm", "1d0385e41fbd76af3961809088aef15dec4c2fdaab97b1c93c6484cb3695a122"}, + "tesla": {:hex, :tesla, "1.7.0", "a62dda2f80d4f8a925eb7b8c5b78c461e0eb996672719fe1a63b26321a5f8b4e", [:mix], [{:castore, "~> 0.1 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:exjsx, ">= 3.0.0", [hex: :exjsx, repo: "hexpm", optional: true]}, {:finch, "~> 0.13", [hex: :finch, repo: "hexpm", optional: true]}, {:fuse, "~> 2.4", [hex: :fuse, repo: "hexpm", optional: true]}, {:gun, "~> 1.3", [hex: :gun, repo: "hexpm", optional: true]}, {:hackney, "~> 1.6", [hex: :hackney, repo: "hexpm", optional: true]}, {:ibrowse, "4.4.0", [hex: :ibrowse, repo: "hexpm", optional: true]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: true]}, {:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mint, "~> 1.0", [hex: :mint, repo: "hexpm", optional: true]}, {:msgpax, "~> 2.3", [hex: :msgpax, repo: "hexpm", optional: true]}, {:poison, ">= 1.0.0", [hex: :poison, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: true]}], "hexpm", "2e64f01ebfdb026209b47bc651a0e65203fcff4ae79c11efb73c4852b00dc313"}, "timex": {:hex, :timex, "3.6.3", "58ce6c9eda8ed47fc80c24dde09d481465838d3bcfc230949287fc1b0b0041c1", [:mix], [{:combine, "~> 0.10", [hex: :combine, repo: "hexpm", optional: false]}, {:gettext, "~> 0.10", [hex: :gettext, repo: "hexpm", optional: false]}, {:tzdata, "~> 0.1.8 or ~> 0.5 or ~> 1.0.0", [hex: :tzdata, repo: "hexpm", optional: false]}], "hexpm", "6d69f4f95fcf5684102a9cb3cf92c5ba6545bd60ed8d8a6a93cd2a4a4fb0d9ec"}, "timex_ecto": {:hex, :timex_ecto, "3.4.0", "7871043345626a591bfa3e313aa271df4a4eda79f51eb69e83f326f0b8f3181c", [:mix], [{:ecto, "~> 2.2", [hex: :ecto, repo: "hexpm", optional: false]}, {:timex, "~> 3.6", [hex: :timex, repo: "hexpm", optional: false]}], "hexpm", "4237fa971c8fb9baeeb901b3ae4efee663e0da335e291228f215d99cf8a64799"}, "tzdata": {:hex, :tzdata, "1.0.5", "69f1ee029a49afa04ad77801febaf69385f3d3e3d1e4b56b9469025677b89a28", [:mix], [{:hackney, "~> 1.0", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "55519aa2a99e5d2095c1e61cc74c9be69688f8ab75c27da724eb8279ff402a5a"}, "unicode_util_compat": {:hex, :unicode_util_compat, "0.7.0", "bc84380c9ab48177092f43ac89e4dfa2c6d62b40b8bd132b1059ecc7232f9a78", [:rebar3], [], "hexpm", "25eee6d67df61960cf6a794239566599b09e17e668d3700247bc498638152521"}, - "wallaby": {:hex, :wallaby, "0.30.1", "81342a34080867ab359aca23de4d1d8c6bbdeb35d8ce2a8c42e42b758d539963", [:mix], [{:ecto_sql, ">= 3.0.0", [hex: :ecto_sql, repo: "hexpm", optional: true]}, {:httpoison, "~> 0.12 or ~> 1.0", [hex: :httpoison, repo: "hexpm", optional: false]}, {:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: false]}, {:phoenix_ecto, ">= 3.0.0", [hex: :phoenix_ecto, repo: "hexpm", optional: true]}, {:web_driver_client, "~> 0.2.0", [hex: :web_driver_client, repo: "hexpm", optional: false]}], "hexpm", "457251df6a94ff80816524136edbce6400cb1ee979586c90224ff634e9543d78"}, + "wallaby": {:hex, :wallaby, "0.30.6", "7dc4c1213f3b52c4152581d126632bc7e06892336d3a0f582853efeeabd45a71", [:mix], [{:ecto_sql, ">= 3.0.0", [hex: :ecto_sql, repo: "hexpm", optional: true]}, {:httpoison, "~> 0.12 or ~> 1.0 or ~> 2.0", [hex: :httpoison, repo: "hexpm", optional: false]}, {:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: false]}, {:phoenix_ecto, ">= 3.0.0", [hex: :phoenix_ecto, repo: "hexpm", optional: true]}, {:web_driver_client, "~> 0.2.0", [hex: :web_driver_client, repo: "hexpm", optional: false]}], "hexpm", "50950c1d968549b54c20e16175c68c7fc0824138e2bb93feb11ef6add8eb23d4"}, "web_driver_client": {:hex, :web_driver_client, "0.2.0", "63b76cd9eb3b0716ec5467a0f8bead73d3d9612e63f7560d21357f03ad86e31a", [:mix], [{:hackney, "~> 1.6", [hex: :hackney, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:tesla, "~> 1.3", [hex: :tesla, repo: "hexpm", optional: false]}], "hexpm", "83cc6092bc3e74926d1c8455f0ce927d5d1d36707b74d9a65e38c084aab0350f"}, + "websock": {:hex, :websock, "0.5.3", "2f69a6ebe810328555b6fe5c831a851f485e303a7c8ce6c5f675abeb20ebdadc", [:mix], [], "hexpm", "6105453d7fac22c712ad66fab1d45abdf049868f253cf719b625151460b8b453"}, + "websock_adapter": {:hex, :websock_adapter, "0.5.4", "7af8408e7ed9d56578539594d1ee7d8461e2dd5c3f57b0f2a5352d610ddde757", [:mix], [{:bandit, ">= 0.6.0", [hex: :bandit, repo: "hexpm", optional: true]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 2.6", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:websock, "~> 0.5", [hex: :websock, repo: "hexpm", optional: false]}], "hexpm", "d2c238c79c52cbe223fcdae22ca0bb5007a735b9e933870e241fce66afb4f4ab"}, } From 2314dc6a19a4886cef19b22db1d09d5abba502b3 Mon Sep 17 00:00:00 2001 From: Dan Barber Date: Wed, 25 Oct 2023 16:21:02 -0500 Subject: [PATCH 18/24] Game now works using LiveView --- assets/css/components/_board.scss | 44 ++----------------- lib/chess/board.ex | 18 +++++--- lib/chess/moves.ex | 2 + lib/chess_web.ex | 7 +-- lib/chess_web/channels/game_channel.ex | 5 +-- lib/chess_web/endpoint.ex | 5 +-- lib/chess_web/router.ex | 7 --- lib/chess_web/templates/game/board.html.leex | 9 ++-- .../templates/game/game_info.html.leex | 21 +++++++-- lib/chess_web/views/game_view.ex | 35 +++++++++++++-- lib/chess_web/views/live/board_live.ex | 30 +++++++++---- lib/chess_web/views/live/game_info_live.ex | 16 +++++++ 12 files changed, 119 insertions(+), 80 deletions(-) diff --git a/assets/css/components/_board.scss b/assets/css/components/_board.scss index c9fac3c..5d0ef5f 100644 --- a/assets/css/components/_board.scss +++ b/assets/css/components/_board.scss @@ -8,16 +8,13 @@ width: 1.5%; } -.board__container { - grid-area: board; -} - .board { background: $background-color; border-collapse: unset; border-radius: 2.8%; border-spacing: 1px; color: $foreground-color; + grid-area: board; height: var(--board-size); padding: calc(var(--board-size) / 20); position: relative; @@ -61,14 +58,6 @@ display: flex; flex-direction: row; } - - .board__body { - flex-direction: column-reverse; - } - - .board__row { - flex-direction: row; - } } .board--player-is-black { @@ -81,45 +70,20 @@ display: flex; flex-direction: row-reverse; } - - .board__body { - flex-direction: column; - } - - .board__row { - flex-direction: row-reverse; - } } .board__body { background: $background-color; border: 0.25rem solid $foreground-color; border-radius: calc(var(--board-size) / 100); - display: flex; - flex-direction: column; + display: grid; + grid-template-columns: repeat(8, 1fr); + grid-template-rows: repeat(8, 1fr); height: 100%; padding: 1%; width: 100%; } -.board__row { - display: flex; - flex-grow: 1; - - @include odd-between(1, 8) { - .square { - @include odd-between(1, 8) { @extend %square--black; } - @include even-between(1, 8) { @extend %square--white; } - } - } - @include even-between(1, 8) { - .square { - @include odd-between(1, 8) { @extend %square--white; } - @include even-between(1, 8) { @extend %square--black; } - } - } -} - .board__rank-labels { display: none; height: 90%; diff --git a/lib/chess/board.ex b/lib/chess/board.ex index e533e99..63f18fd 100644 --- a/lib/chess/board.ex +++ b/lib/chess/board.ex @@ -1,6 +1,8 @@ defmodule Chess.Board do @moduledoc false + require Logger + def search(board, %{"type" => type, "colour" => colour}) do board |> Enum.filter(fn {_index, piece} -> @@ -17,9 +19,13 @@ defmodule Chess.Board do |> indexes_to_tuples end + def piece(board, {file, rank}) do + board["#{file},#{rank}"] + end + def move_piece(board, %{ - "from" => [from_file, from_rank], - "to" => [to_file, to_rank] + from: {from_file, from_rank}, + to: {to_file, to_rank} }) do {piece, board} = Map.pop(board, to_index({from_file, from_rank})) {piece_captured, board} = Map.pop(board, to_index({to_file, to_rank})) @@ -54,15 +60,15 @@ defmodule Chess.Board do def castling_move(board, %{from: {4, rank}, to: {2, _rank}}) do move_piece(board, %{ - "from" => [0, rank], - "to" => [3, rank] + from: {0, rank}, + to: {3, rank} }) end def castling_move(board, %{"from" => [4, rank], "to" => [6, _rank]}) do move_piece(board, %{ - "from" => [7, rank], - "to" => [5, rank] + from: {7, rank}, + to: {5, rank} }) end diff --git a/lib/chess/moves.ex b/lib/chess/moves.ex index 3fc1c00..73f729a 100644 --- a/lib/chess/moves.ex +++ b/lib/chess/moves.ex @@ -14,6 +14,8 @@ defmodule Chess.Moves do alias Chess.Moves.Pieces.Queen alias Chess.Moves.Pieces.King + require Logger + def make_move(game, move_params) do params = game.board diff --git a/lib/chess_web.ex b/lib/chess_web.ex index aa29f97..db3c672 100644 --- a/lib/chess_web.ex +++ b/lib/chess_web.ex @@ -39,7 +39,8 @@ defmodule ChessWeb do # Import convenience functions from controllers import Phoenix.Controller, only: [get_csrf_token: 0, get_flash: 2, view_module: 1] - import Phoenix.LiveView.Helpers + + import Phoenix.Component # Use all HTML functionality (forms, tags, etc) use Phoenix.HTML @@ -52,11 +53,10 @@ defmodule ChessWeb do end end - def live_view do quote do use Phoenix.LiveView, - layout: {ChessWeb.LayoutView, "live.html"} + layout: {ChessWeb.LayoutView, :live} unquote(view_helpers()) end @@ -90,6 +90,7 @@ defmodule ChessWeb do def router do quote do use Phoenix.Router + import Phoenix.LiveView.Router end end diff --git a/lib/chess_web/channels/game_channel.ex b/lib/chess_web/channels/game_channel.ex index e3707c6..9f85bd9 100644 --- a/lib/chess_web/channels/game_channel.ex +++ b/lib/chess_web/channels/game_channel.ex @@ -5,7 +5,6 @@ defmodule ChessWeb.GameChannel do import ChessWeb.GameView, only: [player: 2, opponent: 2] - alias Chess.Board alias Chess.Emails alias Chess.Mailer alias Chess.MoveList @@ -29,7 +28,7 @@ defmodule ChessWeb.GameChannel do opponent_id: opponent(game, socket.assigns.user_id).id, player: player(game, socket.assigns.user_id), opponent: opponent(game, socket.assigns.user_id).name, - board: Board.transform(game.board), + board: game.board, turn: game.turn, state: game.state, moves: MoveList.transform(game.moves) @@ -135,7 +134,7 @@ defmodule ChessWeb.GameChannel do |> Queries.game_with_moves(socket.assigns.game_id) payload = %{ - board: Board.transform(game.board), + board: game.board, turn: game.turn, state: game.state, moves: MoveList.transform(game.moves) diff --git a/lib/chess_web/endpoint.ex b/lib/chess_web/endpoint.ex index 9a5b77a..fd404cd 100644 --- a/lib/chess_web/endpoint.ex +++ b/lib/chess_web/endpoint.ex @@ -4,15 +4,14 @@ defmodule ChessWeb.Endpoint do @session_options [ store: :cookie, key: "_chess_key", - signing_salt: "9LqUhZTU" + signing_salt: "9LqUhZTU", + same_site: "Lax" ] if sandbox = Application.compile_env(:chess, :sandbox) do plug(Phoenix.Ecto.SQL.Sandbox, sandbox: sandbox) end - socket("/socket", ChessWeb.UserSocket) - socket("/live", Phoenix.LiveView.Socket, websocket: [connect_info: [session: @session_options]]) # Serve at "/" the static files from "priv/static" directory. diff --git a/lib/chess_web/router.ex b/lib/chess_web/router.ex index d640d43..bb56960 100644 --- a/lib/chess_web/router.ex +++ b/lib/chess_web/router.ex @@ -42,13 +42,6 @@ defmodule ChessWeb.Router do resources("/password", PasswordController, only: [:edit, :update], singleton: true) end - # Other scopes may use custom stacks. - scope "/api", as: :api do - pipe_through([:api, :auth, :ensure_auth]) - - resources("/opponents", ChessWeb.Api.OpponentsController, only: [:index]) - end - if Mix.env() == :dev do forward("/sent_emails", Bamboo.SentEmailViewerPlug) end diff --git a/lib/chess_web/templates/game/board.html.leex b/lib/chess_web/templates/game/board.html.leex index d11be6e..f243169 100644 --- a/lib/chess_web/templates/game/board.html.leex +++ b/lib/chess_web/templates/game/board.html.leex @@ -21,9 +21,12 @@
    h
    + <% rank_range = if white?(@user, @game), do: 7..0, else: 0..7 %> + <% file_range = if black?(@user, @game), do: 7..0, else: 0..7 %> +
    - <%= for rank <- 0..7 do %> - <%= for file <- 0..7 do %> + <%= for rank <- rank_range do %> + <%= for file <- file_range do %> <%= render ChessWeb.SquareView, "square.html", rank: rank, @@ -36,6 +39,6 @@
    - <%= states(@game.state) %> + <%= state_text(@game.state) %>
    diff --git a/lib/chess_web/templates/game/game_info.html.leex b/lib/chess_web/templates/game/game_info.html.leex index 8c2c50a..317cab7 100644 --- a/lib/chess_web/templates/game/game_info.html.leex +++ b/lib/chess_web/templates/game/game_info.html.leex @@ -15,10 +15,23 @@
    1.e4
    <%= i + 1 %>."><%= move_text(white_move) %>"><%= move_text(black_move) %>"><%= move_text(white_move) %>
    diff --git a/lib/chess_web/views/game_view.ex b/lib/chess_web/views/game_view.ex index 2be10d8..a76ecc7 100644 --- a/lib/chess_web/views/game_view.ex +++ b/lib/chess_web/views/game_view.ex @@ -6,6 +6,15 @@ defmodule ChessWeb.GameView do import Phoenix.Component import Chess.Auth, only: [current_user: 1] + @pieces %{ + pawn: "", + knight: "N", + bishop: "B", + rook: "R", + queen: "Q", + king: "K" + } + def won_lost(user, game) do if game_over?(game) && game.state == "checkmate" do (your_turn?(user, game) && @@ -21,7 +30,7 @@ defmodule ChessWeb.GameView do def state(user, game) do cond do GameState.game_over?(game) -> - states(game.state) + state_text(game.state) your_turn?(user, game) -> gettext("Your turn") @@ -37,6 +46,14 @@ defmodule ChessWeb.GameView do end end + def white?(user, game) do + player_colour(user, game) == "white" + end + + def black?(user, game) do + player_colour(user, game) == "black" + end + def your_turn?(user, game) do user |> player_colour(game) == game.turn @@ -47,7 +64,7 @@ defmodule ChessWeb.GameView do end def piece(board, {file, rank}) do - board["#{file},#{rank}"] + Chess.Board.piece(board, {file, rank}) end def files(user, game) do @@ -79,7 +96,19 @@ defmodule ChessWeb.GameView do end end - def states(state) do + def move_text(move) do + move = Chess.Store.Move.transform(move) + + piece_type = move.piece["type"] |> String.to_atom() + + [ + @pieces[piece_type], + move.to + ] + |> Enum.join() + end + + def state_text(state) do Map.get( %{ "checkmate" => gettext("Checkmate!"), diff --git a/lib/chess_web/views/live/board_live.ex b/lib/chess_web/views/live/board_live.ex index e58d732..ac062fb 100644 --- a/lib/chess_web/views/live/board_live.ex +++ b/lib/chess_web/views/live/board_live.ex @@ -3,12 +3,18 @@ defmodule ChessWeb.BoardLive do alias Chess.Store.User alias Chess.Store.Game + alias Chess.Store.Move alias Chess.Repo - alias Chess.Board alias Chess.Moves + alias ChessWeb.GameView + + import Ecto.Query + + require Logger + def render(assigns) do - Phoenix.View.render(ChessWeb.GameView, "board.html", assigns) + Phoenix.View.render(GameView, "board.html", assigns) end def mount(_params, %{"user_id" => user_id, "game_id" => game_id}, socket) do @@ -41,6 +47,7 @@ defmodule ChessWeb.BoardLive do end def handle_info(%{event: "move", payload: state}, socket) do + Logger.info("Handling move from board") {:noreply, assign(socket, state)} end @@ -49,7 +56,7 @@ defmodule ChessWeb.BoardLive do board = game.board user = socket.assigns[:user] - colour = ChessWeb.GameView.player_colour(user, game) + colour = GameView.player_colour(user, game) assigns = if colour == game.turn do @@ -66,7 +73,7 @@ defmodule ChessWeb.BoardLive do end defp handle_selection(board, colour, file, rank) do - case Board.piece(board, {file, rank}) do + case GameView.piece(board, {file, rank}) do %{"colour" => ^colour} -> [ {:selected, {file, rank}}, @@ -88,14 +95,21 @@ defmodule ChessWeb.BoardLive do |> Moves.make_move(%{from: selected, to: {file, rank}}) |> case do {:ok, %{game: game}} -> - board = Board.transform(game.board) - - broadcast_move(game, board) + game + |> Repo.preload([:user, :opponent]) + |> Repo.preload( + moves: + from( + move in Move, + order_by: [asc: move.inserted_at] + ) + ) + |> broadcast_move(game.board) [ {:selected, nil}, {:available, []}, - {:board, board}, + {:board, game.board}, {:game, game} ] end diff --git a/lib/chess_web/views/live/game_info_live.ex b/lib/chess_web/views/live/game_info_live.ex index f4447db..63e873e 100644 --- a/lib/chess_web/views/live/game_info_live.ex +++ b/lib/chess_web/views/live/game_info_live.ex @@ -3,23 +3,39 @@ defmodule ChessWeb.GameInfoLive do alias Chess.Store.User alias Chess.Store.Game + alias Chess.Store.Move alias Chess.Repo import Ecto.Query + require Logger + def render(assigns) do Phoenix.View.render(ChessWeb.GameView, "game_info.html", assigns) end def mount(_params, %{"game_id" => game_id, "user_id" => user_id}, socket) do + ChessWeb.Endpoint.subscribe("game:#{game_id}") + user = Repo.get!(User, user_id) game = Game.for_user(user) |> preload(:user) |> preload(:opponent) + |> preload( + moves: + ^from( + move in Move, + order_by: [asc: move.inserted_at] + ) + ) |> Repo.get!(game_id) {:ok, assign(socket, game: game, user: user)} end + + def handle_info(%{event: "move", payload: state}, socket) do + {:noreply, assign(socket, state)} + end end From e30627b3acde23dd431bc1420cbcccd02815f434 Mon Sep 17 00:00:00 2001 From: Dan Barber Date: Wed, 25 Oct 2023 16:21:14 -0500 Subject: [PATCH 19/24] Opponent finder in LiveView --- lib/chess_web/templates/game/new.html.eex | 7 ++- .../templates/game/opponent_finder.html.leex | 32 ++++++++++++ .../views/live/opponent_finder_live.ex | 51 +++++++++++++++++++ 3 files changed, 89 insertions(+), 1 deletion(-) create mode 100644 lib/chess_web/templates/game/opponent_finder.html.leex create mode 100644 lib/chess_web/views/live/opponent_finder_live.ex diff --git a/lib/chess_web/templates/game/new.html.eex b/lib/chess_web/templates/game/new.html.eex index cad9015..c67d600 100644 --- a/lib/chess_web/templates/game/new.html.eex +++ b/lib/chess_web/templates/game/new.html.eex @@ -4,7 +4,12 @@ <%= form_for @changeset, game_path(@conn, :create), [class: "create-game"], fn form -> %>
    -
    + <%= live_render( + @conn, + ChessWeb.OpponentFinderLive, + session: %{"user_id" => current_user(@conn).id} + ) %> + <%= error_tag form, :opponent_id %>
    diff --git a/lib/chess_web/templates/game/opponent_finder.html.leex b/lib/chess_web/templates/game/opponent_finder.html.leex new file mode 100644 index 0000000..0fe0035 --- /dev/null +++ b/lib/chess_web/templates/game/opponent_finder.html.leex @@ -0,0 +1,32 @@ +
    +
    + + + <%= tag :input, + id: "query-string", + class: "search-input", + name: "q", + type: "text", + autocomplete: "off", + "phx-change": "search", + "phx-debounce": "250", + value: @q, + placeholder: Map.get(@selected, :name, "") + %> + <%= tag :input, + name: "game[opponent_id]", + type: "hidden", + value: Map.get(@selected, :id, nil) + %> + + <%= if Enum.any?(@opponents) do %> + + <% end %> +
    +
    diff --git a/lib/chess_web/views/live/opponent_finder_live.ex b/lib/chess_web/views/live/opponent_finder_live.ex new file mode 100644 index 0000000..7d866b9 --- /dev/null +++ b/lib/chess_web/views/live/opponent_finder_live.ex @@ -0,0 +1,51 @@ +defmodule ChessWeb.OpponentFinderLive do + use Phoenix.LiveView + + alias Chess.Store.User + alias Chess.Repo + alias Chess.Repo.Queries + + alias ChessWeb.GameView + + def render(assigns) do + Phoenix.View.render(GameView, "opponent_finder.html", assigns) + end + + def mount(_params, %{"user_id" => user_id}, socket) do + ChessWeb.Endpoint.subscribe("opponent_finder:#{user_id}") + + user = Repo.get!(User, user_id) + + {:ok, assign(socket, default_assigns(user))} + end + + def handle_event("search", %{"q" => q}, socket) do + opponents = + case q do + "" -> + [] + + query_string -> + socket.assigns.user + |> Queries.opponents(query_string) + |> Repo.all() + end + + {:noreply, assign(socket, %{opponents: opponents})} + end + + def handle_event("select", %{"id" => id}, socket) do + opponent = Repo.get!(User, id) + + {:noreply, assign(socket, %{q: "", opponents: [], selected: opponent})} + end + + def default_assigns(user) do + %{ + q: "", + user: user, + opponents: [], + selected: %{} + } + end +end From d03b82ecfa45ed07630c0a7434ca0454446cffcb Mon Sep 17 00:00:00 2001 From: Dan Barber Date: Wed, 8 Nov 2023 17:17:38 -0600 Subject: [PATCH 20/24] Implement presence and fix email test --- assets/js/app.js | 2 +- lib/chess/board.ex | 2 +- lib/chess/emails.ex | 4 +- lib/chess_web/channels/presence.ex | 69 ------------------- .../templates/game/game_info.html.leex | 6 +- lib/chess_web/views/game_view.ex | 9 +++ lib/chess_web/views/live/board_live.ex | 43 +++++++++--- lib/chess_web/views/live/game_info_live.ex | 35 +++++++++- test/chess/board_test.exs | 6 +- 9 files changed, 89 insertions(+), 87 deletions(-) diff --git a/assets/js/app.js b/assets/js/app.js index 2f2961d..ab4e73d 100644 --- a/assets/js/app.js +++ b/assets/js/app.js @@ -17,6 +17,6 @@ const liveSocket = new LiveSocket( liveSocket.connect(); -liveSocket.enableDebug(); +// liveSocket.enableDebug(); window.liveSocket = liveSocket; diff --git a/lib/chess/board.ex b/lib/chess/board.ex index 63f18fd..eb82753 100644 --- a/lib/chess/board.ex +++ b/lib/chess/board.ex @@ -65,7 +65,7 @@ defmodule Chess.Board do }) end - def castling_move(board, %{"from" => [4, rank], "to" => [6, _rank]}) do + def castling_move(board, %{from: {4, rank}, to: {6, _rank}}) do move_piece(board, %{ from: {7, rank}, to: {5, rank} diff --git a/lib/chess/emails.ex b/lib/chess/emails.ex index eb46189..ec1df82 100644 --- a/lib/chess/emails.ex +++ b/lib/chess/emails.ex @@ -19,8 +19,8 @@ defmodule Chess.Emails do end def opponent_moved_email(socket, game) do - user = Repo.get(User, socket.assigns.user_id) - opponent = opponent(game, socket.assigns.user_id) + user = Repo.get(User, socket.assigns.user.id) + opponent = opponent(game, socket.assigns.user.id) new_email() |> to(opponent) diff --git a/lib/chess_web/channels/presence.ex b/lib/chess_web/channels/presence.ex index 3dbab22..7af26a2 100644 --- a/lib/chess_web/channels/presence.ex +++ b/lib/chess_web/channels/presence.ex @@ -1,73 +1,4 @@ defmodule ChessWeb.Presence do - @moduledoc """ - Provides presence tracking to channels and processes. - - See the [`Phoenix.Presence`](http://hexdocs.pm/phoenix/Phoenix.Presence.html) - docs for more details. - - ## Usage - - Presences can be tracked in your channel after joining: - - defmodule Chess.MyChannel do - use ChessWeb, :channel - alias Chess.Presence - - def join("some:topic", _params, socket) do - send(self, :after_join) - {:ok, assign(socket, :user_id, ...)} - end - - def handle_info(:after_join, socket) do - push socket, "presence_state", Presence.list(socket) - {:ok, _} = Presence.track(socket, socket.assigns.user_id, %{ - online_at: inspect(System.system_time(:second)) - }) - {:noreply, socket} - end - end - - In the example above, `Presence.track` is used to register this - channel's process as a presence for the socket's user ID, with - a map of metadata. Next, the current presence list for - the socket's topic is pushed to the client as a `"presence_state"` event. - - Finally, a diff of presence join and leave events will be sent to the - client as they happen in real-time with the "presence_diff" event. - See `Phoenix.Presence.list/2` for details on the presence datastructure. - - ## Fetching Presence Information - - The `fetch/2` callback is triggered when using `list/1` - and serves as a mechanism to fetch presence information a single time, - before broadcasting the information to all channel subscribers. - This prevents N query problems and gives you a single place to group - isolated data fetching to extend presence metadata. - - The function receives a topic and map of presences and must return a - map of data matching the Presence datastructure: - - %{"123" => %{metas: [%{status: "away", phx_ref: ...}], - "456" => %{metas: [%{status: "online", phx_ref: ...}]} - - The `:metas` key must be kept, but you can extend the map of information - to include any additional information. For example: - - def fetch(_topic, entries) do - users = entries |> Map.keys() |> Accounts.get_users_map(entries) - # => %{"123" => %{name: "User 123"}, "456" => %{name: nil}} - - for {key, %{metas: metas}} <- entries, into: %{} do - {key, %{metas: metas, user: users[key]}} - end - end - - The function above fetches all users from the database who - have registered presences for the given topic. The fetched - information is then extended with a `:user` key of the user's - information, while maintaining the required `:metas` field from the - original presence data. - """ use Phoenix.Presence, otp_app: :chess, pubsub_server: Chess.PubSub diff --git a/lib/chess_web/templates/game/game_info.html.leex b/lib/chess_web/templates/game/game_info.html.leex index 317cab7..2ed6916 100644 --- a/lib/chess_web/templates/game/game_info.html.leex +++ b/lib/chess_web/templates/game/game_info.html.leex @@ -1,7 +1,11 @@

    Playing <%= opponent(@game, @user.id).name %> - offline + <%= if Map.has_key?(@presence, opponent(@game, @user.id).id) do %> + online + <% else %> + offline + <% end %>

    diff --git a/lib/chess_web/views/game_view.ex b/lib/chess_web/views/game_view.ex index a76ecc7..31da762 100644 --- a/lib/chess_web/views/game_view.ex +++ b/lib/chess_web/views/game_view.ex @@ -2,6 +2,7 @@ defmodule ChessWeb.GameView do use ChessWeb, :view alias Chess.GameState + alias Chess.Repo import Phoenix.Component import Chess.Auth, only: [current_user: 1] @@ -88,6 +89,14 @@ defmodule ChessWeb.GameView do end end + def opponent_id(game, user_id) do + if game.user_id == user_id do + game.opponent_id + else + game.user_id + end + end + def opponent(game, user_id) do if game.user_id == user_id do game.opponent diff --git a/lib/chess_web/views/live/board_live.ex b/lib/chess_web/views/live/board_live.ex index ac062fb..f6943ef 100644 --- a/lib/chess_web/views/live/board_live.ex +++ b/lib/chess_web/views/live/board_live.ex @@ -1,6 +1,8 @@ defmodule ChessWeb.BoardLive do use Phoenix.LiveView, container: {:div, class: "board__container"} + alias Chess.Emails + alias Chess.Mailer alias Chess.Store.User alias Chess.Store.Game alias Chess.Store.Move @@ -8,6 +10,7 @@ defmodule ChessWeb.BoardLive do alias Chess.Moves alias ChessWeb.GameView + alias ChessWeb.Presence import Ecto.Query @@ -25,6 +28,7 @@ defmodule ChessWeb.BoardLive do game = Game.for_user(user) |> Repo.get!(game_id) + |> Repo.preload([:user, :opponent]) {:ok, assign(socket, default_assigns(game, user))} end @@ -51,10 +55,14 @@ defmodule ChessWeb.BoardLive do {:noreply, assign(socket, state)} end + def handle_info(%{event: "presence_diff", payload: _params}, socket) do + {:noreply, socket} + end + defp handle_click(socket, file, rank) do - game = socket.assigns[:game] + game = socket.assigns.game board = game.board - user = socket.assigns[:user] + user = socket.assigns.user colour = GameView.player_colour(user, game) @@ -65,7 +73,7 @@ defmodule ChessWeb.BoardLive do handle_selection(board, colour, file, rank) _ -> - handle_move(socket.assigns, file, rank) + handle_move(socket, file, rank) end end @@ -85,17 +93,16 @@ defmodule ChessWeb.BoardLive do end end - defp handle_move( - %{game: game, available: available, selected: selected}, - file, - rank - ) do + defp handle_move(socket, file, rank) do + %{game: game, available: available, selected: selected} = socket.assigns + if {file, rank} in available do game |> Moves.make_move(%{from: selected, to: {file, rank}}) |> case do {:ok, %{game: game}} -> game + |> Repo.reload() |> Repo.preload([:user, :opponent]) |> Repo.preload( moves: @@ -106,6 +113,8 @@ defmodule ChessWeb.BoardLive do ) |> broadcast_move(game.board) + email_move(socket, game) + [ {:selected, nil}, {:available, []}, @@ -118,6 +127,24 @@ defmodule ChessWeb.BoardLive do end end + defp email_move(socket, game) do + opponent_id = + GameView.opponent_id(game, socket.assigns.user.id) + |> Integer.to_string() + + "game:#{game.id}" + |> Presence.list() + |> case do + %{^opponent_id => _} -> + nil + + _ -> + socket + |> Emails.opponent_moved_email(game) + |> Mailer.deliver_later() + end + end + defp broadcast_move(game, board) do ChessWeb.Endpoint.broadcast_from( self(), diff --git a/lib/chess_web/views/live/game_info_live.ex b/lib/chess_web/views/live/game_info_live.ex index 63e873e..1d5eb04 100644 --- a/lib/chess_web/views/live/game_info_live.ex +++ b/lib/chess_web/views/live/game_info_live.ex @@ -5,6 +5,7 @@ defmodule ChessWeb.GameInfoLive do alias Chess.Store.Game alias Chess.Store.Move alias Chess.Repo + alias ChessWeb.Presence import Ecto.Query @@ -15,7 +16,9 @@ defmodule ChessWeb.GameInfoLive do end def mount(_params, %{"game_id" => game_id, "user_id" => user_id}, socket) do - ChessWeb.Endpoint.subscribe("game:#{game_id}") + topic = "game:#{game_id}" + + ChessWeb.Endpoint.subscribe(topic) user = Repo.get!(User, user_id) @@ -32,10 +35,38 @@ defmodule ChessWeb.GameInfoLive do ) |> Repo.get!(game_id) - {:ok, assign(socket, game: game, user: user)} + Presence.track(self(), topic, :user, %{id: user_id}) + + {:ok, assign(socket, game: game, user: user, presence: presence_list(topic))} end def handle_info(%{event: "move", payload: state}, socket) do {:noreply, assign(socket, state)} end + + def handle_info( + %{event: "presence_diff", payload: %{joins: joins, leaves: leaves}}, + socket + ) do + {:noreply, socket |> handle_joins(joins) |> handle_leaves(leaves)} + end + + defp presence_list(topic) do + Presence.list(topic) + |> Map.get("user") + |> Map.get(:metas) + |> Map.new(fn meta -> {meta.id, meta} end) + end + + defp handle_joins(socket, joins) do + Enum.reduce(joins, socket, fn {"user", %{metas: [meta | _]}}, socket -> + assign(socket, :presence, Map.put(socket.assigns.presence, meta.id, meta)) + end) + end + + defp handle_leaves(socket, leaves) do + Enum.reduce(leaves, socket, fn {"user", %{metas: [meta | _]}}, socket -> + assign(socket, :presence, Map.delete(socket.assigns.presence, meta.id)) + end) + end end diff --git a/test/chess/board_test.exs b/test/chess/board_test.exs index d626d82..c2ec727 100644 --- a/test/chess/board_test.exs +++ b/test/chess/board_test.exs @@ -72,7 +72,7 @@ defmodule Chess.BoardTest do "3,0" => %{"type" => "queen", "colour" => "white"} } - %{board: new_board} = Board.move_piece(board, %{"from" => [3, 0], "to" => [5, 2]}) + %{board: new_board} = Board.move_piece(board, %{from: {3, 0}, to: {5, 2}}) assert new_board == %{ "5,2" => %{"type" => "queen", "colour" => "white"} @@ -85,7 +85,7 @@ defmodule Chess.BoardTest do "7,0" => %{"type" => "rook", "colour" => "white"} } - %{board: new_board} = Board.move_piece(board, %{"from" => [4, 0], "to" => [6, 0]}) + %{board: new_board} = Board.move_piece(board, %{from: {4, 0}, to: {6, 0}}) assert new_board == %{ "6,0" => %{"type" => "king", "colour" => "white"}, @@ -99,7 +99,7 @@ defmodule Chess.BoardTest do "0,0" => %{"type" => "rook", "colour" => "white"} } - %{board: new_board} = Board.move_piece(board, %{"from" => [4, 0], "to" => [2, 0]}) + %{board: new_board} = Board.move_piece(board, %{from: {4, 0}, to: {2, 0}}) assert new_board == %{ "2,0" => %{"type" => "king", "colour" => "white"}, From 43d59cc24f64c12ac1db82a7a904fa2ef032e9a5 Mon Sep 17 00:00:00 2001 From: Dan Barber Date: Thu, 9 Nov 2023 16:38:23 -0600 Subject: [PATCH 21/24] Fix CSS --- assets/css/components/_square.scss | 26 +++++++++++++++++++++++++- config/dev.exs | 16 +++++----------- mix.exs | 2 +- 3 files changed, 31 insertions(+), 13 deletions(-) diff --git a/assets/css/components/_square.scss b/assets/css/components/_square.scss index 52c3d53..900a1d3 100644 --- a/assets/css/components/_square.scss +++ b/assets/css/components/_square.scss @@ -64,6 +64,30 @@ min-height: 20px; min-width: 20px; + @include odd-between(1, 8) { @extend %square--white; } + @include even-between(1, 8) { @extend %square--black; } + + @include odd-between(9, 16) { @extend %square--black; } + @include even-between(9, 16) { @extend %square--white; } + + @include odd-between(17, 24) { @extend %square--white; } + @include even-between(17, 24) { @extend %square--black; } + + @include odd-between(25, 32) { @extend %square--black; } + @include even-between(25, 32) { @extend %square--white; } + + @include odd-between(33, 40) { @extend %square--white; } + @include even-between(33, 40) { @extend %square--black; } + + @include odd-between(41, 48) { @extend %square--black; } + @include even-between(41, 48) { @extend %square--white; } + + @include odd-between(49, 56) { @extend %square--white; } + @include even-between(49, 56) { @extend %square--black; } + + @include odd-between(57, 64) { @extend %square--black; } + @include even-between(57, 64) { @extend %square--white; } + &::before { background-position: center; background-repeat: no-repeat; @@ -80,7 +104,7 @@ @each $colour in $colours { @each $piece in $pieces { &.square--#{$colour}.square--#{$piece}::before { - background-image: url("../static/images/#{$piece}_#{$colour}.svg"); + background-image: url("/images/#{$piece}_#{$colour}.svg"); } } } diff --git a/config/dev.exs b/config/dev.exs index 1a19f65..65264b9 100644 --- a/config/dev.exs +++ b/config/dev.exs @@ -1,21 +1,18 @@ import Config -# For development, we disable any cache and enable -# debugging and code reloading. -# -# The watchers configuration can be used to run external -# watchers to your application. For example, we use it -# with brunch.io to recompile .js and .css sources. config :chess, ChessWeb.Endpoint, http: [port: 4000], debug_errors: true, code_reloader: true, check_origin: false, watchers: [ - esbuild: {Esbuild, :install_and_run, [:default, ~w(--sourcemap=inline --watch)]} + esbuild: {Esbuild, :install_and_run, [:default, ~w(--sourcemap=inline + --watch)]}, + sass: + {DartSass, :install_and_run, + [:default, ~w(--embed-source-map --source-map-urls=absolute --watch)]} ] -# Watch static and templates for browser reloading. config :chess, ChessWeb.Endpoint, live_reload: [ patterns: [ @@ -26,11 +23,8 @@ config :chess, ChessWeb.Endpoint, ] ] -# Do not include metadata nor timestamps in development logs config :logger, :console, format: "[$level] $message\n" -# Set a higher stacktrace during development. Avoid configuring such -# in production as building large stacktraces may be expensive. config :phoenix, :stacktrace_depth, 20 config :chess, Chess.Mailer, adapter: Bamboo.LocalAdapter diff --git a/mix.exs b/mix.exs index 98b06cc..4b628be 100644 --- a/mix.exs +++ b/mix.exs @@ -39,7 +39,7 @@ defmodule Chess.Mixfile do {:comeonin, "~> 5.0"}, {:cowboy, "~> 2.0"}, {:credo, "~> 1.0", only: [:dev, :test]}, - {:dart_sass, "~> 0.5", runtime: Mix.env() == :dev}, + {:dart_sass, "~> 0.7", runtime: Mix.env() == :dev}, {:ecto_sql, "~> 3.0"}, {:floki, "~> 0.34", only: :test}, {:esbuild, "~> 0.7", runtime: Mix.env() == :dev}, From 278025b0989d3eff3966e55d8758d8b81c8abe45 Mon Sep 17 00:00:00 2001 From: Dan Barber Date: Tue, 21 Nov 2023 13:15:06 -0600 Subject: [PATCH 22/24] Address genserver failures in tests --- lib/chess_web/views/live/board_live.ex | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/chess_web/views/live/board_live.ex b/lib/chess_web/views/live/board_live.ex index f6943ef..33867b5 100644 --- a/lib/chess_web/views/live/board_live.ex +++ b/lib/chess_web/views/live/board_live.ex @@ -75,6 +75,8 @@ defmodule ChessWeb.BoardLive do _ -> handle_move(socket, file, rank) end + else + [] end assign(socket, assigns) @@ -121,6 +123,9 @@ defmodule ChessWeb.BoardLive do {:board, game.board}, {:game, game} ] + + {:error, _, _, _} -> + [] end else [{:selected, nil}, {:available, []}] From 8026e8ccec4ebeff30076f6d7a4809eb961f3cda Mon Sep 17 00:00:00 2001 From: Dan Barber Date: Tue, 21 Nov 2023 13:15:17 -0600 Subject: [PATCH 23/24] We don't need JSX anymore --- config/config.exs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/config.exs b/config/config.exs index cc9aaad..3b97c59 100644 --- a/config/config.exs +++ b/config/config.exs @@ -39,7 +39,7 @@ config :esbuild, version: "0.19.4", default: [ args: - ~w(js/app.js --bundle --target=es2017 --outdir=../priv/static/js --external:/fonts/* --external:/images/* --loader:.js=jsx), + ~w(js/app.js --bundle --target=es2017 --outdir=../priv/static/js --external:/fonts/* --external:/images/*), cd: Path.expand("../assets", __DIR__), env: %{"NODE_PATH" => Path.expand("../deps", __DIR__)} ] From 72e3d5ea65c4d73b945138aba9389050a616e831 Mon Sep 17 00:00:00 2001 From: Dan Barber Date: Tue, 21 Nov 2023 13:15:27 -0600 Subject: [PATCH 24/24] Add server script --- bin/server | 3 +++ 1 file changed, 3 insertions(+) create mode 100755 bin/server diff --git a/bin/server b/bin/server new file mode 100755 index 0000000..f2f92e4 --- /dev/null +++ b/bin/server @@ -0,0 +1,3 @@ +#!/bin/sh + +mix phx.server