From 0780d2ad9a00e80b6da5ccccae1eabcc2ef9995f Mon Sep 17 00:00:00 2001 From: Gareth Latty Date: Sun, 26 Apr 2020 13:36:51 +0100 Subject: [PATCH] Resolve #101: Blank cards focus properly. --- client/package-lock.json | 84 ++++++++-- client/package.json | 2 +- client/src/elm/MassiveDecks/Card.elm | 32 ++-- client/src/elm/MassiveDecks/Card/Call.elm | 6 +- client/src/elm/MassiveDecks/Card/Response.elm | 15 +- client/src/elm/MassiveDecks/Game.elm | 9 +- .../elm/MassiveDecks/Game/Round/Playing.elm | 14 +- .../elm/MassiveDecks/Game/Round/Revealing.elm | 2 +- .../Pages/Lobby/Spectate/Stages/Round.elm | 16 +- client/src/elm/MassiveDecks/Pages/Start.elm | 2 +- package-lock.json | 154 ++++++++++++------ 11 files changed, 226 insertions(+), 110 deletions(-) diff --git a/client/package-lock.json b/client/package-lock.json index e1eae14..42e0820 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -5559,9 +5559,9 @@ "dev": true }, "jest-worker": { - "version": "25.2.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-25.2.1.tgz", - "integrity": "sha512-IHnpekk8H/hCUbBlfeaPZzU6v75bqwJp3n4dUrQuQOAgOneI4tx3jV2o8pvlXnDfcRsfkFIUD//HWXpCmR+evQ==", + "version": "25.4.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-25.4.0.tgz", + "integrity": "sha512-ghAs/1FtfYpMmYQ0AHqxV62XPvKdUDIBBApMZfly+E9JEmYh2K45G0R5dWxx986RN12pRCxsViwQVtGl+N4whw==", "dev": true, "requires": { "merge-stream": "^2.0.0", @@ -9992,20 +9992,80 @@ } }, "terser-webpack-plugin": { - "version": "2.3.5", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-2.3.5.tgz", - "integrity": "sha512-WlWksUoq+E4+JlJ+h+U+QUzXpcsMSSNXkDy9lBVkSqDn1w23Gg29L/ary9GeJVYCGiNJJX7LnVc4bwL1N3/g1w==", + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-2.3.6.tgz", + "integrity": "sha512-I8IDsQwZrqjdmOicNeE8L/MhwatAap3mUrtcAKJuilsemUNcX+Hier/eAzwStVqhlCxq0aG3ni9bK/0BESXkTg==", "dev": true, "requires": { "cacache": "^13.0.1", - "find-cache-dir": "^3.2.0", - "jest-worker": "^25.1.0", - "p-limit": "^2.2.2", - "schema-utils": "^2.6.4", - "serialize-javascript": "^2.1.2", + "find-cache-dir": "^3.3.1", + "jest-worker": "^25.4.0", + "p-limit": "^2.3.0", + "schema-utils": "^2.6.6", + "serialize-javascript": "^3.0.0", "source-map": "^0.6.1", - "terser": "^4.4.3", + "terser": "^4.6.12", "webpack-sources": "^1.4.3" + }, + "dependencies": { + "ajv": { + "version": "6.12.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.2.tgz", + "integrity": "sha512-k+V+hzjm5q/Mr8ef/1Y9goCmlsK4I6Sm74teeyGvFk1XrOsbsKLjEdrvny42CZ+a8sXbk8KWpY/bDwS+FLL2UQ==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "schema-utils": { + "version": "2.6.6", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.6.6.tgz", + "integrity": "sha512-wHutF/WPSbIi9x6ctjGGk2Hvl0VOz5l3EKEuKbjPlB30mKZUzb9A5k9yEXRX3pwyqVLPvpfZZEllaFq/M718hA==", + "dev": true, + "requires": { + "ajv": "^6.12.0", + "ajv-keywords": "^3.4.1" + } + }, + "serialize-javascript": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-3.0.0.tgz", + "integrity": "sha512-skZcHYw2vEX4bw90nAr2iTTsz6x2SrHEnfxgKYmZlvJYBEZrvbKtobJWlQ20zczKb3bsHHXXTYt48zBA7ni9cw==", + "dev": true + }, + "source-map-support": { + "version": "0.5.19", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", + "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "terser": { + "version": "4.6.12", + "resolved": "https://registry.npmjs.org/terser/-/terser-4.6.12.tgz", + "integrity": "sha512-fnIwuaKjFPANG6MAixC/k1TDtnl1YlPLUlLVIxxGZUn1gfUx2+l3/zGNB72wya+lgsb50QBi2tUV75RiODwnww==", + "dev": true, + "requires": { + "commander": "^2.20.0", + "source-map": "~0.6.1", + "source-map-support": "~0.5.12" + } + } } }, "through2": { diff --git a/client/package.json b/client/package.json index 961c524..bbaa878 100644 --- a/client/package.json +++ b/client/package.json @@ -53,7 +53,7 @@ "sass-inline-svg": "^1.2.3", "sass-loader": "^8.0.2", "style-loader": "^1.2.0", - "terser-webpack-plugin": "^2.3.5", + "terser-webpack-plugin": "^2.3.6", "ts-loader": "^7.0.1", "typescript": "^3.8.3", "uglifyjs-webpack-plugin": "^2.2.0", diff --git a/client/src/elm/MassiveDecks/Card.elm b/client/src/elm/MassiveDecks/Card.elm index 021f611..3f4905e 100644 --- a/client/src/elm/MassiveDecks/Card.elm +++ b/client/src/elm/MassiveDecks/Card.elm @@ -2,7 +2,6 @@ module MassiveDecks.Card exposing ( asResponse , asResponseFromDict , details - , frontSide , view , viewUnknown ) @@ -15,6 +14,8 @@ import MassiveDecks.Card.Source as Source import MassiveDecks.Card.Source.Model as Source exposing (Source) import MassiveDecks.Model exposing (Shared) import MassiveDecks.Pages.Lobby.Configure.Decks.Model as Configure +import MassiveDecks.Strings as Strings +import MassiveDecks.Strings.Languages as Lang import MassiveDecks.Util.Html as Html import MassiveDecks.Util.Maybe as Maybe @@ -40,15 +41,15 @@ view cardTypeClass shared getSummary visibleSide attributes viewBody viewInstruc ] :: attributes ) - [ Html.div [ HtmlA.class "aspect" ] [ front shared getSummary viewBody viewInstructions source, back ] ] + [ Html.div [ HtmlA.class "aspect" ] [ front shared getSummary viewBody viewInstructions source, back shared ] ] {-| Render an unknown card to HTML, face-down. -} -viewUnknown : String -> List (Html.Attribute msg) -> Html msg -viewUnknown cardTypeClass attributes = +viewUnknown : Shared -> String -> List (Html.Attribute msg) -> Html msg +viewUnknown shared cardTypeClass attributes = Html.div (HtmlA.class "game-card face-down" :: (HtmlA.class cardTypeClass :: attributes)) - [ Html.div [ HtmlA.class "aspect" ] [ back ] ] + [ Html.div [ HtmlA.class "aspect" ] [ back shared ] ] {-| Fill a blank response into a normal one from a dictionary, falling back to nothing if the card id isn't in it. @@ -84,17 +85,6 @@ details potentiallyBlankResponse = b.details -{-| Get a side from a boolean test. --} -frontSide : Bool -> Side -frontSide isFront = - if isFront then - Front - - else - Back - - {- Private -} @@ -104,11 +94,15 @@ cardSide side content = Html.div [ HtmlA.classList [ ( "side", True ), ( "front", side == Front ), ( "back", side == Back ) ] ] content -back : Html msg -back = +back : Shared -> Html msg +back shared = + let + renderWord word = + Html.p [] [ Html.span [] [ Html.text word ] ] + in cardSide Back [ Html.div [ HtmlA.class "content" ] - [ Html.p [] [ Html.span [] [ Html.text "Massive" ] ], Html.p [] [ Html.span [] [ Html.text "Decks" ] ] ] + (Strings.MassiveDecks |> Lang.string shared |> String.words |> List.map renderWord) ] diff --git a/client/src/elm/MassiveDecks/Card/Call.elm b/client/src/elm/MassiveDecks/Card/Call.elm index aeb1e59..5916a8e 100644 --- a/client/src/elm/MassiveDecks/Card/Call.elm +++ b/client/src/elm/MassiveDecks/Card/Call.elm @@ -37,9 +37,9 @@ viewFilled shared config side attributes fillWith call = {-| Render an unknown response to HTML, face-down. -} -viewUnknown : List (Html.Attribute msg) -> Html msg -viewUnknown attributes = - Card.viewUnknown "call" attributes +viewUnknown : Shared -> List (Html.Attribute msg) -> Html msg +viewUnknown shared attributes = + Card.viewUnknown shared "call" attributes diff --git a/client/src/elm/MassiveDecks/Card/Response.elm b/client/src/elm/MassiveDecks/Card/Response.elm index db8fc46..60ad50a 100644 --- a/client/src/elm/MassiveDecks/Card/Response.elm +++ b/client/src/elm/MassiveDecks/Card/Response.elm @@ -34,9 +34,9 @@ view shared config side attributes response = {-| Render an unknown response to HTML, face-down. -} -viewUnknown : List (Html.Attribute msg) -> Html msg -viewUnknown attributes = - Card.viewUnknown "response" attributes +viewUnknown : Shared -> List (Html.Attribute msg) -> Html msg +viewUnknown shared attributes = + Card.viewUnknown shared "response" attributes {-| Render a potentially blank card to HTML. @@ -61,7 +61,7 @@ viewBlank shared config side update attributes response fill = (config.decks |> Decks.getSummary) side attributes - (viewBlankBody update fill) + (viewBlankBody response.details.id update fill) viewInstructions response.details.source @@ -75,12 +75,13 @@ viewBody response = ViewBody (\() -> [ Html.p [] [ Html.span [] [ response.body |> String.capitalise |> Html.text ] ] ]) -viewBlankBody : (String -> msg) -> Maybe String -> ViewBody msg -viewBlankBody update value = +viewBlankBody : String -> (String -> msg) -> Maybe String -> ViewBody msg +viewBlankBody id update value = ViewBody (\() -> [ Html.textarea - [ value |> Maybe.withDefault "" |> HtmlA.value + [ HtmlA.id id + , value |> Maybe.withDefault "" |> HtmlA.value , update |> HtmlE.onInput ] [] diff --git a/client/src/elm/MassiveDecks/Game.elm b/client/src/elm/MassiveDecks/Game.elm index 9019dcc..d010aaa 100644 --- a/client/src/elm/MassiveDecks/Game.elm +++ b/client/src/elm/MassiveDecks/Game.elm @@ -103,8 +103,13 @@ update wrap shared msg model = newRound = Round.P { playingRound | pick = { picks | cards = picked |> List.drop extra } } + + focus = + Dom.focus played.id + |> Task.onError (\_ -> Task.succeed ()) + |> Task.perform (\_ -> wrap NoOp) in - ( { model | game = { game | round = newRound } }, Cmd.none ) + ( { model | game = { game | round = newRound } }, focus ) _ -> ( model, Cmd.none ) @@ -112,7 +117,7 @@ update wrap shared msg model = EditBlank id text -> case game.round of Round.P playingRound -> - if playingRound.pick.cards |> List.all (\p -> p.id /= id) then + if playingRound.pick.state /= Round.Submitted then ( { model | filledCards = model.filledCards |> Dict.insert id text }, Cmd.none ) else diff --git a/client/src/elm/MassiveDecks/Game/Round/Playing.elm b/client/src/elm/MassiveDecks/Game/Round/Playing.elm index 177a868..c4d0670 100644 --- a/client/src/elm/MassiveDecks/Game/Round/Playing.elm +++ b/client/src/elm/MassiveDecks/Game/Round/Playing.elm @@ -79,7 +79,7 @@ view wrap auth shared config users model round = backgroundPlays = Html.div [ HtmlA.class "background-plays" ] - (round.players |> Set.toList |> List.map (viewBackgroundPlay model.playStyles slots round.played)) + (round.players |> Set.toList |> List.map (viewBackgroundPlay shared model.playStyles slots round.played)) picked = round.pick.cards @@ -130,24 +130,24 @@ viewHandCard wrap shared config filled picked response = ) -viewBackgroundPlay : PlayStyles -> Int -> Set User.Id -> User.Id -> Html msg -viewBackgroundPlay playStyles slots played for = +viewBackgroundPlay : Shared -> PlayStyles -> Int -> Set User.Id -> User.Id -> Html msg +viewBackgroundPlay shared playStyles slots played for = let -- TODO: Move to css variable --rotation when possible. cards = playStyles |> Dict.get for |> Maybe.withDefault (List.repeat slots { rotation = 0 }) - |> List.map viewBackgroundPlayCard + |> List.map (viewBackgroundPlayCard shared) in Html.div [ HtmlA.classList [ ( "play", True ), ( "played", Set.member for played ) ] ] cards -viewBackgroundPlayCard : CardStyle -> Html msg -viewBackgroundPlayCard playStyle = - Response.viewUnknown +viewBackgroundPlayCard : Shared -> CardStyle -> Html msg +viewBackgroundPlayCard shared playStyle = + Response.viewUnknown shared [ "rotate(" ++ String.fromFloat playStyle.rotation ++ "turn)" |> HtmlA.style "transform" , HtmlA.class "ignore-minimal-card-size" ] diff --git a/client/src/elm/MassiveDecks/Game/Round/Revealing.elm b/client/src/elm/MassiveDecks/Game/Round/Revealing.elm index 0246082..36be6cd 100644 --- a/client/src/elm/MassiveDecks/Game/Round/Revealing.elm +++ b/client/src/elm/MassiveDecks/Game/Round/Revealing.elm @@ -61,6 +61,6 @@ playDetails wrap shared config slots isCzar { id, responses } = cards = responses |> Maybe.map (List.map (\r -> Response.view shared config Card.Front [] r)) - |> Maybe.withDefault (List.repeat slots (Response.viewUnknown [])) + |> Maybe.withDefault (List.repeat slots (Response.viewUnknown shared [])) in Plays.Details id cards (Reveal id |> wrap |> Maybe.justIf isCzar) [] diff --git a/client/src/elm/MassiveDecks/Pages/Lobby/Spectate/Stages/Round.elm b/client/src/elm/MassiveDecks/Pages/Lobby/Spectate/Stages/Round.elm index e75489f..b4fa003 100644 --- a/client/src/elm/MassiveDecks/Pages/Lobby/Spectate/Stages/Round.elm +++ b/client/src/elm/MassiveDecks/Pages/Lobby/Spectate/Stages/Round.elm @@ -48,7 +48,7 @@ viewPlaying shared config playStyles round = round.call |> Call.slotCount in [ viewCall shared config Nothing round.call - , viewUnknownPlays slots playStyles round.players round.played + , viewUnknownPlays shared slots playStyles round.players round.played ] @@ -103,8 +103,8 @@ viewCall shared config fillWith call = ] -viewUnknownPlays : Int -> Game.PlayStyles -> Set User.Id -> Set User.Id -> Html msg -viewUnknownPlays slotCount playStyles players played = +viewUnknownPlays : Shared -> Int -> Game.PlayStyles -> Set User.Id -> Set User.Id -> Html msg +viewUnknownPlays shared slotCount playStyles players played = let angle = players |> Set.size |> anglePerPlay @@ -115,7 +115,7 @@ viewUnknownPlays slotCount playStyles players played = Html.ul [ HtmlA.id "plays" ] (players |> Set.toList - |> List.indexedMap (\i -> \u -> viewUnknownPlay (toFloat i * angle) (getPlayStyle u) (Set.member u played)) + |> List.indexedMap (\i -> \u -> viewUnknownPlay shared (toFloat i * angle) (getPlayStyle u) (Set.member u played)) ) @@ -174,14 +174,14 @@ viewPlay shared config slotCount angle playedBy isWinner play = ] (play |> Maybe.map (.play >> List.map (\response -> Html.li [] [ Response.view shared config Card.Front [] response ])) - |> Maybe.withDefault (List.repeat slotCount (Html.li [] [ Response.viewUnknown [] ])) + |> Maybe.withDefault (List.repeat slotCount (Html.li [] [ Response.viewUnknown shared [] ])) ) ] ] -viewUnknownPlay : Float -> Game.PlayStyle -> Bool -> Html msg -viewUnknownPlay angle playStyle played = +viewUnknownPlay : Shared -> Float -> Game.PlayStyle -> Bool -> Html msg +viewUnknownPlay shared angle playStyle played = let distance = if played then @@ -197,7 +197,7 @@ viewUnknownPlay angle playStyle played = , Html.ol [ HtmlA.classList [ ( "play", True ), ( "card-set", True ) ] ] - (playStyle |> List.map (\cardStyle -> Html.li [] [ Response.viewUnknown [ rotated cardStyle.rotation ] ])) + (playStyle |> List.map (\cardStyle -> Html.li [] [ Response.viewUnknown shared [ rotated cardStyle.rotation ] ])) ] ] diff --git a/client/src/elm/MassiveDecks/Pages/Start.elm b/client/src/elm/MassiveDecks/Pages/Start.elm index d4655e1..99e9e9f 100644 --- a/client/src/elm/MassiveDecks/Pages/Start.elm +++ b/client/src/elm/MassiveDecks/Pages/Start.elm @@ -191,7 +191,7 @@ view shared model = [ Html.div [ HtmlA.class "page start" ] [ overlay shared model.overlay , Html.header [ HtmlA.class "title-card" ] - [ Html.h1 [] [ Html.div [ HtmlA.class "card-slicer" ] [ Call.viewUnknown [] ] ] + [ Html.h1 [] [ Html.div [ HtmlA.class "card-slicer" ] [ Call.viewUnknown shared [] ] ] , Html.div [ HtmlA.class "subtitle" ] [ Html.div [ HtmlA.class "card-slicer" ] [ Response.view shared Configure.fake Card.Front [] (subtitleCard shared) diff --git a/package-lock.json b/package-lock.json index 9b7d974..301b0b5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -41,18 +41,18 @@ "integrity": "sha512-/+CRPXpBDpo2RK9C68N3b2cOvO0Cf5B9aPijHsoDQTHivnGSObdOF2BRQOYjojWTDy6nQvMjmqRXIxH55VjxxA==" }, "@types/chrome": { - "version": "0.0.103", - "resolved": "https://registry.npmjs.org/@types/chrome/-/chrome-0.0.103.tgz", - "integrity": "sha512-s8So1IG1fIu2dg2MRV3k6W5OjlVaJriNXIxIWDHi+Rdz5dLeuzPKcWzkVlcaVL4gONfn44JKC0RhW+P0UohLfg==", + "version": "0.0.104", + "resolved": "https://registry.npmjs.org/@types/chrome/-/chrome-0.0.104.tgz", + "integrity": "sha512-NDq+Vpphs5XT7IXrIHJcy27Rvf09Mes3XNsfpP2yOXUk6YiEU1QRcSLjj/A+y5jyq/kpUwC5shNET2jFeWAqEw==", "requires": { "@types/filesystem": "*", "@types/har-format": "*" } }, "@types/chromecast-caf-receiver": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/@types/chromecast-caf-receiver/-/chromecast-caf-receiver-5.0.3.tgz", - "integrity": "sha512-Zl4HZEXvilgu6U79gj8JkYDibr7Pm4qOmm3uhYDZ8QjDnoH/opkBT922xPQtUu16PudOGcrzeB2qz62C1Hhb8g==" + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@types/chromecast-caf-receiver/-/chromecast-caf-receiver-5.0.4.tgz", + "integrity": "sha512-LlgMrB5k8Cx5uULMtRqZtV4sHefBRiYYMbENfplRahA0UIu2x525ez9gBJtVwPY4GrLRQIVlJidLduuiQcrmGA==" }, "@types/chromecast-caf-sender": { "version": "1.0.3", @@ -2244,22 +2244,23 @@ } }, "css-loader": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-3.4.2.tgz", - "integrity": "sha512-jYq4zdZT0oS0Iykt+fqnzVLRIeiPWhka+7BqPn+oSIpWJAHak5tmB/WZrJ2a21JhCeFyNnnlroSl8c+MtVndzA==", + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-3.5.3.tgz", + "integrity": "sha512-UEr9NH5Lmi7+dguAm+/JSPovNjYbm2k3TK58EiwQHzOHH5Jfq1Y+XoP2bQO6TMn7PptMd0opxxedAWcaSTRKHw==", "requires": { "camelcase": "^5.3.1", "cssesc": "^3.0.0", "icss-utils": "^4.1.1", "loader-utils": "^1.2.3", "normalize-path": "^3.0.0", - "postcss": "^7.0.23", + "postcss": "^7.0.27", "postcss-modules-extract-imports": "^2.0.0", "postcss-modules-local-by-default": "^3.0.2", - "postcss-modules-scope": "^2.1.1", + "postcss-modules-scope": "^2.2.0", "postcss-modules-values": "^3.0.0", - "postcss-value-parser": "^4.0.2", - "schema-utils": "^2.6.0" + "postcss-value-parser": "^4.0.3", + "schema-utils": "^2.6.6", + "semver": "^6.3.0" }, "dependencies": { "ajv": { @@ -3886,9 +3887,9 @@ } }, "html-webpack-plugin": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-4.0.4.tgz", - "integrity": "sha512-BREQzUbFfIQS39KqxkT2L1Ot0tuu1isako1CaCQLrgEQ43zi2ScHAe3SMTnVBWsStnIsGtl8jprDdxwZkNhrwQ==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-4.2.0.tgz", + "integrity": "sha512-zL7LYTuq/fcJX6vV6tmmvFR508Bd9e6kvVGbS76YAjZ2CPVRzsjkvDYs/SshPevpolSdTWgaDV39D6k6oQoVFw==", "requires": { "@types/html-minifier-terser": "^5.0.0", "@types/tapable": "^1.0.5", @@ -4468,9 +4469,9 @@ "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" }, "jest-worker": { - "version": "25.2.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-25.2.1.tgz", - "integrity": "sha512-IHnpekk8H/hCUbBlfeaPZzU6v75bqwJp3n4dUrQuQOAgOneI4tx3jV2o8pvlXnDfcRsfkFIUD//HWXpCmR+evQ==", + "version": "25.4.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-25.4.0.tgz", + "integrity": "sha512-ghAs/1FtfYpMmYQ0AHqxV62XPvKdUDIBBApMZfly+E9JEmYh2K45G0R5dWxx986RN12pRCxsViwQVtGl+N4whw==", "requires": { "merge-stream": "^2.0.0", "supports-color": "^7.0.0" @@ -5199,9 +5200,9 @@ "integrity": "sha512-wp8zyQVwef2hpZ/dJH7SfSrIPD6YoJz6BDQDpGEkcA0s3LpAQoxBIYmfIq6QAhC1DhwsyCgTaTTcONwX8qzCuQ==" }, "node-sass": { - "version": "4.13.1", - "resolved": "https://registry.npmjs.org/node-sass/-/node-sass-4.13.1.tgz", - "integrity": "sha512-TTWFx+ZhyDx1Biiez2nB0L3YrCZ/8oHagaDalbuBSlqXgUPsdkUSzJsVxeDO9LtPB49+Fh3WQl3slABo6AotNw==", + "version": "4.14.0", + "resolved": "https://registry.npmjs.org/node-sass/-/node-sass-4.14.0.tgz", + "integrity": "sha512-AxqU+DFpk0lEz95sI6jO0hU0Rwyw7BXVEv6o9OItoXLyeygPeaSpiV4rwQb10JiTghHaa0gZeD21sz+OsQluaw==", "requires": { "async-foreach": "^0.1.3", "chalk": "^1.1.1", @@ -6765,9 +6766,9 @@ "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=" }, "prettier": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.0.2.tgz", - "integrity": "sha512-5xJQIPT8BraI7ZnaDwSbu5zLrB6vvi8hVV58yHQ+QK64qrY40dULy0HSRlQ2/2IdzeBpjhDkqdcFBnFeDEMVdg==" + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.0.5.tgz", + "integrity": "sha512-7PtVymN48hGcO4fGjybyBSIWDsLU4H4XlvOHfq91pz9kkGlonzwTfYkaIEwiRg/dAJF9YlbsduBAgtYLi+8cFg==" }, "prettier-plugin-elm": { "version": "0.7.0", @@ -8263,11 +8264,12 @@ } }, "style-loader": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-1.1.3.tgz", - "integrity": "sha512-rlkH7X/22yuwFYK357fMN/BxYOorfnfq0eD7+vqlemSK4wEcejFF1dg4zxP0euBW8NrYx2WZzZ8PPFevr7D+Kw==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-1.2.0.tgz", + "integrity": "sha512-HC8WcGnjwNrKji7HSBqFOhGNUSt7UDU/jHxT6bA83Gk+JWJBmgitWlGihc0V1w6ZvwlzcX5LJOsofZzSP7b1tQ==", "requires": { - "schema-utils": "^2.6.4" + "loader-utils": "^2.0.0", + "schema-utils": "^2.6.6" }, "dependencies": { "ajv": { @@ -8420,19 +8422,73 @@ } }, "terser-webpack-plugin": { - "version": "2.3.5", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-2.3.5.tgz", - "integrity": "sha512-WlWksUoq+E4+JlJ+h+U+QUzXpcsMSSNXkDy9lBVkSqDn1w23Gg29L/ary9GeJVYCGiNJJX7LnVc4bwL1N3/g1w==", + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-2.3.6.tgz", + "integrity": "sha512-I8IDsQwZrqjdmOicNeE8L/MhwatAap3mUrtcAKJuilsemUNcX+Hier/eAzwStVqhlCxq0aG3ni9bK/0BESXkTg==", "requires": { "cacache": "^13.0.1", - "find-cache-dir": "^3.2.0", - "jest-worker": "^25.1.0", - "p-limit": "^2.2.2", - "schema-utils": "^2.6.4", - "serialize-javascript": "^2.1.2", + "find-cache-dir": "^3.3.1", + "jest-worker": "^25.4.0", + "p-limit": "^2.3.0", + "schema-utils": "^2.6.6", + "serialize-javascript": "^3.0.0", "source-map": "^0.6.1", - "terser": "^4.4.3", + "terser": "^4.6.12", "webpack-sources": "^1.4.3" + }, + "dependencies": { + "ajv": { + "version": "6.12.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.2.tgz", + "integrity": "sha512-k+V+hzjm5q/Mr8ef/1Y9goCmlsK4I6Sm74teeyGvFk1XrOsbsKLjEdrvny42CZ+a8sXbk8KWpY/bDwS+FLL2UQ==", + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "requires": { + "p-try": "^2.0.0" + } + }, + "schema-utils": { + "version": "2.6.6", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.6.6.tgz", + "integrity": "sha512-wHutF/WPSbIi9x6ctjGGk2Hvl0VOz5l3EKEuKbjPlB30mKZUzb9A5k9yEXRX3pwyqVLPvpfZZEllaFq/M718hA==", + "requires": { + "ajv": "^6.12.0", + "ajv-keywords": "^3.4.1" + } + }, + "serialize-javascript": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-3.0.0.tgz", + "integrity": "sha512-skZcHYw2vEX4bw90nAr2iTTsz6x2SrHEnfxgKYmZlvJYBEZrvbKtobJWlQ20zczKb3bsHHXXTYt48zBA7ni9cw==" + }, + "source-map-support": { + "version": "0.5.19", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", + "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "terser": { + "version": "4.6.12", + "resolved": "https://registry.npmjs.org/terser/-/terser-4.6.12.tgz", + "integrity": "sha512-fnIwuaKjFPANG6MAixC/k1TDtnl1YlPLUlLVIxxGZUn1gfUx2+l3/zGNB72wya+lgsb50QBi2tUV75RiODwnww==", + "requires": { + "commander": "^2.20.0", + "source-map": "~0.6.1", + "source-map-support": "~0.5.12" + } + } } }, "through2": { @@ -8548,9 +8604,9 @@ } }, "ts-loader": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-6.2.2.tgz", - "integrity": "sha512-HDo5kXZCBml3EUPcc7RlZOV/JGlLHwppTLEHb3SHnr5V7NXD4klMEkrhJe5wgRbaWsSXi+Y1SIBN/K9B6zWGWQ==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-7.0.1.tgz", + "integrity": "sha512-wdGs9xO8UnwASwbluehzXciBtc9HfGlYA8Aiv856etLmdv8mJfAxCkt3YpS4g7G1IsGxaCVKQ102Qh0zycpeZQ==", "requires": { "chalk": "^2.3.0", "enhanced-resolve": "^4.0.0", @@ -9040,15 +9096,15 @@ } }, "webpack": { - "version": "4.42.1", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.42.1.tgz", - "integrity": "sha512-SGfYMigqEfdGchGhFFJ9KyRpQKnipvEvjc1TwrXEPCM6H5Wywu10ka8o3KGrMzSMxMQKt8aCHUFh5DaQ9UmyRg==", + "version": "4.43.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.43.0.tgz", + "integrity": "sha512-GW1LjnPipFW2Y78OOab8NJlCflB7EFskMih2AHdvjbpKMeDJqEgSx24cXXXiPS65+WSwVyxtDsJH6jGX2czy+g==", "requires": { "@webassemblyjs/ast": "1.9.0", "@webassemblyjs/helper-module-context": "1.9.0", "@webassemblyjs/wasm-edit": "1.9.0", "@webassemblyjs/wasm-parser": "1.9.0", - "acorn": "^6.2.1", + "acorn": "^6.4.1", "ajv": "^6.10.2", "ajv-keywords": "^3.4.1", "chrome-trace-event": "^1.0.2", @@ -9065,14 +9121,14 @@ "schema-utils": "^1.0.0", "tapable": "^1.1.3", "terser-webpack-plugin": "^1.4.3", - "watchpack": "^1.6.0", + "watchpack": "^1.6.1", "webpack-sources": "^1.4.1" }, "dependencies": { "ajv": { - "version": "6.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.0.tgz", - "integrity": "sha512-D6gFiFA0RRLyUbvijN74DWAjXSFxWKaWP7mldxkVhyhAV3+SWA9HEJPHQ2c9soIeTFJqcSdFDGFgdqs1iUU2Hw==", + "version": "6.12.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.2.tgz", + "integrity": "sha512-k+V+hzjm5q/Mr8ef/1Y9goCmlsK4I6Sm74teeyGvFk1XrOsbsKLjEdrvny42CZ+a8sXbk8KWpY/bDwS+FLL2UQ==", "requires": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0",