├── examples
├── .gitignore
├── build.sh
├── elm.json
├── Configs.elm
└── Main.elm
├── .gitignore
├── elm.json
├── docs
├── index.html
└── index.js
├── LICENSE
├── README.md
└── src
├── Styles.elm
└── ContextMenu.elm
/examples/.gitignore:
--------------------------------------------------------------------------------
1 | elm-stuff
2 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | elm-stuff
2 | docs.json
3 |
--------------------------------------------------------------------------------
/examples/build.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | elm make Main.elm --output=../docs/index.js
--------------------------------------------------------------------------------
/elm.json:
--------------------------------------------------------------------------------
1 | {
2 | "type": "package",
3 | "name": "jinjor/elm-contextmenu",
4 | "summary": "Flexible context menu for Elm",
5 | "license": "BSD-3-Clause",
6 | "version": "2.0.0",
7 | "exposed-modules": [
8 | "ContextMenu"
9 | ],
10 | "elm-version": "0.19.0 <= v < 0.20.0",
11 | "dependencies": {
12 | "elm/browser": "1.0.0 <= v < 2.0.0",
13 | "elm/core": "1.0.0 <= v < 2.0.0",
14 | "elm/html": "1.0.0 <= v < 2.0.0",
15 | "elm/json": "1.0.0 <= v < 2.0.0"
16 | },
17 | "test-dependencies": {}
18 | }
--------------------------------------------------------------------------------
/docs/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Main
7 |
20 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/examples/elm.json:
--------------------------------------------------------------------------------
1 | {
2 | "type": "application",
3 | "source-directories": [
4 | ".",
5 | "../src"
6 | ],
7 | "elm-version": "0.19.0",
8 | "dependencies": {
9 | "direct": {
10 | "elm/browser": "1.0.0",
11 | "elm/core": "1.0.0",
12 | "elm/html": "1.0.0",
13 | "elm/json": "1.0.0",
14 | "elm/svg": "1.0.0"
15 | },
16 | "indirect": {
17 | "elm/time": "1.0.0",
18 | "elm/url": "1.0.0",
19 | "elm/virtual-dom": "1.0.0"
20 | }
21 | },
22 | "test-dependencies": {
23 | "direct": {},
24 | "indirect": {}
25 | }
26 | }
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | BSD 3-Clause License
2 |
3 | Copyright (c) 2016, Yosuke Torii
4 | All rights reserved.
5 |
6 | Redistribution and use in source and binary forms, with or without
7 | modification, are permitted provided that the following conditions are met:
8 |
9 | * Redistributions of source code must retain the above copyright notice, this
10 | list of conditions and the following disclaimer.
11 |
12 | * Redistributions in binary form must reproduce the above copyright notice,
13 | this list of conditions and the following disclaimer in the documentation
14 | and/or other materials provided with the distribution.
15 |
16 | * Neither the name of the copyright holder nor the names of its
17 | contributors may be used to endorse or promote products derived from
18 | this software without specific prior written permission.
19 |
20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | elm-contextmenu
2 | ===
3 |
4 | Flexible context menu for Elm ([Demo](https://jinjor.github.io/elm-contextmenu/))
5 |
6 | ## Warning
7 |
8 | On the migration from Elm 0.18 to 0.19, the legacy `Color` type has changed to just a type alias of `String` like `#aaa`, `rgb(100,100,200)`. Also, some icon libraries that uses `Color` type (i.e. `FontAwesome`, `MaterialIcons`) cannot be used anymore. So now you need to make a function typed as `String -> Int -> Html msg`. It *should* work but I haven't tested yet.
9 |
10 | I also think the implementation can be improved using new Browser API, but I cannot spend my time to try it. The styling method can be improved too. I would really appreciate if someone do that. Don't hesitate to fork this package or make your own from scratch! ([This article](http://jinjor-labo.hatenablog.com/entry/2016/11/05/201107) may help.)
11 |
12 |
13 | ## How to use
14 |
15 | This component works with [The Elm Architecture](https://guide.elm-lang.org/architecture/).
16 |
17 | 1. Model
18 | ```elm
19 | type alias Model =
20 | { contextMenu : ContextMenu Context
21 | , config : ContextMenu.Config
22 | , message : String
23 | }
24 | ```
25 |
26 | 2. Msg
27 | ```elm
28 | type Msg
29 | = ContextMenuMsg (ContextMenu.Msg Context)
30 | | Item Int
31 | ```
32 |
33 | 3. Initialize
34 | ```elm
35 | init : Flags -> (Model, Cmd Msg)
36 | init flags =
37 | let
38 | (contextMenu, msg) = ContextMenu.init
39 | in
40 | ( { contextMenu = contextMenu
41 | }
42 | , Cmd.map ContextMenuMsg msg
43 | )
44 | ```
45 |
46 | 4. Update
47 | ```elm
48 | update : Msg -> Model -> (Model, Cmd Msg)
49 | update msg model =
50 | case msg of
51 | ContextMenuMsg msg ->
52 | let
53 | (contextMenu, cmd) =
54 | ContextMenu.update msg model.contextMenu
55 | in
56 | ( { model | contextMenu = contextMenu }
57 | , Cmd.map ContextMenuMsg cmd
58 | )
59 | ```
60 |
61 | 5. Subscribe
62 | ```elm
63 | subscriptions : Model -> Sub Msg
64 | subscriptions model =
65 | Sub.map ContextMenuMsg (ContextMenu.subscriptions model.contextMenu)
66 | ```
67 |
68 | 6. View
69 | ```elm
70 | view : Model -> Html Msg
71 | view model =
72 | div
73 | [ ContextMenu.open ContextMenuMsg "context1" ]
74 | [ ContextMenu.view
75 | ContextMenu.defaultConfig
76 | ContextMenuMsg
77 | toItemGroups
78 | toItemGroups model.contextMenu
79 | ]
80 |
81 | toItemGroups : String -> List (List Item)
82 | toItemGroups context =
83 | if context == "context1" then
84 | [ [ (ContextMenu.item "Hey", Item 1)
85 | , (ContextMenu.item "Yo!", Item 2)
86 | ]
87 | ]
88 | else
89 | []
90 | ```
91 |
92 |
93 | ## License
94 |
95 | BSD-3-Clause
96 |
--------------------------------------------------------------------------------
/examples/Configs.elm:
--------------------------------------------------------------------------------
1 | module Configs exposing (deepBlue, googleSpreadsheet, gray, lightBlue, lightGray, mac, white, winChrome, winDesktop, winEdge, winFirefox)
2 |
3 | import ContextMenu exposing (..)
4 |
5 |
6 | type alias Color =
7 | String
8 |
9 |
10 | winDesktop : ContextMenu.Config
11 | winDesktop =
12 | { defaultConfig
13 | | direction = LeftBottom
14 | , overflowX = Shift
15 | , overflowY = Mirror
16 | , containerColor = lightGray
17 | , hoverColor = gray
18 | , invertText = False
19 | , cursor = Arrow
20 | , rounded = False
21 | }
22 |
23 |
24 | winChrome : ContextMenu.Config
25 | winChrome =
26 | { defaultConfig
27 | | direction = RightBottom
28 | , overflowX = Shift
29 | , overflowY = Mirror
30 | , containerColor = white
31 | , hoverColor = lightGray
32 | , invertText = False
33 | , cursor = Arrow
34 | , rounded = False
35 | }
36 |
37 |
38 | winFirefox : ContextMenu.Config
39 | winFirefox =
40 | { defaultConfig
41 | | direction = RightBottom
42 | , overflowX = Shift
43 | , overflowY = Mirror
44 | , containerColor = lightGray
45 | , hoverColor = lightBlue
46 | , invertText = False
47 | , cursor = Arrow
48 | , rounded = False
49 | }
50 |
51 |
52 | winEdge : ContextMenu.Config
53 | winEdge =
54 | { defaultConfig
55 | | direction = RightBottom
56 | , overflowX = Mirror
57 | , overflowY = Mirror
58 | , containerColor = lightGray
59 | , hoverColor = gray
60 | , invertText = False
61 | , cursor = Arrow
62 | , rounded = False
63 | }
64 |
65 |
66 | mac : ContextMenu.Config
67 | mac =
68 | { defaultConfig
69 | | direction = RightBottom
70 | , overflowX = Mirror
71 | , overflowY = Shift
72 | , containerColor = lightGray
73 | , hoverColor = deepBlue
74 | , invertText = True
75 | , cursor = Arrow
76 | , rounded = True
77 | }
78 |
79 |
80 | googleSpreadsheet : ContextMenu.Config
81 | googleSpreadsheet =
82 | { defaultConfig
83 | | direction = RightBottom
84 | , overflowX = Shift
85 | , overflowY = Shift
86 | , containerColor = white
87 | , hoverColor = lightGray
88 | , invertText = False
89 | , cursor = Pointer
90 | , rounded = False
91 | }
92 |
93 |
94 |
95 | ---- COLORS
96 |
97 |
98 | white : Color
99 | white =
100 | "rgb(255, 255, 255)"
101 |
102 |
103 | lightGray : Color
104 | lightGray =
105 | "rgb(238, 238, 238)"
106 |
107 |
108 | gray : Color
109 | gray =
110 | "rgb(217, 217, 217)"
111 |
112 |
113 | lightBlue : Color
114 | lightBlue =
115 | "rgb(117, 199, 253)"
116 |
117 |
118 | deepBlue : Color
119 | deepBlue =
120 | "rgb(62,126,255)"
121 |
--------------------------------------------------------------------------------
/src/Styles.elm:
--------------------------------------------------------------------------------
1 | module Styles exposing (Style, annotation, borderColor, container, icon, partition, px, row, shortcut, text)
2 |
3 | import Html exposing (Attribute)
4 | import Html.Attributes exposing (style)
5 |
6 |
7 | type alias Color =
8 | String
9 |
10 |
11 | type alias Style msg =
12 | List (Attribute msg)
13 |
14 |
15 | borderColor : String
16 | borderColor =
17 | "#ccc"
18 |
19 |
20 | container : Color -> Float -> Float -> Bool -> Float -> Float -> Float -> String -> Float -> Style msg
21 | container containerColor borderWidth padding rounded width left top fontFamily fontSize =
22 | [ style "border-style" "solid"
23 | , style "border-width" (px borderWidth)
24 | , style "border-color" borderColor
25 | , style "position" "fixed"
26 | , style "top" (px top)
27 | , style "left" (px left)
28 | , style "width" (px width)
29 | , style "z-index" (String.fromFloat (2147483647 - 10))
30 | , style "background-color" containerColor
31 | , style "cursor" "default"
32 | , style "box-shadow" "0px 3px 8px 0px rgba(0,0,0,0.3)"
33 | , style "padding" (px padding ++ " 0")
34 | , style "border-radius"
35 | (if rounded then
36 | px padding
37 |
38 | else
39 | ""
40 | )
41 | , style "font-family" fontFamily
42 | , style "font-size" (px fontSize)
43 | ]
44 |
45 |
46 | row : Color -> Color -> Bool -> Bool -> Float -> Bool -> Bool -> Bool -> Style msg
47 | row hoverColor disabledTextColor invertText usePointer lineHeight hovered disabled hasShortCut =
48 | [ style "position" "relative"
49 | , style "padding" "0 18px 0 28px"
50 | , style "background-color"
51 | (if hovered then
52 | hoverColor
53 |
54 | else
55 | ""
56 | )
57 | , style "height" (px lineHeight)
58 | , style "color"
59 | (if disabled then
60 | disabledTextColor
61 |
62 | else if hovered && invertText then
63 | "#fff"
64 |
65 | else
66 | ""
67 | )
68 | , style "cursor"
69 | (if not disabled && usePointer then
70 | "pointer"
71 |
72 | else
73 | ""
74 | )
75 | , style "display" "flex"
76 | , style "justify-content"
77 | (if hasShortCut then
78 | "space-between"
79 |
80 | else
81 | ""
82 | )
83 | ]
84 |
85 |
86 | text : Float -> Style msg
87 | text lineHeight =
88 | [ style "line-height" (px lineHeight)
89 | , style "text-overflow" "ellipsis"
90 | , style "overflow" "hidden"
91 | , style "white-space" "nowrap"
92 | ]
93 |
94 |
95 | annotation : Color -> Float -> Float -> Bool -> Style msg
96 | annotation color annotationHeight fontSize disabled =
97 | [ style "margin-top" "-2px"
98 | , style "line-height" (px annotationHeight)
99 | , style "font-size" (px fontSize)
100 | , style "color" color
101 | ]
102 |
103 |
104 | shortcut : Color -> Float -> Bool -> Style msg
105 | shortcut color lineHeight hovered =
106 | [ style "line-height" (px lineHeight)
107 | , style "color"
108 | (if hovered then
109 | ""
110 |
111 | else
112 | color
113 | )
114 | ]
115 |
116 |
117 | partition : Float -> Float -> Style msg
118 | partition borderWidth margin =
119 | [ style "border-bottom-style" "solid"
120 | , style "border-bottom-width" (px 1)
121 | , style "border-bottom-color" borderColor
122 | , style "border-top" "none"
123 | , style "margin" (px margin ++ " 0")
124 | ]
125 |
126 |
127 | icon : Float -> Style msg
128 | icon size =
129 | [ style "position" "absolute"
130 | , style "margin-left" (px (-size - 4))
131 | , style "top" "2px"
132 | ]
133 |
134 |
135 |
136 | ----
137 |
138 |
139 | px : Float -> String
140 | px n =
141 | String.fromFloat n ++ "px"
142 |
--------------------------------------------------------------------------------
/examples/Main.elm:
--------------------------------------------------------------------------------
1 | port module Main exposing (Context(..), Model, Msg(..), backgroundStyles, init, main, objectStyles, subscriptions, toItemGroups, update, view)
2 |
3 | import Browser
4 | import Configs
5 | import ContextMenu exposing (ContextMenu)
6 | import Html exposing (..)
7 | import Html.Attributes exposing (..)
8 |
9 |
10 | main : Program () Model Msg
11 | main =
12 | Browser.element
13 | { init = init
14 | , update = update
15 | , view = view
16 | , subscriptions = subscriptions
17 | }
18 |
19 |
20 | type alias Model =
21 | { contextMenu : ContextMenu Context
22 | , config : ContextMenu.Config
23 | , message : String
24 | }
25 |
26 |
27 | type Context
28 | = Object
29 | | Background
30 |
31 |
32 | type Msg
33 | = ContextMenuMsg (ContextMenu.Msg Context)
34 | | Item Int
35 |
36 |
37 | init : () -> ( Model, Cmd Msg )
38 | init _ =
39 | let
40 | ( contextMenu, msg ) =
41 | ContextMenu.init
42 | in
43 | ( { contextMenu = contextMenu
44 | , config = Configs.winChrome
45 | , message = ""
46 | }
47 | , Cmd.map ContextMenuMsg msg
48 | )
49 |
50 |
51 | update : Msg -> Model -> ( Model, Cmd Msg )
52 | update msg model =
53 | case msg of
54 | ContextMenuMsg msg_ ->
55 | let
56 | ( contextMenu, cmd ) =
57 | ContextMenu.update msg_ model.contextMenu
58 | in
59 | ( { model | contextMenu = contextMenu }
60 | , Cmd.map ContextMenuMsg cmd
61 | )
62 |
63 | Item num ->
64 | ( { model | message = "Item[" ++ String.fromInt num ++ "] was clicked." }
65 | , Cmd.none
66 | )
67 |
68 |
69 | subscriptions : Model -> Sub Msg
70 | subscriptions model =
71 | Sub.map ContextMenuMsg (ContextMenu.subscriptions model.contextMenu)
72 |
73 |
74 | view : Model -> Html Msg
75 | view model =
76 | div
77 | []
78 | [ div
79 | (ContextMenu.open ContextMenuMsg Background :: backgroundStyles)
80 | [ div
81 | (ContextMenu.open ContextMenuMsg Object :: objectStyles)
82 | []
83 | ]
84 | , div [] [ text model.message ]
85 | , ContextMenu.view
86 | model.config
87 | ContextMenuMsg
88 | toItemGroups
89 | model.contextMenu
90 | ]
91 |
92 |
93 | backgroundStyles : List (Attribute msg)
94 | backgroundStyles =
95 | [ style "left" "10%"
96 | , style "right" "10%"
97 | , style "top" "10%"
98 | , style "bottom" "-10%"
99 | , style "position" "absolute"
100 | , style "background-color" "#cdb"
101 | ]
102 |
103 |
104 | objectStyles : List (Attribute msg)
105 | objectStyles =
106 | [ style "position" "absolute"
107 | , style "top" "100px"
108 | , style "left" "150px"
109 | , style "width" "100px"
110 | , style "height" "100px"
111 | , style "background-color" "#976"
112 | ]
113 |
114 |
115 | toItemGroups : Context -> List (List ( ContextMenu.Item, Msg ))
116 | toItemGroups context =
117 | case context of
118 | Background ->
119 | [ [ ( ContextMenu.item "Hey", Item 1 )
120 | , ( ContextMenu.item "Yo!", Item 2 )
121 | ]
122 | , [ ( ContextMenu.item "Take photos"
123 | -- |> ContextMenu.icon FontAwesome.camera Color.green
124 | |> ContextMenu.disabled True
125 | , Item 3
126 | )
127 | , ( ContextMenu.item "Have a break"
128 | -- |> ContextMenu.icon FontAwesome.coffee Color.brown
129 | |> ContextMenu.disabled False
130 | , Item 4
131 | )
132 | , ( ContextMenu.item "Pneumonoultramicroscopicsilicovolcanoconiosis", Item 5 )
133 | , ( ContextMenu.item "Save"
134 | |> ContextMenu.shortcut "Ctrl+S"
135 | , Item 6
136 | )
137 | , ( ContextMenu.itemWithAnnotation "Item with annotation" "Some annotation here"
138 | -- |> ContextMenu.icon Material.tag_faces Color.red
139 | |> ContextMenu.disabled False
140 | , Item 7
141 | )
142 | ]
143 | ]
144 |
145 | Object ->
146 | [ [ ( ContextMenu.item "Pen", Item 8 )
147 | , ( ContextMenu.item "Pineapple", Item 9 )
148 | , ( ContextMenu.item "Apple", Item 10 )
149 | ]
150 | ]
151 |
--------------------------------------------------------------------------------
/src/ContextMenu.elm:
--------------------------------------------------------------------------------
1 | module ContextMenu exposing
2 | ( ContextMenu, Msg, init, update, subscriptions
3 | , Item, item, itemWithAnnotation, disabled, icon, shortcut
4 | , Config, Direction(..), Overflow(..), Cursor(..), defaultConfig
5 | , view, open, openIf
6 | , setOnDehover
7 | )
8 |
9 | {-| The ContextMenu component that follows the Elm Architecture.
10 |
11 | See [How to use](http://package.elm-lang.org/packages/jinjor/elm-contextmenu/latest).
12 |
13 |
14 | # TEA Parts
15 |
16 | The boilerplace functions. See [The Elm Architecture](https://guide.elm-lang.org/architecture/) for more information.
17 |
18 | @docs ContextMenu, Msg, init, update, subscriptions
19 |
20 |
21 | # Item
22 |
23 | @docs Item, item, itemWithAnnotation, disabled, icon, shortcut
24 |
25 |
26 | # Config
27 |
28 | @docs Config, Direction, Overflow, Cursor, defaultConfig
29 |
30 |
31 | # View
32 |
33 | @docs view, open, openIf
34 |
35 |
36 | # Advanced
37 |
38 | @docs setOnDehover
39 |
40 | -}
41 |
42 | import Browser
43 | import Browser.Dom
44 | import Browser.Events
45 | import Html exposing (..)
46 | import Html.Attributes exposing (..)
47 | import Html.Events exposing (..)
48 | import Json.Decode as Decode
49 | import Process
50 | import Styles as S
51 | import Task exposing (Task)
52 |
53 |
54 |
55 | -- TYPES
56 |
57 |
58 | type alias Color =
59 | String
60 |
61 |
62 | type alias Size =
63 | { width : Float
64 | , height : Float
65 | }
66 |
67 |
68 | type alias Position =
69 | { x : Float
70 | , y : Float
71 | }
72 |
73 |
74 |
75 | -- MODEL
76 |
77 |
78 | {-| The Model. Put whatever context you like, which is used to create menu items.
79 | -}
80 | type ContextMenu context
81 | = ContextMenu { openState : OpenState context, closeOnDehover : Bool }
82 |
83 |
84 | type HoverState
85 | = Container
86 | | ItemIndex ( Int, Int )
87 | | None
88 |
89 |
90 | getItemIndex : HoverState -> Maybe ( Int, Int )
91 | getItemIndex hover =
92 | case hover of
93 | ItemIndex index ->
94 | Just index
95 |
96 | _ ->
97 | Nothing
98 |
99 |
100 | type alias OpenState context =
101 | Maybe
102 | { mouse : Position
103 | , window : Size
104 | , hover : HoverState
105 | , context : context
106 | }
107 |
108 |
109 | shouldCloseOnClick : Bool -> OpenState context -> Bool
110 | shouldCloseOnClick closeOnDehover openState =
111 | case openState of
112 | Just { hover } ->
113 | if closeOnDehover then
114 | False
115 |
116 | else
117 | hover /= Container
118 |
119 | Nothing ->
120 | True
121 |
122 |
123 | setHoverState : HoverState -> OpenState context -> OpenState context
124 | setHoverState hover openState =
125 | openState
126 | |> Maybe.map
127 | (\{ mouse, window, context } ->
128 | { mouse = mouse
129 | , window = window
130 | , hover = hover
131 | , context = context
132 | }
133 | )
134 |
135 |
136 | {-| This switches when the menu should be closed.
137 |
138 | - True: Closes when mouse leaves the menu (keeps opening on cliking)
139 | - False(default): Closes when somewhere in the window is clicked
140 |
141 | -}
142 | setOnDehover : Bool -> ContextMenu context -> ContextMenu context
143 | setOnDehover closeOnDehover (ContextMenu model) =
144 | ContextMenu { model | closeOnDehover = closeOnDehover }
145 |
146 |
147 | enterItem : ( Int, Int ) -> OpenState context -> OpenState context
148 | enterItem index openState =
149 | setHoverState (ItemIndex index) openState
150 |
151 |
152 | leaveItem : OpenState context -> OpenState context
153 | leaveItem openState =
154 | setHoverState Container openState
155 |
156 |
157 | enterContainer : OpenState context -> OpenState context
158 | enterContainer openState =
159 | setHoverState Container openState
160 |
161 |
162 | leaveContainer : OpenState context -> OpenState context
163 | leaveContainer openState =
164 | setHoverState None openState
165 |
166 |
167 |
168 | -- UPDATE
169 |
170 |
171 | {-| The Message.
172 | -}
173 | type Msg context
174 | = NoOp
175 | | RequestOpen context Position
176 | | Open context Position Size
177 | | Close
178 | | EnterItem ( Int, Int )
179 | | LeaveItem
180 | | EnterContainer
181 | | LeaveContainer
182 |
183 |
184 | {-| The init function.
185 | -}
186 | init : ( ContextMenu context, Cmd (Msg context) )
187 | init =
188 | ( ContextMenu { openState = Nothing, closeOnDehover = False }, Cmd.none )
189 |
190 |
191 | {-| The update function.
192 | -}
193 | update : Msg context -> ContextMenu context -> ( ContextMenu context, Cmd (Msg context) )
194 | update msg (ContextMenu model) =
195 | case msg of
196 | NoOp ->
197 | ( ContextMenu model, Cmd.none )
198 |
199 | RequestOpen context mouse ->
200 | ( ContextMenu model
201 | , Task.perform (Open context mouse) windowSize
202 | )
203 |
204 | Open context mouse window ->
205 | ( ContextMenu
206 | { model
207 | | openState =
208 | Just
209 | { mouse = mouse
210 | , window = window
211 | , hover = None
212 | , context = context
213 | }
214 | }
215 | , Cmd.none
216 | )
217 |
218 | Close ->
219 | ( ContextMenu { model | openState = Nothing }, Cmd.none )
220 |
221 | EnterItem index ->
222 | ( ContextMenu { model | openState = enterItem index model.openState }
223 | , Cmd.none
224 | )
225 |
226 | LeaveItem ->
227 | ( ContextMenu { model | openState = leaveItem model.openState }
228 | , Cmd.none
229 | )
230 |
231 | EnterContainer ->
232 | ( ContextMenu { model | openState = enterContainer model.openState }
233 | , Cmd.none
234 | )
235 |
236 | LeaveContainer ->
237 | if model.closeOnDehover then
238 | update Close (ContextMenu { model | openState = leaveContainer model.openState })
239 |
240 | else
241 | ( ContextMenu { model | openState = leaveContainer model.openState }, Cmd.none )
242 |
243 |
244 | windowSize : Task x Size
245 | windowSize =
246 | Browser.Dom.getViewport
247 | |> Task.map
248 | (\v ->
249 | Size v.viewport.width v.viewport.height
250 | )
251 |
252 |
253 | {-| The Subscription.
254 | -}
255 | subscriptions : ContextMenu context -> Sub (Msg context)
256 | subscriptions (ContextMenu model) =
257 | Sub.batch
258 | [ if shouldCloseOnClick model.closeOnDehover model.openState then
259 | Browser.Events.onMouseDown (Decode.succeed Close)
260 |
261 | else
262 | Sub.none
263 | ]
264 |
265 |
266 |
267 | -- NUMBERS AND CALCULATION
268 |
269 |
270 | disabledTextColor : Color
271 | disabledTextColor =
272 | "rgb(200, 200, 200)"
273 |
274 |
275 | annotationTextColor : Color
276 | annotationTextColor =
277 | "rgb(200, 200, 200)"
278 |
279 |
280 | shortcutTextColor : Color
281 | shortcutTextColor =
282 | "rgb(200, 200, 200)"
283 |
284 |
285 | containerBorderWidth : Float
286 | containerBorderWidth =
287 | 1
288 |
289 |
290 | containerPadding : Float
291 | containerPadding =
292 | 4
293 |
294 |
295 | partitionWidth : Float
296 | partitionWidth =
297 | 1
298 |
299 |
300 | partitionMargin : Float
301 | partitionMargin =
302 | 6
303 |
304 |
305 | defaultItemHeight : Float
306 | defaultItemHeight =
307 | 20
308 |
309 |
310 | fontSize : Float
311 | fontSize =
312 | 13
313 |
314 |
315 | annotationHeight : Float
316 | annotationHeight =
317 | 12
318 |
319 |
320 | annotationFontSize : Float
321 | annotationFontSize =
322 | 10
323 |
324 |
325 | menuWidthWithBorders : Float -> Float
326 | menuWidthWithBorders menuWidth =
327 | menuWidth + containerBorderWidth * 2
328 |
329 |
330 | calculateMenuHeight : List (List Item) -> Float
331 | calculateMenuHeight groups =
332 | let
333 | containerBorders =
334 | containerBorderWidth * 2
335 |
336 | containerPaddings =
337 | containerPadding * 2
338 |
339 | partitions =
340 | toFloat (List.length groups - 1) * (partitionMargin * 2 + partitionWidth)
341 |
342 | items =
343 | List.sum
344 | (List.map
345 | (\items_ ->
346 | List.sum (List.map (\(Item item_) -> item_.height) items_)
347 | )
348 | groups
349 | )
350 | in
351 | containerBorders + containerPaddings + partitions + toFloat items
352 |
353 |
354 | calculateX : Direction -> Overflow -> Float -> Float -> Float -> Float
355 | calculateX direction overflow windowWidth menuWidth x =
356 | Basics.max 0 <|
357 | case direction of
358 | LeftBottom ->
359 | if x - menuWidth < 0 then
360 | if overflow == Shift then
361 | 0
362 |
363 | else
364 | x
365 |
366 | else
367 | x - menuWidth
368 |
369 | RightBottom ->
370 | if x + menuWidth > windowWidth then
371 | if overflow == Shift then
372 | windowWidth - menuWidth
373 |
374 | else
375 | x - menuWidth
376 |
377 | else
378 | x
379 |
380 |
381 | calculateY : Overflow -> Float -> Float -> Float -> Float
382 | calculateY overflow windowHeight menuHeight y =
383 | Basics.max 0 <|
384 | if y + menuHeight > windowHeight then
385 | if overflow == Shift then
386 | windowHeight - menuHeight
387 |
388 | else
389 | y - menuHeight
390 |
391 | else
392 | y
393 |
394 |
395 |
396 | -- ITEM
397 |
398 |
399 | {-| The menu item. You can construct it with pipe-friendly functions.
400 |
401 | ContextMenu.item "Take photos"
402 | -- This library is outdated. See README.
403 | -- |> ContextMenu.icon FontAwesome.camera Color.green
404 | |> ContextMenu.disabled True
405 |
406 | -}
407 | type Item
408 | = Item
409 | { height : Int
410 | , icon : Maybe ( String -> Int -> Html Never, String )
411 | , content : Content
412 | , shortcut : String
413 | , disabled : Bool
414 | }
415 |
416 |
417 | type Content
418 | = Text String
419 | | Custom (Bool -> Html Never)
420 |
421 |
422 | {-| Creates a simple text item.
423 | -}
424 | item : String -> Item
425 | item s =
426 | Item
427 | { height = floor defaultItemHeight
428 | , icon = Nothing
429 | , content = Text s
430 | , shortcut = ""
431 | , disabled = False
432 | }
433 |
434 |
435 | custom : Int -> (Bool -> Html Never) -> Item
436 | custom height content =
437 | Item
438 | { height = Basics.max (floor defaultItemHeight) height
439 | , icon = Nothing
440 | , content = Custom content
441 | , shortcut = ""
442 | , disabled = False
443 | }
444 |
445 |
446 | {-| Creates an item with annotation which will displayed just below the item name.
447 | -}
448 | itemWithAnnotation : String -> String -> Item
449 | itemWithAnnotation s ann =
450 | custom (floor <| defaultItemHeight + annotationHeight - 2) (annotationView s ann)
451 |
452 |
453 | {-| Disables the item. True = disabled, False = enabled.
454 | -}
455 | disabled : Bool -> Item -> Item
456 | disabled disabled_ (Item item_) =
457 | Item { item_ | disabled = disabled_ }
458 |
459 |
460 | {-| Displays the shortcut key at the right.
461 | -}
462 | shortcut : String -> Item -> Item
463 | shortcut shortcutName (Item item_) =
464 | Item { item_ | shortcut = shortcutName }
465 |
466 |
467 | {-| Shows the icon.
468 |
469 | The first argument is a function that creates an icon,
470 | given a color string(like `#fff`, `rgb(100,200,200)`, etc.) and icon size (px).
471 |
472 | -}
473 | icon : (String -> Int -> Html Never) -> String -> Item -> Item
474 | icon icon_ color (Item item_) =
475 | Item { item_ | icon = Just ( icon_, color ) }
476 |
477 |
478 |
479 | -- CONFIG
480 |
481 |
482 | {-| Defines the styles of the menu. See [examples](https://github.com/jinjor/elm-contextmenu/blob/master/examples/Configs.elm).
483 | -}
484 | type alias Config =
485 | { width : Int
486 | , direction : Direction
487 | , overflowX : Overflow
488 | , overflowY : Overflow
489 | , containerColor : Color
490 | , hoverColor : Color
491 | , invertText : Bool
492 | , cursor : Cursor
493 | , rounded : Bool
494 | , fontFamily : String
495 | }
496 |
497 |
498 | {-| The default direction the menu will be shown at.
499 | -}
500 | type Direction
501 | = LeftBottom
502 | | RightBottom
503 |
504 |
505 | {-| The strategies how to show the menu when it goes out of window.
506 | -}
507 | type Overflow
508 | = Shift
509 | | Mirror
510 |
511 |
512 | {-| The shape of cursor during hovering on the menu.
513 | -}
514 | type Cursor
515 | = Arrow
516 | | Pointer
517 |
518 |
519 | {-| The default config.
520 |
521 | defaultConfig =
522 | { width = 300
523 | , direction = RightBottom
524 | , overflowX = Mirror
525 | , overflowY = Mirror
526 | , containerColor = "white"
527 | , hoverColor = "rgb(240 240 240)"
528 | , invertText = False
529 | , cursor = Pointer
530 | , rounded = False
531 | , fontFamily = "initial"
532 | }
533 |
534 | -}
535 | defaultConfig : Config
536 | defaultConfig =
537 | { width = 300
538 | , direction = RightBottom
539 | , overflowX = Mirror
540 | , overflowY = Mirror
541 | , containerColor = "white"
542 | , hoverColor = "rgb(240 240 240)"
543 | , invertText = False
544 | , cursor = Pointer
545 | , rounded = False
546 | , fontFamily = "initial"
547 | }
548 |
549 |
550 |
551 | -- VIEW
552 |
553 |
554 | {-| Makes the attribute that triggers to open the menu.
555 | This attribute is passed for each element that needs a menu.
556 |
557 | Arguments:
558 |
559 | 1. function to transform component's message into user's message
560 | 2. the context which is used to create items
561 |
562 | -}
563 | open : (Msg context -> msg) -> context -> Attribute msg
564 | open transform context =
565 | openIf True transform context
566 |
567 |
568 | {-| Similar to `open` but only works under particular condition.
569 |
570 | This is useful for debugging on browser.
571 |
572 | -}
573 | openIf : Bool -> (Msg context -> msg) -> context -> Attribute msg
574 | openIf condition transform context =
575 | if condition then
576 | Html.Events.custom
577 | "contextmenu"
578 | (position
579 | |> Decode.map (RequestOpen context)
580 | |> Decode.map transform
581 | |> Decode.map
582 | (\msg ->
583 | { message = msg
584 | , stopPropagation = True
585 | , preventDefault = True
586 | }
587 | )
588 | )
589 |
590 | else
591 | on "contextmenu" (Decode.succeed (transform NoOp))
592 |
593 |
594 | position : Decode.Decoder Position
595 | position =
596 | Decode.map2 Position
597 | (Decode.field "clientX" Decode.float)
598 | (Decode.field "clientY" Decode.float)
599 |
600 |
601 | {-| Shows the menu. This should be called at only one place.
602 |
603 | Arguments:
604 |
605 | 1. the Config
606 | 2. function to transform component's message into user's message
607 | 3. function to create item groups
608 | 4. the Model
609 |
610 | -}
611 | view : Config -> (Msg context -> msg) -> (context -> List (List ( Item, msg ))) -> ContextMenu context -> Html msg
612 | view config transform toItemGroups (ContextMenu model) =
613 | case model.openState of
614 | Just { mouse, window, hover, context } ->
615 | let
616 | groups =
617 | toItemGroups context
618 |
619 | itemGroups =
620 | List.map (List.map Tuple.first) groups
621 |
622 | groupsView =
623 | List.indexedMap
624 | (itemGroupView config transform (getItemIndex hover))
625 | groups
626 | in
627 | case joinGroupsWithPartition groupsView of
628 | Just items ->
629 | let
630 | x_ =
631 | calculateX
632 | config.direction
633 | config.overflowX
634 | window.width
635 | (menuWidthWithBorders (toFloat config.width))
636 | mouse.x
637 |
638 | y_ =
639 | calculateY
640 | config.overflowY
641 | window.height
642 | (calculateMenuHeight itemGroups)
643 | mouse.y
644 | in
645 | div
646 | (S.container
647 | config.containerColor
648 | containerBorderWidth
649 | containerPadding
650 | config.rounded
651 | (toFloat config.width)
652 | x_
653 | y_
654 | config.fontFamily
655 | fontSize
656 | ++ [ onMouseEnter (transform EnterContainer)
657 | , onMouseLeave (transform LeaveContainer)
658 | ]
659 | )
660 | items
661 |
662 | Nothing ->
663 | Html.text ""
664 |
665 | Nothing ->
666 | Html.text ""
667 |
668 |
669 | joinGroupsWithPartition : List (List (Html msg)) -> Maybe (List (Html msg))
670 | joinGroupsWithPartition groups =
671 | List.foldr
672 | (\group prev ->
673 | case prev of
674 | Just items ->
675 | Just (group ++ (partition :: items))
676 |
677 | Nothing ->
678 | Just group
679 | )
680 | Nothing
681 | groups
682 |
683 |
684 | partition : Html msg
685 | partition =
686 | hr (S.partition partitionWidth partitionMargin) []
687 |
688 |
689 | itemGroupView : Config -> (Msg context -> msg) -> Maybe ( Int, Int ) -> Int -> List ( Item, msg ) -> List (Html msg)
690 | itemGroupView config transform hoverIndex groupIndex items =
691 | List.indexedMap (itemView config transform hoverIndex groupIndex) items
692 |
693 |
694 | itemView : Config -> (Msg context -> msg) -> Maybe ( Int, Int ) -> Int -> Int -> ( Item, msg ) -> Html msg
695 | itemView config transform hoverIndex groupIndex index ( Item item_, msg ) =
696 | let
697 | hovered =
698 | hoverIndex == Just ( groupIndex, index )
699 |
700 | styles =
701 | S.row
702 | config.hoverColor
703 | disabledTextColor
704 | config.invertText
705 | (config.cursor == Pointer)
706 | (toFloat item_.height)
707 | hovered
708 | item_.disabled
709 | (String.trim item_.shortcut /= "")
710 |
711 | events =
712 | if item_.disabled then
713 | []
714 |
715 | else
716 | [ onMouseEnter (transform <| EnterItem ( groupIndex, index ))
717 | , onMouseLeave (transform <| LeaveItem)
718 | , onMouseDown msg
719 | ]
720 |
721 | icon_ =
722 | case item_.icon of
723 | Just ( icon__, color ) ->
724 | Html.map never <|
725 | div
726 | (S.icon fontSize)
727 | [ icon__
728 | (if item_.disabled then
729 | disabledTextColor
730 |
731 | else
732 | color
733 | )
734 | (floor fontSize)
735 | ]
736 |
737 | Nothing ->
738 | Html.text ""
739 |
740 | content =
741 | case item_.content of
742 | Text s ->
743 | div (S.text (toFloat item_.height)) [ text s ]
744 |
745 | Custom toHtml ->
746 | toHtml item_.disabled
747 |
748 | shortCut =
749 | div
750 | (S.shortcut shortcutTextColor (toFloat item_.height) hovered)
751 | [ text item_.shortcut ]
752 | in
753 | div
754 | (styles ++ events)
755 | [ icon_
756 | , Html.map never content
757 | , shortCut
758 | ]
759 |
760 |
761 | annotationView : String -> String -> Bool -> Html Never
762 | annotationView s ann disabled_ =
763 | div []
764 | [ div
765 | (S.text defaultItemHeight)
766 | [ text s ]
767 | , div
768 | (S.annotation
769 | annotationTextColor
770 | annotationHeight
771 | annotationFontSize
772 | disabled_
773 | )
774 | [ text ann ]
775 | ]
776 |
--------------------------------------------------------------------------------
/docs/index.js:
--------------------------------------------------------------------------------
1 | (function(scope){
2 | 'use strict';
3 |
4 | function F(arity, fun, wrapper) {
5 | wrapper.a = arity;
6 | wrapper.f = fun;
7 | return wrapper;
8 | }
9 |
10 | function F2(fun) {
11 | return F(2, fun, function(a) { return function(b) { return fun(a,b); }; })
12 | }
13 | function F3(fun) {
14 | return F(3, fun, function(a) {
15 | return function(b) { return function(c) { return fun(a, b, c); }; };
16 | });
17 | }
18 | function F4(fun) {
19 | return F(4, fun, function(a) { return function(b) { return function(c) {
20 | return function(d) { return fun(a, b, c, d); }; }; };
21 | });
22 | }
23 | function F5(fun) {
24 | return F(5, fun, function(a) { return function(b) { return function(c) {
25 | return function(d) { return function(e) { return fun(a, b, c, d, e); }; }; }; };
26 | });
27 | }
28 | function F6(fun) {
29 | return F(6, fun, function(a) { return function(b) { return function(c) {
30 | return function(d) { return function(e) { return function(f) {
31 | return fun(a, b, c, d, e, f); }; }; }; }; };
32 | });
33 | }
34 | function F7(fun) {
35 | return F(7, fun, function(a) { return function(b) { return function(c) {
36 | return function(d) { return function(e) { return function(f) {
37 | return function(g) { return fun(a, b, c, d, e, f, g); }; }; }; }; }; };
38 | });
39 | }
40 | function F8(fun) {
41 | return F(8, fun, function(a) { return function(b) { return function(c) {
42 | return function(d) { return function(e) { return function(f) {
43 | return function(g) { return function(h) {
44 | return fun(a, b, c, d, e, f, g, h); }; }; }; }; }; }; };
45 | });
46 | }
47 | function F9(fun) {
48 | return F(9, fun, function(a) { return function(b) { return function(c) {
49 | return function(d) { return function(e) { return function(f) {
50 | return function(g) { return function(h) { return function(i) {
51 | return fun(a, b, c, d, e, f, g, h, i); }; }; }; }; }; }; }; };
52 | });
53 | }
54 |
55 | function A2(fun, a, b) {
56 | return fun.a === 2 ? fun.f(a, b) : fun(a)(b);
57 | }
58 | function A3(fun, a, b, c) {
59 | return fun.a === 3 ? fun.f(a, b, c) : fun(a)(b)(c);
60 | }
61 | function A4(fun, a, b, c, d) {
62 | return fun.a === 4 ? fun.f(a, b, c, d) : fun(a)(b)(c)(d);
63 | }
64 | function A5(fun, a, b, c, d, e) {
65 | return fun.a === 5 ? fun.f(a, b, c, d, e) : fun(a)(b)(c)(d)(e);
66 | }
67 | function A6(fun, a, b, c, d, e, f) {
68 | return fun.a === 6 ? fun.f(a, b, c, d, e, f) : fun(a)(b)(c)(d)(e)(f);
69 | }
70 | function A7(fun, a, b, c, d, e, f, g) {
71 | return fun.a === 7 ? fun.f(a, b, c, d, e, f, g) : fun(a)(b)(c)(d)(e)(f)(g);
72 | }
73 | function A8(fun, a, b, c, d, e, f, g, h) {
74 | return fun.a === 8 ? fun.f(a, b, c, d, e, f, g, h) : fun(a)(b)(c)(d)(e)(f)(g)(h);
75 | }
76 | function A9(fun, a, b, c, d, e, f, g, h, i) {
77 | return fun.a === 9 ? fun.f(a, b, c, d, e, f, g, h, i) : fun(a)(b)(c)(d)(e)(f)(g)(h)(i);
78 | }
79 |
80 | console.warn('Compiled in DEV mode. Follow the advice at https://elm-lang.org/0.19.0/optimize for better performance and smaller assets.');
81 |
82 |
83 | var _List_Nil_UNUSED = { $: 0 };
84 | var _List_Nil = { $: '[]' };
85 |
86 | function _List_Cons_UNUSED(hd, tl) { return { $: 1, a: hd, b: tl }; }
87 | function _List_Cons(hd, tl) { return { $: '::', a: hd, b: tl }; }
88 |
89 |
90 | var _List_cons = F2(_List_Cons);
91 |
92 | function _List_fromArray(arr)
93 | {
94 | var out = _List_Nil;
95 | for (var i = arr.length; i--; )
96 | {
97 | out = _List_Cons(arr[i], out);
98 | }
99 | return out;
100 | }
101 |
102 | function _List_toArray(xs)
103 | {
104 | for (var out = []; xs.b; xs = xs.b) // WHILE_CONS
105 | {
106 | out.push(xs.a);
107 | }
108 | return out;
109 | }
110 |
111 | var _List_map2 = F3(function(f, xs, ys)
112 | {
113 | for (var arr = []; xs.b && ys.b; xs = xs.b, ys = ys.b) // WHILE_CONSES
114 | {
115 | arr.push(A2(f, xs.a, ys.a));
116 | }
117 | return _List_fromArray(arr);
118 | });
119 |
120 | var _List_map3 = F4(function(f, xs, ys, zs)
121 | {
122 | for (var arr = []; xs.b && ys.b && zs.b; xs = xs.b, ys = ys.b, zs = zs.b) // WHILE_CONSES
123 | {
124 | arr.push(A3(f, xs.a, ys.a, zs.a));
125 | }
126 | return _List_fromArray(arr);
127 | });
128 |
129 | var _List_map4 = F5(function(f, ws, xs, ys, zs)
130 | {
131 | for (var arr = []; ws.b && xs.b && ys.b && zs.b; ws = ws.b, xs = xs.b, ys = ys.b, zs = zs.b) // WHILE_CONSES
132 | {
133 | arr.push(A4(f, ws.a, xs.a, ys.a, zs.a));
134 | }
135 | return _List_fromArray(arr);
136 | });
137 |
138 | var _List_map5 = F6(function(f, vs, ws, xs, ys, zs)
139 | {
140 | for (var arr = []; vs.b && ws.b && xs.b && ys.b && zs.b; vs = vs.b, ws = ws.b, xs = xs.b, ys = ys.b, zs = zs.b) // WHILE_CONSES
141 | {
142 | arr.push(A5(f, vs.a, ws.a, xs.a, ys.a, zs.a));
143 | }
144 | return _List_fromArray(arr);
145 | });
146 |
147 | var _List_sortBy = F2(function(f, xs)
148 | {
149 | return _List_fromArray(_List_toArray(xs).sort(function(a, b) {
150 | return _Utils_cmp(f(a), f(b));
151 | }));
152 | });
153 |
154 | var _List_sortWith = F2(function(f, xs)
155 | {
156 | return _List_fromArray(_List_toArray(xs).sort(function(a, b) {
157 | var ord = A2(f, a, b);
158 | return ord === elm$core$Basics$EQ ? 0 : ord === elm$core$Basics$LT ? -1 : 1;
159 | }));
160 | });
161 |
162 |
163 |
164 | // EQUALITY
165 |
166 | function _Utils_eq(x, y)
167 | {
168 | for (
169 | var pair, stack = [], isEqual = _Utils_eqHelp(x, y, 0, stack);
170 | isEqual && (pair = stack.pop());
171 | isEqual = _Utils_eqHelp(pair.a, pair.b, 0, stack)
172 | )
173 | {}
174 |
175 | return isEqual;
176 | }
177 |
178 | function _Utils_eqHelp(x, y, depth, stack)
179 | {
180 | if (depth > 100)
181 | {
182 | stack.push(_Utils_Tuple2(x,y));
183 | return true;
184 | }
185 |
186 | if (x === y)
187 | {
188 | return true;
189 | }
190 |
191 | if (typeof x !== 'object' || x === null || y === null)
192 | {
193 | typeof x === 'function' && _Debug_crash(5);
194 | return false;
195 | }
196 |
197 | /**/
198 | if (x.$ === 'Set_elm_builtin')
199 | {
200 | x = elm$core$Set$toList(x);
201 | y = elm$core$Set$toList(y);
202 | }
203 | if (x.$ === 'RBNode_elm_builtin' || x.$ === 'RBEmpty_elm_builtin')
204 | {
205 | x = elm$core$Dict$toList(x);
206 | y = elm$core$Dict$toList(y);
207 | }
208 | //*/
209 |
210 | /**_UNUSED/
211 | if (x.$ < 0)
212 | {
213 | x = elm$core$Dict$toList(x);
214 | y = elm$core$Dict$toList(y);
215 | }
216 | //*/
217 |
218 | for (var key in x)
219 | {
220 | if (!_Utils_eqHelp(x[key], y[key], depth + 1, stack))
221 | {
222 | return false;
223 | }
224 | }
225 | return true;
226 | }
227 |
228 | var _Utils_equal = F2(_Utils_eq);
229 | var _Utils_notEqual = F2(function(a, b) { return !_Utils_eq(a,b); });
230 |
231 |
232 |
233 | // COMPARISONS
234 |
235 | // Code in Generate/JavaScript.hs, Basics.js, and List.js depends on
236 | // the particular integer values assigned to LT, EQ, and GT.
237 |
238 | function _Utils_cmp(x, y, ord)
239 | {
240 | if (typeof x !== 'object')
241 | {
242 | return x === y ? /*EQ*/ 0 : x < y ? /*LT*/ -1 : /*GT*/ 1;
243 | }
244 |
245 | /**/
246 | if (x instanceof String)
247 | {
248 | var a = x.valueOf();
249 | var b = y.valueOf();
250 | return a === b ? 0 : a < b ? -1 : 1;
251 | }
252 | //*/
253 |
254 | /**_UNUSED/
255 | if (!x.$)
256 | //*/
257 | /**/
258 | if (x.$[0] === '#')
259 | //*/
260 | {
261 | return (ord = _Utils_cmp(x.a, y.a))
262 | ? ord
263 | : (ord = _Utils_cmp(x.b, y.b))
264 | ? ord
265 | : _Utils_cmp(x.c, y.c);
266 | }
267 |
268 | // traverse conses until end of a list or a mismatch
269 | for (; x.b && y.b && !(ord = _Utils_cmp(x.a, y.a)); x = x.b, y = y.b) {} // WHILE_CONSES
270 | return ord || (x.b ? /*GT*/ 1 : y.b ? /*LT*/ -1 : /*EQ*/ 0);
271 | }
272 |
273 | var _Utils_lt = F2(function(a, b) { return _Utils_cmp(a, b) < 0; });
274 | var _Utils_le = F2(function(a, b) { return _Utils_cmp(a, b) < 1; });
275 | var _Utils_gt = F2(function(a, b) { return _Utils_cmp(a, b) > 0; });
276 | var _Utils_ge = F2(function(a, b) { return _Utils_cmp(a, b) >= 0; });
277 |
278 | var _Utils_compare = F2(function(x, y)
279 | {
280 | var n = _Utils_cmp(x, y);
281 | return n < 0 ? elm$core$Basics$LT : n ? elm$core$Basics$GT : elm$core$Basics$EQ;
282 | });
283 |
284 |
285 | // COMMON VALUES
286 |
287 | var _Utils_Tuple0_UNUSED = 0;
288 | var _Utils_Tuple0 = { $: '#0' };
289 |
290 | function _Utils_Tuple2_UNUSED(a, b) { return { a: a, b: b }; }
291 | function _Utils_Tuple2(a, b) { return { $: '#2', a: a, b: b }; }
292 |
293 | function _Utils_Tuple3_UNUSED(a, b, c) { return { a: a, b: b, c: c }; }
294 | function _Utils_Tuple3(a, b, c) { return { $: '#3', a: a, b: b, c: c }; }
295 |
296 | function _Utils_chr_UNUSED(c) { return c; }
297 | function _Utils_chr(c) { return new String(c); }
298 |
299 |
300 | // RECORDS
301 |
302 | function _Utils_update(oldRecord, updatedFields)
303 | {
304 | var newRecord = {};
305 |
306 | for (var key in oldRecord)
307 | {
308 | newRecord[key] = oldRecord[key];
309 | }
310 |
311 | for (var key in updatedFields)
312 | {
313 | newRecord[key] = updatedFields[key];
314 | }
315 |
316 | return newRecord;
317 | }
318 |
319 |
320 | // APPEND
321 |
322 | var _Utils_append = F2(_Utils_ap);
323 |
324 | function _Utils_ap(xs, ys)
325 | {
326 | // append Strings
327 | if (typeof xs === 'string')
328 | {
329 | return xs + ys;
330 | }
331 |
332 | // append Lists
333 | if (!xs.b)
334 | {
335 | return ys;
336 | }
337 | var root = _List_Cons(xs.a, ys);
338 | xs = xs.b
339 | for (var curr = root; xs.b; xs = xs.b) // WHILE_CONS
340 | {
341 | curr = curr.b = _List_Cons(xs.a, ys);
342 | }
343 | return root;
344 | }
345 |
346 |
347 |
348 | var _JsArray_empty = [];
349 |
350 | function _JsArray_singleton(value)
351 | {
352 | return [value];
353 | }
354 |
355 | function _JsArray_length(array)
356 | {
357 | return array.length;
358 | }
359 |
360 | var _JsArray_initialize = F3(function(size, offset, func)
361 | {
362 | var result = new Array(size);
363 |
364 | for (var i = 0; i < size; i++)
365 | {
366 | result[i] = func(offset + i);
367 | }
368 |
369 | return result;
370 | });
371 |
372 | var _JsArray_initializeFromList = F2(function (max, ls)
373 | {
374 | var result = new Array(max);
375 |
376 | for (var i = 0; i < max && ls.b; i++)
377 | {
378 | result[i] = ls.a;
379 | ls = ls.b;
380 | }
381 |
382 | result.length = i;
383 | return _Utils_Tuple2(result, ls);
384 | });
385 |
386 | var _JsArray_unsafeGet = F2(function(index, array)
387 | {
388 | return array[index];
389 | });
390 |
391 | var _JsArray_unsafeSet = F3(function(index, value, array)
392 | {
393 | var length = array.length;
394 | var result = new Array(length);
395 |
396 | for (var i = 0; i < length; i++)
397 | {
398 | result[i] = array[i];
399 | }
400 |
401 | result[index] = value;
402 | return result;
403 | });
404 |
405 | var _JsArray_push = F2(function(value, array)
406 | {
407 | var length = array.length;
408 | var result = new Array(length + 1);
409 |
410 | for (var i = 0; i < length; i++)
411 | {
412 | result[i] = array[i];
413 | }
414 |
415 | result[length] = value;
416 | return result;
417 | });
418 |
419 | var _JsArray_foldl = F3(function(func, acc, array)
420 | {
421 | var length = array.length;
422 |
423 | for (var i = 0; i < length; i++)
424 | {
425 | acc = A2(func, array[i], acc);
426 | }
427 |
428 | return acc;
429 | });
430 |
431 | var _JsArray_foldr = F3(function(func, acc, array)
432 | {
433 | for (var i = array.length - 1; i >= 0; i--)
434 | {
435 | acc = A2(func, array[i], acc);
436 | }
437 |
438 | return acc;
439 | });
440 |
441 | var _JsArray_map = F2(function(func, array)
442 | {
443 | var length = array.length;
444 | var result = new Array(length);
445 |
446 | for (var i = 0; i < length; i++)
447 | {
448 | result[i] = func(array[i]);
449 | }
450 |
451 | return result;
452 | });
453 |
454 | var _JsArray_indexedMap = F3(function(func, offset, array)
455 | {
456 | var length = array.length;
457 | var result = new Array(length);
458 |
459 | for (var i = 0; i < length; i++)
460 | {
461 | result[i] = A2(func, offset + i, array[i]);
462 | }
463 |
464 | return result;
465 | });
466 |
467 | var _JsArray_slice = F3(function(from, to, array)
468 | {
469 | return array.slice(from, to);
470 | });
471 |
472 | var _JsArray_appendN = F3(function(n, dest, source)
473 | {
474 | var destLen = dest.length;
475 | var itemsToCopy = n - destLen;
476 |
477 | if (itemsToCopy > source.length)
478 | {
479 | itemsToCopy = source.length;
480 | }
481 |
482 | var size = destLen + itemsToCopy;
483 | var result = new Array(size);
484 |
485 | for (var i = 0; i < destLen; i++)
486 | {
487 | result[i] = dest[i];
488 | }
489 |
490 | for (var i = 0; i < itemsToCopy; i++)
491 | {
492 | result[i + destLen] = source[i];
493 | }
494 |
495 | return result;
496 | });
497 |
498 |
499 |
500 | // LOG
501 |
502 | var _Debug_log_UNUSED = F2(function(tag, value)
503 | {
504 | return value;
505 | });
506 |
507 | var _Debug_log = F2(function(tag, value)
508 | {
509 | console.log(tag + ': ' + _Debug_toString(value));
510 | return value;
511 | });
512 |
513 |
514 | // TODOS
515 |
516 | function _Debug_todo(moduleName, region)
517 | {
518 | return function(message) {
519 | _Debug_crash(8, moduleName, region, message);
520 | };
521 | }
522 |
523 | function _Debug_todoCase(moduleName, region, value)
524 | {
525 | return function(message) {
526 | _Debug_crash(9, moduleName, region, value, message);
527 | };
528 | }
529 |
530 |
531 | // TO STRING
532 |
533 | function _Debug_toString_UNUSED(value)
534 | {
535 | return '';
536 | }
537 |
538 | function _Debug_toString(value)
539 | {
540 | return _Debug_toAnsiString(false, value);
541 | }
542 |
543 | function _Debug_toAnsiString(ansi, value)
544 | {
545 | if (typeof value === 'function')
546 | {
547 | return _Debug_internalColor(ansi, '');
548 | }
549 |
550 | if (typeof value === 'boolean')
551 | {
552 | return _Debug_ctorColor(ansi, value ? 'True' : 'False');
553 | }
554 |
555 | if (typeof value === 'number')
556 | {
557 | return _Debug_numberColor(ansi, value + '');
558 | }
559 |
560 | if (value instanceof String)
561 | {
562 | return _Debug_charColor(ansi, "'" + _Debug_addSlashes(value, true) + "'");
563 | }
564 |
565 | if (typeof value === 'string')
566 | {
567 | return _Debug_stringColor(ansi, '"' + _Debug_addSlashes(value, false) + '"');
568 | }
569 |
570 | if (typeof value === 'object' && '$' in value)
571 | {
572 | var tag = value.$;
573 |
574 | if (typeof tag === 'number')
575 | {
576 | return _Debug_internalColor(ansi, '');
577 | }
578 |
579 | if (tag[0] === '#')
580 | {
581 | var output = [];
582 | for (var k in value)
583 | {
584 | if (k === '$') continue;
585 | output.push(_Debug_toAnsiString(ansi, value[k]));
586 | }
587 | return '(' + output.join(',') + ')';
588 | }
589 |
590 | if (tag === 'Set_elm_builtin')
591 | {
592 | return _Debug_ctorColor(ansi, 'Set')
593 | + _Debug_fadeColor(ansi, '.fromList') + ' '
594 | + _Debug_toAnsiString(ansi, elm$core$Set$toList(value));
595 | }
596 |
597 | if (tag === 'RBNode_elm_builtin' || tag === 'RBEmpty_elm_builtin')
598 | {
599 | return _Debug_ctorColor(ansi, 'Dict')
600 | + _Debug_fadeColor(ansi, '.fromList') + ' '
601 | + _Debug_toAnsiString(ansi, elm$core$Dict$toList(value));
602 | }
603 |
604 | if (tag === 'Array_elm_builtin')
605 | {
606 | return _Debug_ctorColor(ansi, 'Array')
607 | + _Debug_fadeColor(ansi, '.fromList') + ' '
608 | + _Debug_toAnsiString(ansi, elm$core$Array$toList(value));
609 | }
610 |
611 | if (tag === '::' || tag === '[]')
612 | {
613 | var output = '[';
614 |
615 | value.b && (output += _Debug_toAnsiString(ansi, value.a), value = value.b)
616 |
617 | for (; value.b; value = value.b) // WHILE_CONS
618 | {
619 | output += ',' + _Debug_toAnsiString(ansi, value.a);
620 | }
621 | return output + ']';
622 | }
623 |
624 | var output = '';
625 | for (var i in value)
626 | {
627 | if (i === '$') continue;
628 | var str = _Debug_toAnsiString(ansi, value[i]);
629 | var c0 = str[0];
630 | var parenless = c0 === '{' || c0 === '(' || c0 === '[' || c0 === '<' || c0 === '"' || str.indexOf(' ') < 0;
631 | output += ' ' + (parenless ? str : '(' + str + ')');
632 | }
633 | return _Debug_ctorColor(ansi, tag) + output;
634 | }
635 |
636 | if (typeof value === 'object')
637 | {
638 | var output = [];
639 | for (var key in value)
640 | {
641 | var field = key[0] === '_' ? key.slice(1) : key;
642 | output.push(_Debug_fadeColor(ansi, field) + ' = ' + _Debug_toAnsiString(ansi, value[key]));
643 | }
644 | if (output.length === 0)
645 | {
646 | return '{}';
647 | }
648 | return '{ ' + output.join(', ') + ' }';
649 | }
650 |
651 | return _Debug_internalColor(ansi, '');
652 | }
653 |
654 | function _Debug_addSlashes(str, isChar)
655 | {
656 | var s = str
657 | .replace(/\\/g, '\\\\')
658 | .replace(/\n/g, '\\n')
659 | .replace(/\t/g, '\\t')
660 | .replace(/\r/g, '\\r')
661 | .replace(/\v/g, '\\v')
662 | .replace(/\0/g, '\\0');
663 |
664 | if (isChar)
665 | {
666 | return s.replace(/\'/g, '\\\'');
667 | }
668 | else
669 | {
670 | return s.replace(/\"/g, '\\"');
671 | }
672 | }
673 |
674 | function _Debug_ctorColor(ansi, string)
675 | {
676 | return ansi ? '\x1b[96m' + string + '\x1b[0m' : string;
677 | }
678 |
679 | function _Debug_numberColor(ansi, string)
680 | {
681 | return ansi ? '\x1b[95m' + string + '\x1b[0m' : string;
682 | }
683 |
684 | function _Debug_stringColor(ansi, string)
685 | {
686 | return ansi ? '\x1b[93m' + string + '\x1b[0m' : string;
687 | }
688 |
689 | function _Debug_charColor(ansi, string)
690 | {
691 | return ansi ? '\x1b[92m' + string + '\x1b[0m' : string;
692 | }
693 |
694 | function _Debug_fadeColor(ansi, string)
695 | {
696 | return ansi ? '\x1b[37m' + string + '\x1b[0m' : string;
697 | }
698 |
699 | function _Debug_internalColor(ansi, string)
700 | {
701 | return ansi ? '\x1b[94m' + string + '\x1b[0m' : string;
702 | }
703 |
704 |
705 |
706 | // CRASH
707 |
708 |
709 | function _Debug_crash_UNUSED(identifier)
710 | {
711 | throw new Error('https://github.com/elm/core/blob/1.0.0/hints/' + identifier + '.md');
712 | }
713 |
714 |
715 | function _Debug_crash(identifier, fact1, fact2, fact3, fact4)
716 | {
717 | switch(identifier)
718 | {
719 | case 0:
720 | throw new Error('What node should I take over? In JavaScript I need something like:\n\n Elm.Main.init({\n node: document.getElementById("elm-node")\n })\n\nYou need to do this with any Browser.sandbox or Browser.element program.');
721 |
722 | case 1:
723 | throw new Error('Browser.application programs cannot handle URLs like this:\n\n ' + document.location.href + '\n\nWhat is the root? The root of your file system? Try looking at this program with `elm reactor` or some other server.');
724 |
725 | case 2:
726 | var jsonErrorString = fact1;
727 | throw new Error('Problem with the flags given to your Elm program on initialization.\n\n' + jsonErrorString);
728 |
729 | case 3:
730 | var portName = fact1;
731 | throw new Error('There can only be one port named `' + portName + '`, but your program has multiple.');
732 |
733 | case 4:
734 | var portName = fact1;
735 | var problem = fact2;
736 | throw new Error('Trying to send an unexpected type of value through port `' + portName + '`:\n' + problem);
737 |
738 | case 5:
739 | throw new Error('Trying to use `(==)` on functions.\nThere is no way to know if functions are "the same" in the Elm sense.\nRead more about this at https://package.elm-lang.org/packages/elm/core/latest/Basics#== which describes why it is this way and what the better version will look like.');
740 |
741 | case 6:
742 | var moduleName = fact1;
743 | throw new Error('Your page is loading multiple Elm scripts with a module named ' + moduleName + '. Maybe a duplicate script is getting loaded accidentally? If not, rename one of them so I know which is which!');
744 |
745 | case 8:
746 | var moduleName = fact1;
747 | var region = fact2;
748 | var message = fact3;
749 | throw new Error('TODO in module `' + moduleName + '` ' + _Debug_regionToString(region) + '\n\n' + message);
750 |
751 | case 9:
752 | var moduleName = fact1;
753 | var region = fact2;
754 | var value = fact3;
755 | var message = fact4;
756 | throw new Error(
757 | 'TODO in module `' + moduleName + '` from the `case` expression '
758 | + _Debug_regionToString(region) + '\n\nIt received the following value:\n\n '
759 | + _Debug_toString(value).replace('\n', '\n ')
760 | + '\n\nBut the branch that handles it says:\n\n ' + message.replace('\n', '\n ')
761 | );
762 |
763 | case 10:
764 | throw new Error('Bug in https://github.com/elm/virtual-dom/issues');
765 |
766 | case 11:
767 | throw new Error('Cannot perform mod 0. Division by zero error.');
768 | }
769 | }
770 |
771 | function _Debug_regionToString(region)
772 | {
773 | if (region.start.line === region.end.line)
774 | {
775 | return 'on line ' + region.start.line;
776 | }
777 | return 'on lines ' + region.start.line + ' through ' + region.end.line;
778 | }
779 |
780 |
781 |
782 | // MATH
783 |
784 | var _Basics_add = F2(function(a, b) { return a + b; });
785 | var _Basics_sub = F2(function(a, b) { return a - b; });
786 | var _Basics_mul = F2(function(a, b) { return a * b; });
787 | var _Basics_fdiv = F2(function(a, b) { return a / b; });
788 | var _Basics_idiv = F2(function(a, b) { return (a / b) | 0; });
789 | var _Basics_pow = F2(Math.pow);
790 |
791 | var _Basics_remainderBy = F2(function(b, a) { return a % b; });
792 |
793 | // https://www.microsoft.com/en-us/research/wp-content/uploads/2016/02/divmodnote-letter.pdf
794 | var _Basics_modBy = F2(function(modulus, x)
795 | {
796 | var answer = x % modulus;
797 | return modulus === 0
798 | ? _Debug_crash(11)
799 | :
800 | ((answer > 0 && modulus < 0) || (answer < 0 && modulus > 0))
801 | ? answer + modulus
802 | : answer;
803 | });
804 |
805 |
806 | // TRIGONOMETRY
807 |
808 | var _Basics_pi = Math.PI;
809 | var _Basics_e = Math.E;
810 | var _Basics_cos = Math.cos;
811 | var _Basics_sin = Math.sin;
812 | var _Basics_tan = Math.tan;
813 | var _Basics_acos = Math.acos;
814 | var _Basics_asin = Math.asin;
815 | var _Basics_atan = Math.atan;
816 | var _Basics_atan2 = F2(Math.atan2);
817 |
818 |
819 | // MORE MATH
820 |
821 | function _Basics_toFloat(x) { return x; }
822 | function _Basics_truncate(n) { return n | 0; }
823 | function _Basics_isInfinite(n) { return n === Infinity || n === -Infinity; }
824 |
825 | var _Basics_ceiling = Math.ceil;
826 | var _Basics_floor = Math.floor;
827 | var _Basics_round = Math.round;
828 | var _Basics_sqrt = Math.sqrt;
829 | var _Basics_log = Math.log;
830 | var _Basics_isNaN = isNaN;
831 |
832 |
833 | // BOOLEANS
834 |
835 | function _Basics_not(bool) { return !bool; }
836 | var _Basics_and = F2(function(a, b) { return a && b; });
837 | var _Basics_or = F2(function(a, b) { return a || b; });
838 | var _Basics_xor = F2(function(a, b) { return a !== b; });
839 |
840 |
841 |
842 | function _Char_toCode(char)
843 | {
844 | var code = char.charCodeAt(0);
845 | if (0xD800 <= code && code <= 0xDBFF)
846 | {
847 | return (code - 0xD800) * 0x400 + char.charCodeAt(1) - 0xDC00 + 0x10000
848 | }
849 | return code;
850 | }
851 |
852 | function _Char_fromCode(code)
853 | {
854 | return _Utils_chr(
855 | (code < 0 || 0x10FFFF < code)
856 | ? '\uFFFD'
857 | :
858 | (code <= 0xFFFF)
859 | ? String.fromCharCode(code)
860 | :
861 | (code -= 0x10000,
862 | String.fromCharCode(Math.floor(code / 0x400) + 0xD800)
863 | +
864 | String.fromCharCode(code % 0x400 + 0xDC00)
865 | )
866 | );
867 | }
868 |
869 | function _Char_toUpper(char)
870 | {
871 | return _Utils_chr(char.toUpperCase());
872 | }
873 |
874 | function _Char_toLower(char)
875 | {
876 | return _Utils_chr(char.toLowerCase());
877 | }
878 |
879 | function _Char_toLocaleUpper(char)
880 | {
881 | return _Utils_chr(char.toLocaleUpperCase());
882 | }
883 |
884 | function _Char_toLocaleLower(char)
885 | {
886 | return _Utils_chr(char.toLocaleLowerCase());
887 | }
888 |
889 |
890 |
891 | var _String_cons = F2(function(chr, str)
892 | {
893 | return chr + str;
894 | });
895 |
896 | function _String_uncons(string)
897 | {
898 | var word = string.charCodeAt(0);
899 | return word
900 | ? elm$core$Maybe$Just(
901 | 0xD800 <= word && word <= 0xDBFF
902 | ? _Utils_Tuple2(_Utils_chr(string[0] + string[1]), string.slice(2))
903 | : _Utils_Tuple2(_Utils_chr(string[0]), string.slice(1))
904 | )
905 | : elm$core$Maybe$Nothing;
906 | }
907 |
908 | var _String_append = F2(function(a, b)
909 | {
910 | return a + b;
911 | });
912 |
913 | function _String_length(str)
914 | {
915 | return str.length;
916 | }
917 |
918 | var _String_map = F2(function(func, string)
919 | {
920 | var len = string.length;
921 | var array = new Array(len);
922 | var i = 0;
923 | while (i < len)
924 | {
925 | var word = string.charCodeAt(i);
926 | if (0xD800 <= word && word <= 0xDBFF)
927 | {
928 | array[i] = func(_Utils_chr(string[i] + string[i+1]));
929 | i += 2;
930 | continue;
931 | }
932 | array[i] = func(_Utils_chr(string[i]));
933 | i++;
934 | }
935 | return array.join('');
936 | });
937 |
938 | var _String_filter = F2(function(isGood, str)
939 | {
940 | var arr = [];
941 | var len = str.length;
942 | var i = 0;
943 | while (i < len)
944 | {
945 | var char = str[i];
946 | var word = str.charCodeAt(i);
947 | i++;
948 | if (0xD800 <= word && word <= 0xDBFF)
949 | {
950 | char += str[i];
951 | i++;
952 | }
953 |
954 | if (isGood(_Utils_chr(char)))
955 | {
956 | arr.push(char);
957 | }
958 | }
959 | return arr.join('');
960 | });
961 |
962 | function _String_reverse(str)
963 | {
964 | var len = str.length;
965 | var arr = new Array(len);
966 | var i = 0;
967 | while (i < len)
968 | {
969 | var word = str.charCodeAt(i);
970 | if (0xD800 <= word && word <= 0xDBFF)
971 | {
972 | arr[len - i] = str[i + 1];
973 | i++;
974 | arr[len - i] = str[i - 1];
975 | i++;
976 | }
977 | else
978 | {
979 | arr[len - i] = str[i];
980 | i++;
981 | }
982 | }
983 | return arr.join('');
984 | }
985 |
986 | var _String_foldl = F3(function(func, state, string)
987 | {
988 | var len = string.length;
989 | var i = 0;
990 | while (i < len)
991 | {
992 | var char = string[i];
993 | var word = string.charCodeAt(i);
994 | i++;
995 | if (0xD800 <= word && word <= 0xDBFF)
996 | {
997 | char += string[i];
998 | i++;
999 | }
1000 | state = A2(func, _Utils_chr(char), state);
1001 | }
1002 | return state;
1003 | });
1004 |
1005 | var _String_foldr = F3(function(func, state, string)
1006 | {
1007 | var i = string.length;
1008 | while (i--)
1009 | {
1010 | var char = string[i];
1011 | var word = string.charCodeAt(i);
1012 | if (0xDC00 <= word && word <= 0xDFFF)
1013 | {
1014 | i--;
1015 | char = string[i] + char;
1016 | }
1017 | state = A2(func, _Utils_chr(char), state);
1018 | }
1019 | return state;
1020 | });
1021 |
1022 | var _String_split = F2(function(sep, str)
1023 | {
1024 | return str.split(sep);
1025 | });
1026 |
1027 | var _String_join = F2(function(sep, strs)
1028 | {
1029 | return strs.join(sep);
1030 | });
1031 |
1032 | var _String_slice = F3(function(start, end, str) {
1033 | return str.slice(start, end);
1034 | });
1035 |
1036 | function _String_trim(str)
1037 | {
1038 | return str.trim();
1039 | }
1040 |
1041 | function _String_trimLeft(str)
1042 | {
1043 | return str.replace(/^\s+/, '');
1044 | }
1045 |
1046 | function _String_trimRight(str)
1047 | {
1048 | return str.replace(/\s+$/, '');
1049 | }
1050 |
1051 | function _String_words(str)
1052 | {
1053 | return _List_fromArray(str.trim().split(/\s+/g));
1054 | }
1055 |
1056 | function _String_lines(str)
1057 | {
1058 | return _List_fromArray(str.split(/\r\n|\r|\n/g));
1059 | }
1060 |
1061 | function _String_toUpper(str)
1062 | {
1063 | return str.toUpperCase();
1064 | }
1065 |
1066 | function _String_toLower(str)
1067 | {
1068 | return str.toLowerCase();
1069 | }
1070 |
1071 | var _String_any = F2(function(isGood, string)
1072 | {
1073 | var i = string.length;
1074 | while (i--)
1075 | {
1076 | var char = string[i];
1077 | var word = string.charCodeAt(i);
1078 | if (0xDC00 <= word && word <= 0xDFFF)
1079 | {
1080 | i--;
1081 | char = string[i] + char;
1082 | }
1083 | if (isGood(_Utils_chr(char)))
1084 | {
1085 | return true;
1086 | }
1087 | }
1088 | return false;
1089 | });
1090 |
1091 | var _String_all = F2(function(isGood, string)
1092 | {
1093 | var i = string.length;
1094 | while (i--)
1095 | {
1096 | var char = string[i];
1097 | var word = string.charCodeAt(i);
1098 | if (0xDC00 <= word && word <= 0xDFFF)
1099 | {
1100 | i--;
1101 | char = string[i] + char;
1102 | }
1103 | if (!isGood(_Utils_chr(char)))
1104 | {
1105 | return false;
1106 | }
1107 | }
1108 | return true;
1109 | });
1110 |
1111 | var _String_contains = F2(function(sub, str)
1112 | {
1113 | return str.indexOf(sub) > -1;
1114 | });
1115 |
1116 | var _String_startsWith = F2(function(sub, str)
1117 | {
1118 | return str.indexOf(sub) === 0;
1119 | });
1120 |
1121 | var _String_endsWith = F2(function(sub, str)
1122 | {
1123 | return str.length >= sub.length &&
1124 | str.lastIndexOf(sub) === str.length - sub.length;
1125 | });
1126 |
1127 | var _String_indexes = F2(function(sub, str)
1128 | {
1129 | var subLen = sub.length;
1130 |
1131 | if (subLen < 1)
1132 | {
1133 | return _List_Nil;
1134 | }
1135 |
1136 | var i = 0;
1137 | var is = [];
1138 |
1139 | while ((i = str.indexOf(sub, i)) > -1)
1140 | {
1141 | is.push(i);
1142 | i = i + subLen;
1143 | }
1144 |
1145 | return _List_fromArray(is);
1146 | });
1147 |
1148 |
1149 | // TO STRING
1150 |
1151 | function _String_fromNumber(number)
1152 | {
1153 | return number + '';
1154 | }
1155 |
1156 |
1157 | // INT CONVERSIONS
1158 |
1159 | function _String_toInt(str)
1160 | {
1161 | var total = 0;
1162 | var code0 = str.charCodeAt(0);
1163 | var start = code0 == 0x2B /* + */ || code0 == 0x2D /* - */ ? 1 : 0;
1164 |
1165 | for (var i = start; i < str.length; ++i)
1166 | {
1167 | var code = str.charCodeAt(i);
1168 | if (code < 0x30 || 0x39 < code)
1169 | {
1170 | return elm$core$Maybe$Nothing;
1171 | }
1172 | total = 10 * total + code - 0x30;
1173 | }
1174 |
1175 | return i == start
1176 | ? elm$core$Maybe$Nothing
1177 | : elm$core$Maybe$Just(code0 == 0x2D ? -total : total);
1178 | }
1179 |
1180 |
1181 | // FLOAT CONVERSIONS
1182 |
1183 | function _String_toFloat(s)
1184 | {
1185 | // check if it is a hex, octal, or binary number
1186 | if (s.length === 0 || /[\sxbo]/.test(s))
1187 | {
1188 | return elm$core$Maybe$Nothing;
1189 | }
1190 | var n = +s;
1191 | // faster isNaN check
1192 | return n === n ? elm$core$Maybe$Just(n) : elm$core$Maybe$Nothing;
1193 | }
1194 |
1195 | function _String_fromList(chars)
1196 | {
1197 | return _List_toArray(chars).join('');
1198 | }
1199 |
1200 |
1201 |
1202 |
1203 | /**/
1204 | function _Json_errorToString(error)
1205 | {
1206 | return elm$json$Json$Decode$errorToString(error);
1207 | }
1208 | //*/
1209 |
1210 |
1211 | // CORE DECODERS
1212 |
1213 | function _Json_succeed(msg)
1214 | {
1215 | return {
1216 | $: 0,
1217 | a: msg
1218 | };
1219 | }
1220 |
1221 | function _Json_fail(msg)
1222 | {
1223 | return {
1224 | $: 1,
1225 | a: msg
1226 | };
1227 | }
1228 |
1229 | var _Json_decodeInt = { $: 2 };
1230 | var _Json_decodeBool = { $: 3 };
1231 | var _Json_decodeFloat = { $: 4 };
1232 | var _Json_decodeValue = { $: 5 };
1233 | var _Json_decodeString = { $: 6 };
1234 |
1235 | function _Json_decodeList(decoder) { return { $: 7, b: decoder }; }
1236 | function _Json_decodeArray(decoder) { return { $: 8, b: decoder }; }
1237 |
1238 | function _Json_decodeNull(value) { return { $: 9, c: value }; }
1239 |
1240 | var _Json_decodeField = F2(function(field, decoder)
1241 | {
1242 | return {
1243 | $: 10,
1244 | d: field,
1245 | b: decoder
1246 | };
1247 | });
1248 |
1249 | var _Json_decodeIndex = F2(function(index, decoder)
1250 | {
1251 | return {
1252 | $: 11,
1253 | e: index,
1254 | b: decoder
1255 | };
1256 | });
1257 |
1258 | function _Json_decodeKeyValuePairs(decoder)
1259 | {
1260 | return {
1261 | $: 12,
1262 | b: decoder
1263 | };
1264 | }
1265 |
1266 | function _Json_mapMany(f, decoders)
1267 | {
1268 | return {
1269 | $: 13,
1270 | f: f,
1271 | g: decoders
1272 | };
1273 | }
1274 |
1275 | var _Json_andThen = F2(function(callback, decoder)
1276 | {
1277 | return {
1278 | $: 14,
1279 | b: decoder,
1280 | h: callback
1281 | };
1282 | });
1283 |
1284 | function _Json_oneOf(decoders)
1285 | {
1286 | return {
1287 | $: 15,
1288 | g: decoders
1289 | };
1290 | }
1291 |
1292 |
1293 | // DECODING OBJECTS
1294 |
1295 | var _Json_map1 = F2(function(f, d1)
1296 | {
1297 | return _Json_mapMany(f, [d1]);
1298 | });
1299 |
1300 | var _Json_map2 = F3(function(f, d1, d2)
1301 | {
1302 | return _Json_mapMany(f, [d1, d2]);
1303 | });
1304 |
1305 | var _Json_map3 = F4(function(f, d1, d2, d3)
1306 | {
1307 | return _Json_mapMany(f, [d1, d2, d3]);
1308 | });
1309 |
1310 | var _Json_map4 = F5(function(f, d1, d2, d3, d4)
1311 | {
1312 | return _Json_mapMany(f, [d1, d2, d3, d4]);
1313 | });
1314 |
1315 | var _Json_map5 = F6(function(f, d1, d2, d3, d4, d5)
1316 | {
1317 | return _Json_mapMany(f, [d1, d2, d3, d4, d5]);
1318 | });
1319 |
1320 | var _Json_map6 = F7(function(f, d1, d2, d3, d4, d5, d6)
1321 | {
1322 | return _Json_mapMany(f, [d1, d2, d3, d4, d5, d6]);
1323 | });
1324 |
1325 | var _Json_map7 = F8(function(f, d1, d2, d3, d4, d5, d6, d7)
1326 | {
1327 | return _Json_mapMany(f, [d1, d2, d3, d4, d5, d6, d7]);
1328 | });
1329 |
1330 | var _Json_map8 = F9(function(f, d1, d2, d3, d4, d5, d6, d7, d8)
1331 | {
1332 | return _Json_mapMany(f, [d1, d2, d3, d4, d5, d6, d7, d8]);
1333 | });
1334 |
1335 |
1336 | // DECODE
1337 |
1338 | var _Json_runOnString = F2(function(decoder, string)
1339 | {
1340 | try
1341 | {
1342 | var value = JSON.parse(string);
1343 | return _Json_runHelp(decoder, value);
1344 | }
1345 | catch (e)
1346 | {
1347 | return elm$core$Result$Err(A2(elm$json$Json$Decode$Failure, 'This is not valid JSON! ' + e.message, _Json_wrap(string)));
1348 | }
1349 | });
1350 |
1351 | var _Json_run = F2(function(decoder, value)
1352 | {
1353 | return _Json_runHelp(decoder, _Json_unwrap(value));
1354 | });
1355 |
1356 | function _Json_runHelp(decoder, value)
1357 | {
1358 | switch (decoder.$)
1359 | {
1360 | case 3:
1361 | return (typeof value === 'boolean')
1362 | ? elm$core$Result$Ok(value)
1363 | : _Json_expecting('a BOOL', value);
1364 |
1365 | case 2:
1366 | if (typeof value !== 'number') {
1367 | return _Json_expecting('an INT', value);
1368 | }
1369 |
1370 | if (-2147483647 < value && value < 2147483647 && (value | 0) === value) {
1371 | return elm$core$Result$Ok(value);
1372 | }
1373 |
1374 | if (isFinite(value) && !(value % 1)) {
1375 | return elm$core$Result$Ok(value);
1376 | }
1377 |
1378 | return _Json_expecting('an INT', value);
1379 |
1380 | case 4:
1381 | return (typeof value === 'number')
1382 | ? elm$core$Result$Ok(value)
1383 | : _Json_expecting('a FLOAT', value);
1384 |
1385 | case 6:
1386 | return (typeof value === 'string')
1387 | ? elm$core$Result$Ok(value)
1388 | : (value instanceof String)
1389 | ? elm$core$Result$Ok(value + '')
1390 | : _Json_expecting('a STRING', value);
1391 |
1392 | case 9:
1393 | return (value === null)
1394 | ? elm$core$Result$Ok(decoder.c)
1395 | : _Json_expecting('null', value);
1396 |
1397 | case 5:
1398 | return elm$core$Result$Ok(_Json_wrap(value));
1399 |
1400 | case 7:
1401 | if (!Array.isArray(value))
1402 | {
1403 | return _Json_expecting('a LIST', value);
1404 | }
1405 | return _Json_runArrayDecoder(decoder.b, value, _List_fromArray);
1406 |
1407 | case 8:
1408 | if (!Array.isArray(value))
1409 | {
1410 | return _Json_expecting('an ARRAY', value);
1411 | }
1412 | return _Json_runArrayDecoder(decoder.b, value, _Json_toElmArray);
1413 |
1414 | case 10:
1415 | var field = decoder.d;
1416 | if (typeof value !== 'object' || value === null || !(field in value))
1417 | {
1418 | return _Json_expecting('an OBJECT with a field named `' + field + '`', value);
1419 | }
1420 | var result = _Json_runHelp(decoder.b, value[field]);
1421 | return (elm$core$Result$isOk(result)) ? result : elm$core$Result$Err(A2(elm$json$Json$Decode$Field, field, result.a));
1422 |
1423 | case 11:
1424 | var index = decoder.e;
1425 | if (!Array.isArray(value))
1426 | {
1427 | return _Json_expecting('an ARRAY', value);
1428 | }
1429 | if (index >= value.length)
1430 | {
1431 | return _Json_expecting('a LONGER array. Need index ' + index + ' but only see ' + value.length + ' entries', value);
1432 | }
1433 | var result = _Json_runHelp(decoder.b, value[index]);
1434 | return (elm$core$Result$isOk(result)) ? result : elm$core$Result$Err(A2(elm$json$Json$Decode$Index, index, result.a));
1435 |
1436 | case 12:
1437 | if (typeof value !== 'object' || value === null || Array.isArray(value))
1438 | {
1439 | return _Json_expecting('an OBJECT', value);
1440 | }
1441 |
1442 | var keyValuePairs = _List_Nil;
1443 | // TODO test perf of Object.keys and switch when support is good enough
1444 | for (var key in value)
1445 | {
1446 | if (value.hasOwnProperty(key))
1447 | {
1448 | var result = _Json_runHelp(decoder.b, value[key]);
1449 | if (!elm$core$Result$isOk(result))
1450 | {
1451 | return elm$core$Result$Err(A2(elm$json$Json$Decode$Field, key, result.a));
1452 | }
1453 | keyValuePairs = _List_Cons(_Utils_Tuple2(key, result.a), keyValuePairs);
1454 | }
1455 | }
1456 | return elm$core$Result$Ok(elm$core$List$reverse(keyValuePairs));
1457 |
1458 | case 13:
1459 | var answer = decoder.f;
1460 | var decoders = decoder.g;
1461 | for (var i = 0; i < decoders.length; i++)
1462 | {
1463 | var result = _Json_runHelp(decoders[i], value);
1464 | if (!elm$core$Result$isOk(result))
1465 | {
1466 | return result;
1467 | }
1468 | answer = answer(result.a);
1469 | }
1470 | return elm$core$Result$Ok(answer);
1471 |
1472 | case 14:
1473 | var result = _Json_runHelp(decoder.b, value);
1474 | return (!elm$core$Result$isOk(result))
1475 | ? result
1476 | : _Json_runHelp(decoder.h(result.a), value);
1477 |
1478 | case 15:
1479 | var errors = _List_Nil;
1480 | for (var temp = decoder.g; temp.b; temp = temp.b) // WHILE_CONS
1481 | {
1482 | var result = _Json_runHelp(temp.a, value);
1483 | if (elm$core$Result$isOk(result))
1484 | {
1485 | return result;
1486 | }
1487 | errors = _List_Cons(result.a, errors);
1488 | }
1489 | return elm$core$Result$Err(elm$json$Json$Decode$OneOf(elm$core$List$reverse(errors)));
1490 |
1491 | case 1:
1492 | return elm$core$Result$Err(A2(elm$json$Json$Decode$Failure, decoder.a, _Json_wrap(value)));
1493 |
1494 | case 0:
1495 | return elm$core$Result$Ok(decoder.a);
1496 | }
1497 | }
1498 |
1499 | function _Json_runArrayDecoder(decoder, value, toElmValue)
1500 | {
1501 | var len = value.length;
1502 | var array = new Array(len);
1503 | for (var i = 0; i < len; i++)
1504 | {
1505 | var result = _Json_runHelp(decoder, value[i]);
1506 | if (!elm$core$Result$isOk(result))
1507 | {
1508 | return elm$core$Result$Err(A2(elm$json$Json$Decode$Index, i, result.a));
1509 | }
1510 | array[i] = result.a;
1511 | }
1512 | return elm$core$Result$Ok(toElmValue(array));
1513 | }
1514 |
1515 | function _Json_toElmArray(array)
1516 | {
1517 | return A2(elm$core$Array$initialize, array.length, function(i) { return array[i]; });
1518 | }
1519 |
1520 | function _Json_expecting(type, value)
1521 | {
1522 | return elm$core$Result$Err(A2(elm$json$Json$Decode$Failure, 'Expecting ' + type, _Json_wrap(value)));
1523 | }
1524 |
1525 |
1526 | // EQUALITY
1527 |
1528 | function _Json_equality(x, y)
1529 | {
1530 | if (x === y)
1531 | {
1532 | return true;
1533 | }
1534 |
1535 | if (x.$ !== y.$)
1536 | {
1537 | return false;
1538 | }
1539 |
1540 | switch (x.$)
1541 | {
1542 | case 0:
1543 | case 1:
1544 | return x.a === y.a;
1545 |
1546 | case 3:
1547 | case 2:
1548 | case 4:
1549 | case 6:
1550 | case 5:
1551 | return true;
1552 |
1553 | case 9:
1554 | return x.c === y.c;
1555 |
1556 | case 7:
1557 | case 8:
1558 | case 12:
1559 | return _Json_equality(x.b, y.b);
1560 |
1561 | case 10:
1562 | return x.d === y.d && _Json_equality(x.b, y.b);
1563 |
1564 | case 11:
1565 | return x.e === y.e && _Json_equality(x.b, y.b);
1566 |
1567 | case 13:
1568 | return x.f === y.f && _Json_listEquality(x.g, y.g);
1569 |
1570 | case 14:
1571 | return x.h === y.h && _Json_equality(x.b, y.b);
1572 |
1573 | case 15:
1574 | return _Json_listEquality(x.g, y.g);
1575 | }
1576 | }
1577 |
1578 | function _Json_listEquality(aDecoders, bDecoders)
1579 | {
1580 | var len = aDecoders.length;
1581 | if (len !== bDecoders.length)
1582 | {
1583 | return false;
1584 | }
1585 | for (var i = 0; i < len; i++)
1586 | {
1587 | if (!_Json_equality(aDecoders[i], bDecoders[i]))
1588 | {
1589 | return false;
1590 | }
1591 | }
1592 | return true;
1593 | }
1594 |
1595 |
1596 | // ENCODE
1597 |
1598 | var _Json_encode = F2(function(indentLevel, value)
1599 | {
1600 | return JSON.stringify(_Json_unwrap(value), null, indentLevel) + '';
1601 | });
1602 |
1603 | function _Json_wrap(value) { return { $: 0, a: value }; }
1604 | function _Json_unwrap(value) { return value.a; }
1605 |
1606 | function _Json_wrap_UNUSED(value) { return value; }
1607 | function _Json_unwrap_UNUSED(value) { return value; }
1608 |
1609 | function _Json_emptyArray() { return []; }
1610 | function _Json_emptyObject() { return {}; }
1611 |
1612 | var _Json_addField = F3(function(key, value, object)
1613 | {
1614 | object[key] = _Json_unwrap(value);
1615 | return object;
1616 | });
1617 |
1618 | function _Json_addEntry(func)
1619 | {
1620 | return F2(function(entry, array)
1621 | {
1622 | array.push(_Json_unwrap(func(entry)));
1623 | return array;
1624 | });
1625 | }
1626 |
1627 | var _Json_encodeNull = _Json_wrap(null);
1628 |
1629 |
1630 |
1631 | // TASKS
1632 |
1633 | function _Scheduler_succeed(value)
1634 | {
1635 | return {
1636 | $: 0,
1637 | a: value
1638 | };
1639 | }
1640 |
1641 | function _Scheduler_fail(error)
1642 | {
1643 | return {
1644 | $: 1,
1645 | a: error
1646 | };
1647 | }
1648 |
1649 | function _Scheduler_binding(callback)
1650 | {
1651 | return {
1652 | $: 2,
1653 | b: callback,
1654 | c: null
1655 | };
1656 | }
1657 |
1658 | var _Scheduler_andThen = F2(function(callback, task)
1659 | {
1660 | return {
1661 | $: 3,
1662 | b: callback,
1663 | d: task
1664 | };
1665 | });
1666 |
1667 | var _Scheduler_onError = F2(function(callback, task)
1668 | {
1669 | return {
1670 | $: 4,
1671 | b: callback,
1672 | d: task
1673 | };
1674 | });
1675 |
1676 | function _Scheduler_receive(callback)
1677 | {
1678 | return {
1679 | $: 5,
1680 | b: callback
1681 | };
1682 | }
1683 |
1684 |
1685 | // PROCESSES
1686 |
1687 | var _Scheduler_guid = 0;
1688 |
1689 | function _Scheduler_rawSpawn(task)
1690 | {
1691 | var proc = {
1692 | $: 0,
1693 | e: _Scheduler_guid++,
1694 | f: task,
1695 | g: null,
1696 | h: []
1697 | };
1698 |
1699 | _Scheduler_enqueue(proc);
1700 |
1701 | return proc;
1702 | }
1703 |
1704 | function _Scheduler_spawn(task)
1705 | {
1706 | return _Scheduler_binding(function(callback) {
1707 | callback(_Scheduler_succeed(_Scheduler_rawSpawn(task)));
1708 | });
1709 | }
1710 |
1711 | function _Scheduler_rawSend(proc, msg)
1712 | {
1713 | proc.h.push(msg);
1714 | _Scheduler_enqueue(proc);
1715 | }
1716 |
1717 | var _Scheduler_send = F2(function(proc, msg)
1718 | {
1719 | return _Scheduler_binding(function(callback) {
1720 | _Scheduler_rawSend(proc, msg);
1721 | callback(_Scheduler_succeed(_Utils_Tuple0));
1722 | });
1723 | });
1724 |
1725 | function _Scheduler_kill(proc)
1726 | {
1727 | return _Scheduler_binding(function(callback) {
1728 | var task = proc.f;
1729 | if (task.$ === 2 && task.c)
1730 | {
1731 | task.c();
1732 | }
1733 |
1734 | proc.f = null;
1735 |
1736 | callback(_Scheduler_succeed(_Utils_Tuple0));
1737 | });
1738 | }
1739 |
1740 |
1741 | /* STEP PROCESSES
1742 |
1743 | type alias Process =
1744 | { $ : tag
1745 | , id : unique_id
1746 | , root : Task
1747 | , stack : null | { $: SUCCEED | FAIL, a: callback, b: stack }
1748 | , mailbox : [msg]
1749 | }
1750 |
1751 | */
1752 |
1753 |
1754 | var _Scheduler_working = false;
1755 | var _Scheduler_queue = [];
1756 |
1757 |
1758 | function _Scheduler_enqueue(proc)
1759 | {
1760 | _Scheduler_queue.push(proc);
1761 | if (_Scheduler_working)
1762 | {
1763 | return;
1764 | }
1765 | _Scheduler_working = true;
1766 | while (proc = _Scheduler_queue.shift())
1767 | {
1768 | _Scheduler_step(proc);
1769 | }
1770 | _Scheduler_working = false;
1771 | }
1772 |
1773 |
1774 | function _Scheduler_step(proc)
1775 | {
1776 | while (proc.f)
1777 | {
1778 | var rootTag = proc.f.$;
1779 | if (rootTag === 0 || rootTag === 1)
1780 | {
1781 | while (proc.g && proc.g.$ !== rootTag)
1782 | {
1783 | proc.g = proc.g.i;
1784 | }
1785 | if (!proc.g)
1786 | {
1787 | return;
1788 | }
1789 | proc.f = proc.g.b(proc.f.a);
1790 | proc.g = proc.g.i;
1791 | }
1792 | else if (rootTag === 2)
1793 | {
1794 | proc.f.c = proc.f.b(function(newRoot) {
1795 | proc.f = newRoot;
1796 | _Scheduler_enqueue(proc);
1797 | });
1798 | return;
1799 | }
1800 | else if (rootTag === 5)
1801 | {
1802 | if (proc.h.length === 0)
1803 | {
1804 | return;
1805 | }
1806 | proc.f = proc.f.b(proc.h.shift());
1807 | }
1808 | else // if (rootTag === 3 || rootTag === 4)
1809 | {
1810 | proc.g = {
1811 | $: rootTag === 3 ? 0 : 1,
1812 | b: proc.f.b,
1813 | i: proc.g
1814 | };
1815 | proc.f = proc.f.d;
1816 | }
1817 | }
1818 | }
1819 |
1820 |
1821 |
1822 | function _Process_sleep(time)
1823 | {
1824 | return _Scheduler_binding(function(callback) {
1825 | var id = setTimeout(function() {
1826 | callback(_Scheduler_succeed(_Utils_Tuple0));
1827 | }, time);
1828 |
1829 | return function() { clearTimeout(id); };
1830 | });
1831 | }
1832 |
1833 |
1834 |
1835 |
1836 | // PROGRAMS
1837 |
1838 |
1839 | var _Platform_worker = F4(function(impl, flagDecoder, debugMetadata, args)
1840 | {
1841 | return _Platform_initialize(
1842 | flagDecoder,
1843 | args,
1844 | impl.init,
1845 | impl.update,
1846 | impl.subscriptions,
1847 | function() { return function() {} }
1848 | );
1849 | });
1850 |
1851 |
1852 |
1853 | // INITIALIZE A PROGRAM
1854 |
1855 |
1856 | function _Platform_initialize(flagDecoder, args, init, update, subscriptions, stepperBuilder)
1857 | {
1858 | var result = A2(_Json_run, flagDecoder, _Json_wrap(args ? args['flags'] : undefined));
1859 | elm$core$Result$isOk(result) || _Debug_crash(2 /**/, _Json_errorToString(result.a) /**/);
1860 | var managers = {};
1861 | result = init(result.a);
1862 | var model = result.a;
1863 | var stepper = stepperBuilder(sendToApp, model);
1864 | var ports = _Platform_setupEffects(managers, sendToApp);
1865 |
1866 | function sendToApp(msg, viewMetadata)
1867 | {
1868 | result = A2(update, msg, model);
1869 | stepper(model = result.a, viewMetadata);
1870 | _Platform_dispatchEffects(managers, result.b, subscriptions(model));
1871 | }
1872 |
1873 | _Platform_dispatchEffects(managers, result.b, subscriptions(model));
1874 |
1875 | return ports ? { ports: ports } : {};
1876 | }
1877 |
1878 |
1879 |
1880 | // TRACK PRELOADS
1881 | //
1882 | // This is used by code in elm/browser and elm/http
1883 | // to register any HTTP requests that are triggered by init.
1884 | //
1885 |
1886 |
1887 | var _Platform_preload;
1888 |
1889 |
1890 | function _Platform_registerPreload(url)
1891 | {
1892 | _Platform_preload.add(url);
1893 | }
1894 |
1895 |
1896 |
1897 | // EFFECT MANAGERS
1898 |
1899 |
1900 | var _Platform_effectManagers = {};
1901 |
1902 |
1903 | function _Platform_setupEffects(managers, sendToApp)
1904 | {
1905 | var ports;
1906 |
1907 | // setup all necessary effect managers
1908 | for (var key in _Platform_effectManagers)
1909 | {
1910 | var manager = _Platform_effectManagers[key];
1911 |
1912 | if (manager.a)
1913 | {
1914 | ports = ports || {};
1915 | ports[key] = manager.a(key, sendToApp);
1916 | }
1917 |
1918 | managers[key] = _Platform_instantiateManager(manager, sendToApp);
1919 | }
1920 |
1921 | return ports;
1922 | }
1923 |
1924 |
1925 | function _Platform_createManager(init, onEffects, onSelfMsg, cmdMap, subMap)
1926 | {
1927 | return {
1928 | b: init,
1929 | c: onEffects,
1930 | d: onSelfMsg,
1931 | e: cmdMap,
1932 | f: subMap
1933 | };
1934 | }
1935 |
1936 |
1937 | function _Platform_instantiateManager(info, sendToApp)
1938 | {
1939 | var router = {
1940 | g: sendToApp,
1941 | h: undefined
1942 | };
1943 |
1944 | var onEffects = info.c;
1945 | var onSelfMsg = info.d;
1946 | var cmdMap = info.e;
1947 | var subMap = info.f;
1948 |
1949 | function loop(state)
1950 | {
1951 | return A2(_Scheduler_andThen, loop, _Scheduler_receive(function(msg)
1952 | {
1953 | var value = msg.a;
1954 |
1955 | if (msg.$ === 0)
1956 | {
1957 | return A3(onSelfMsg, router, value, state);
1958 | }
1959 |
1960 | return cmdMap && subMap
1961 | ? A4(onEffects, router, value.i, value.j, state)
1962 | : A3(onEffects, router, cmdMap ? value.i : value.j, state);
1963 | }));
1964 | }
1965 |
1966 | return router.h = _Scheduler_rawSpawn(A2(_Scheduler_andThen, loop, info.b));
1967 | }
1968 |
1969 |
1970 |
1971 | // ROUTING
1972 |
1973 |
1974 | var _Platform_sendToApp = F2(function(router, msg)
1975 | {
1976 | return _Scheduler_binding(function(callback)
1977 | {
1978 | router.g(msg);
1979 | callback(_Scheduler_succeed(_Utils_Tuple0));
1980 | });
1981 | });
1982 |
1983 |
1984 | var _Platform_sendToSelf = F2(function(router, msg)
1985 | {
1986 | return A2(_Scheduler_send, router.h, {
1987 | $: 0,
1988 | a: msg
1989 | });
1990 | });
1991 |
1992 |
1993 |
1994 | // BAGS
1995 |
1996 |
1997 | function _Platform_leaf(home)
1998 | {
1999 | return function(value)
2000 | {
2001 | return {
2002 | $: 1,
2003 | k: home,
2004 | l: value
2005 | };
2006 | };
2007 | }
2008 |
2009 |
2010 | function _Platform_batch(list)
2011 | {
2012 | return {
2013 | $: 2,
2014 | m: list
2015 | };
2016 | }
2017 |
2018 |
2019 | var _Platform_map = F2(function(tagger, bag)
2020 | {
2021 | return {
2022 | $: 3,
2023 | n: tagger,
2024 | o: bag
2025 | }
2026 | });
2027 |
2028 |
2029 |
2030 | // PIPE BAGS INTO EFFECT MANAGERS
2031 |
2032 |
2033 | function _Platform_dispatchEffects(managers, cmdBag, subBag)
2034 | {
2035 | var effectsDict = {};
2036 | _Platform_gatherEffects(true, cmdBag, effectsDict, null);
2037 | _Platform_gatherEffects(false, subBag, effectsDict, null);
2038 |
2039 | for (var home in managers)
2040 | {
2041 | _Scheduler_rawSend(managers[home], {
2042 | $: 'fx',
2043 | a: effectsDict[home] || { i: _List_Nil, j: _List_Nil }
2044 | });
2045 | }
2046 | }
2047 |
2048 |
2049 | function _Platform_gatherEffects(isCmd, bag, effectsDict, taggers)
2050 | {
2051 | switch (bag.$)
2052 | {
2053 | case 1:
2054 | var home = bag.k;
2055 | var effect = _Platform_toEffect(isCmd, home, taggers, bag.l);
2056 | effectsDict[home] = _Platform_insert(isCmd, effect, effectsDict[home]);
2057 | return;
2058 |
2059 | case 2:
2060 | for (var list = bag.m; list.b; list = list.b) // WHILE_CONS
2061 | {
2062 | _Platform_gatherEffects(isCmd, list.a, effectsDict, taggers);
2063 | }
2064 | return;
2065 |
2066 | case 3:
2067 | _Platform_gatherEffects(isCmd, bag.o, effectsDict, {
2068 | p: bag.n,
2069 | q: taggers
2070 | });
2071 | return;
2072 | }
2073 | }
2074 |
2075 |
2076 | function _Platform_toEffect(isCmd, home, taggers, value)
2077 | {
2078 | function applyTaggers(x)
2079 | {
2080 | for (var temp = taggers; temp; temp = temp.q)
2081 | {
2082 | x = temp.p(x);
2083 | }
2084 | return x;
2085 | }
2086 |
2087 | var map = isCmd
2088 | ? _Platform_effectManagers[home].e
2089 | : _Platform_effectManagers[home].f;
2090 |
2091 | return A2(map, applyTaggers, value)
2092 | }
2093 |
2094 |
2095 | function _Platform_insert(isCmd, newEffect, effects)
2096 | {
2097 | effects = effects || { i: _List_Nil, j: _List_Nil };
2098 |
2099 | isCmd
2100 | ? (effects.i = _List_Cons(newEffect, effects.i))
2101 | : (effects.j = _List_Cons(newEffect, effects.j));
2102 |
2103 | return effects;
2104 | }
2105 |
2106 |
2107 |
2108 | // PORTS
2109 |
2110 |
2111 | function _Platform_checkPortName(name)
2112 | {
2113 | if (_Platform_effectManagers[name])
2114 | {
2115 | _Debug_crash(3, name)
2116 | }
2117 | }
2118 |
2119 |
2120 |
2121 | // OUTGOING PORTS
2122 |
2123 |
2124 | function _Platform_outgoingPort(name, converter)
2125 | {
2126 | _Platform_checkPortName(name);
2127 | _Platform_effectManagers[name] = {
2128 | e: _Platform_outgoingPortMap,
2129 | r: converter,
2130 | a: _Platform_setupOutgoingPort
2131 | };
2132 | return _Platform_leaf(name);
2133 | }
2134 |
2135 |
2136 | var _Platform_outgoingPortMap = F2(function(tagger, value) { return value; });
2137 |
2138 |
2139 | function _Platform_setupOutgoingPort(name)
2140 | {
2141 | var subs = [];
2142 | var converter = _Platform_effectManagers[name].r;
2143 |
2144 | // CREATE MANAGER
2145 |
2146 | var init = _Process_sleep(0);
2147 |
2148 | _Platform_effectManagers[name].b = init;
2149 | _Platform_effectManagers[name].c = F3(function(router, cmdList, state)
2150 | {
2151 | for ( ; cmdList.b; cmdList = cmdList.b) // WHILE_CONS
2152 | {
2153 | // grab a separate reference to subs in case unsubscribe is called
2154 | var currentSubs = subs;
2155 | var value = _Json_unwrap(converter(cmdList.a));
2156 | for (var i = 0; i < currentSubs.length; i++)
2157 | {
2158 | currentSubs[i](value);
2159 | }
2160 | }
2161 | return init;
2162 | });
2163 |
2164 | // PUBLIC API
2165 |
2166 | function subscribe(callback)
2167 | {
2168 | subs.push(callback);
2169 | }
2170 |
2171 | function unsubscribe(callback)
2172 | {
2173 | // copy subs into a new array in case unsubscribe is called within a
2174 | // subscribed callback
2175 | subs = subs.slice();
2176 | var index = subs.indexOf(callback);
2177 | if (index >= 0)
2178 | {
2179 | subs.splice(index, 1);
2180 | }
2181 | }
2182 |
2183 | return {
2184 | subscribe: subscribe,
2185 | unsubscribe: unsubscribe
2186 | };
2187 | }
2188 |
2189 |
2190 |
2191 | // INCOMING PORTS
2192 |
2193 |
2194 | function _Platform_incomingPort(name, converter)
2195 | {
2196 | _Platform_checkPortName(name);
2197 | _Platform_effectManagers[name] = {
2198 | f: _Platform_incomingPortMap,
2199 | r: converter,
2200 | a: _Platform_setupIncomingPort
2201 | };
2202 | return _Platform_leaf(name);
2203 | }
2204 |
2205 |
2206 | var _Platform_incomingPortMap = F2(function(tagger, finalTagger)
2207 | {
2208 | return function(value)
2209 | {
2210 | return tagger(finalTagger(value));
2211 | };
2212 | });
2213 |
2214 |
2215 | function _Platform_setupIncomingPort(name, sendToApp)
2216 | {
2217 | var subs = _List_Nil;
2218 | var converter = _Platform_effectManagers[name].r;
2219 |
2220 | // CREATE MANAGER
2221 |
2222 | var init = _Scheduler_succeed(null);
2223 |
2224 | _Platform_effectManagers[name].b = init;
2225 | _Platform_effectManagers[name].c = F3(function(router, subList, state)
2226 | {
2227 | subs = subList;
2228 | return init;
2229 | });
2230 |
2231 | // PUBLIC API
2232 |
2233 | function send(incomingValue)
2234 | {
2235 | var result = A2(_Json_run, converter, _Json_wrap(incomingValue));
2236 |
2237 | elm$core$Result$isOk(result) || _Debug_crash(4, name, result.a);
2238 |
2239 | var value = result.a;
2240 | for (var temp = subs; temp.b; temp = temp.b) // WHILE_CONS
2241 | {
2242 | sendToApp(temp.a(value));
2243 | }
2244 | }
2245 |
2246 | return { send: send };
2247 | }
2248 |
2249 |
2250 |
2251 | // EXPORT ELM MODULES
2252 | //
2253 | // Have DEBUG and PROD versions so that we can (1) give nicer errors in
2254 | // debug mode and (2) not pay for the bits needed for that in prod mode.
2255 | //
2256 |
2257 |
2258 | function _Platform_export_UNUSED(exports)
2259 | {
2260 | scope['Elm']
2261 | ? _Platform_mergeExportsProd(scope['Elm'], exports)
2262 | : scope['Elm'] = exports;
2263 | }
2264 |
2265 |
2266 | function _Platform_mergeExportsProd(obj, exports)
2267 | {
2268 | for (var name in exports)
2269 | {
2270 | (name in obj)
2271 | ? (name == 'init')
2272 | ? _Debug_crash(6)
2273 | : _Platform_mergeExportsProd(obj[name], exports[name])
2274 | : (obj[name] = exports[name]);
2275 | }
2276 | }
2277 |
2278 |
2279 | function _Platform_export(exports)
2280 | {
2281 | scope['Elm']
2282 | ? _Platform_mergeExportsDebug('Elm', scope['Elm'], exports)
2283 | : scope['Elm'] = exports;
2284 | }
2285 |
2286 |
2287 | function _Platform_mergeExportsDebug(moduleName, obj, exports)
2288 | {
2289 | for (var name in exports)
2290 | {
2291 | (name in obj)
2292 | ? (name == 'init')
2293 | ? _Debug_crash(6, moduleName)
2294 | : _Platform_mergeExportsDebug(moduleName + '.' + name, obj[name], exports[name])
2295 | : (obj[name] = exports[name]);
2296 | }
2297 | }
2298 |
2299 |
2300 |
2301 |
2302 | // HELPERS
2303 |
2304 |
2305 | var _VirtualDom_divertHrefToApp;
2306 |
2307 | var _VirtualDom_doc = typeof document !== 'undefined' ? document : {};
2308 |
2309 |
2310 | function _VirtualDom_appendChild(parent, child)
2311 | {
2312 | parent.appendChild(child);
2313 | }
2314 |
2315 | var _VirtualDom_init = F4(function(virtualNode, flagDecoder, debugMetadata, args)
2316 | {
2317 | // NOTE: this function needs _Platform_export available to work
2318 |
2319 | /**_UNUSED/
2320 | var node = args['node'];
2321 | //*/
2322 | /**/
2323 | var node = args && args['node'] ? args['node'] : _Debug_crash(0);
2324 | //*/
2325 |
2326 | node.parentNode.replaceChild(
2327 | _VirtualDom_render(virtualNode, function() {}),
2328 | node
2329 | );
2330 |
2331 | return {};
2332 | });
2333 |
2334 |
2335 |
2336 | // TEXT
2337 |
2338 |
2339 | function _VirtualDom_text(string)
2340 | {
2341 | return {
2342 | $: 0,
2343 | a: string
2344 | };
2345 | }
2346 |
2347 |
2348 |
2349 | // NODE
2350 |
2351 |
2352 | var _VirtualDom_nodeNS = F2(function(namespace, tag)
2353 | {
2354 | return F2(function(factList, kidList)
2355 | {
2356 | for (var kids = [], descendantsCount = 0; kidList.b; kidList = kidList.b) // WHILE_CONS
2357 | {
2358 | var kid = kidList.a;
2359 | descendantsCount += (kid.b || 0);
2360 | kids.push(kid);
2361 | }
2362 | descendantsCount += kids.length;
2363 |
2364 | return {
2365 | $: 1,
2366 | c: tag,
2367 | d: _VirtualDom_organizeFacts(factList),
2368 | e: kids,
2369 | f: namespace,
2370 | b: descendantsCount
2371 | };
2372 | });
2373 | });
2374 |
2375 |
2376 | var _VirtualDom_node = _VirtualDom_nodeNS(undefined);
2377 |
2378 |
2379 |
2380 | // KEYED NODE
2381 |
2382 |
2383 | var _VirtualDom_keyedNodeNS = F2(function(namespace, tag)
2384 | {
2385 | return F2(function(factList, kidList)
2386 | {
2387 | for (var kids = [], descendantsCount = 0; kidList.b; kidList = kidList.b) // WHILE_CONS
2388 | {
2389 | var kid = kidList.a;
2390 | descendantsCount += (kid.b.b || 0);
2391 | kids.push(kid);
2392 | }
2393 | descendantsCount += kids.length;
2394 |
2395 | return {
2396 | $: 2,
2397 | c: tag,
2398 | d: _VirtualDom_organizeFacts(factList),
2399 | e: kids,
2400 | f: namespace,
2401 | b: descendantsCount
2402 | };
2403 | });
2404 | });
2405 |
2406 |
2407 | var _VirtualDom_keyedNode = _VirtualDom_keyedNodeNS(undefined);
2408 |
2409 |
2410 |
2411 | // CUSTOM
2412 |
2413 |
2414 | function _VirtualDom_custom(factList, model, render, diff)
2415 | {
2416 | return {
2417 | $: 3,
2418 | d: _VirtualDom_organizeFacts(factList),
2419 | g: model,
2420 | h: render,
2421 | i: diff
2422 | };
2423 | }
2424 |
2425 |
2426 |
2427 | // MAP
2428 |
2429 |
2430 | var _VirtualDom_map = F2(function(tagger, node)
2431 | {
2432 | return {
2433 | $: 4,
2434 | j: tagger,
2435 | k: node,
2436 | b: 1 + (node.b || 0)
2437 | };
2438 | });
2439 |
2440 |
2441 |
2442 | // LAZY
2443 |
2444 |
2445 | function _VirtualDom_thunk(refs, thunk)
2446 | {
2447 | return {
2448 | $: 5,
2449 | l: refs,
2450 | m: thunk,
2451 | k: undefined
2452 | };
2453 | }
2454 |
2455 | var _VirtualDom_lazy = F2(function(func, a)
2456 | {
2457 | return _VirtualDom_thunk([func, a], function() {
2458 | return func(a);
2459 | });
2460 | });
2461 |
2462 | var _VirtualDom_lazy2 = F3(function(func, a, b)
2463 | {
2464 | return _VirtualDom_thunk([func, a, b], function() {
2465 | return A2(func, a, b);
2466 | });
2467 | });
2468 |
2469 | var _VirtualDom_lazy3 = F4(function(func, a, b, c)
2470 | {
2471 | return _VirtualDom_thunk([func, a, b, c], function() {
2472 | return A3(func, a, b, c);
2473 | });
2474 | });
2475 |
2476 | var _VirtualDom_lazy4 = F5(function(func, a, b, c, d)
2477 | {
2478 | return _VirtualDom_thunk([func, a, b, c, d], function() {
2479 | return A4(func, a, b, c, d);
2480 | });
2481 | });
2482 |
2483 | var _VirtualDom_lazy5 = F6(function(func, a, b, c, d, e)
2484 | {
2485 | return _VirtualDom_thunk([func, a, b, c, d, e], function() {
2486 | return A5(func, a, b, c, d, e);
2487 | });
2488 | });
2489 |
2490 | var _VirtualDom_lazy6 = F7(function(func, a, b, c, d, e, f)
2491 | {
2492 | return _VirtualDom_thunk([func, a, b, c, d, e, f], function() {
2493 | return A6(func, a, b, c, d, e, f);
2494 | });
2495 | });
2496 |
2497 | var _VirtualDom_lazy7 = F8(function(func, a, b, c, d, e, f, g)
2498 | {
2499 | return _VirtualDom_thunk([func, a, b, c, d, e, f, g], function() {
2500 | return A7(func, a, b, c, d, e, f, g);
2501 | });
2502 | });
2503 |
2504 | var _VirtualDom_lazy8 = F9(function(func, a, b, c, d, e, f, g, h)
2505 | {
2506 | return _VirtualDom_thunk([func, a, b, c, d, e, f, g, h], function() {
2507 | return A8(func, a, b, c, d, e, f, g, h);
2508 | });
2509 | });
2510 |
2511 |
2512 |
2513 | // FACTS
2514 |
2515 |
2516 | var _VirtualDom_on = F2(function(key, handler)
2517 | {
2518 | return {
2519 | $: 'a0',
2520 | n: key,
2521 | o: handler
2522 | };
2523 | });
2524 | var _VirtualDom_style = F2(function(key, value)
2525 | {
2526 | return {
2527 | $: 'a1',
2528 | n: key,
2529 | o: value
2530 | };
2531 | });
2532 | var _VirtualDom_property = F2(function(key, value)
2533 | {
2534 | return {
2535 | $: 'a2',
2536 | n: key,
2537 | o: value
2538 | };
2539 | });
2540 | var _VirtualDom_attribute = F2(function(key, value)
2541 | {
2542 | return {
2543 | $: 'a3',
2544 | n: key,
2545 | o: value
2546 | };
2547 | });
2548 | var _VirtualDom_attributeNS = F3(function(namespace, key, value)
2549 | {
2550 | return {
2551 | $: 'a4',
2552 | n: key,
2553 | o: { f: namespace, o: value }
2554 | };
2555 | });
2556 |
2557 |
2558 |
2559 | // XSS ATTACK VECTOR CHECKS
2560 |
2561 |
2562 | function _VirtualDom_noScript(tag)
2563 | {
2564 | return tag == 'script' ? 'p' : tag;
2565 | }
2566 |
2567 | function _VirtualDom_noOnOrFormAction(key)
2568 | {
2569 | return /^(on|formAction$)/i.test(key) ? 'data-' + key : key;
2570 | }
2571 |
2572 | function _VirtualDom_noInnerHtmlOrFormAction(key)
2573 | {
2574 | return key == 'innerHTML' || key == 'formAction' ? 'data-' + key : key;
2575 | }
2576 |
2577 | function _VirtualDom_noJavaScriptUri_UNUSED(value)
2578 | {
2579 | return /^javascript:/i.test(value.replace(/\s/g,'')) ? '' : value;
2580 | }
2581 |
2582 | function _VirtualDom_noJavaScriptUri(value)
2583 | {
2584 | return /^javascript:/i.test(value.replace(/\s/g,''))
2585 | ? 'javascript:alert("This is an XSS vector. Please use ports or web components instead.")'
2586 | : value;
2587 | }
2588 |
2589 | function _VirtualDom_noJavaScriptOrHtmlUri_UNUSED(value)
2590 | {
2591 | return /^\s*(javascript:|data:text\/html)/i.test(value) ? '' : value;
2592 | }
2593 |
2594 | function _VirtualDom_noJavaScriptOrHtmlUri(value)
2595 | {
2596 | return /^\s*(javascript:|data:text\/html)/i.test(value)
2597 | ? 'javascript:alert("This is an XSS vector. Please use ports or web components instead.")'
2598 | : value;
2599 | }
2600 |
2601 |
2602 |
2603 | // MAP FACTS
2604 |
2605 |
2606 | var _VirtualDom_mapAttribute = F2(function(func, attr)
2607 | {
2608 | return (attr.$ === 'a0')
2609 | ? A2(_VirtualDom_on, attr.n, _VirtualDom_mapHandler(func, attr.o))
2610 | : attr;
2611 | });
2612 |
2613 | function _VirtualDom_mapHandler(func, handler)
2614 | {
2615 | var tag = elm$virtual_dom$VirtualDom$toHandlerInt(handler);
2616 |
2617 | // 0 = Normal
2618 | // 1 = MayStopPropagation
2619 | // 2 = MayPreventDefault
2620 | // 3 = Custom
2621 |
2622 | return {
2623 | $: handler.$,
2624 | a:
2625 | !tag
2626 | ? A2(elm$json$Json$Decode$map, func, handler.a)
2627 | :
2628 | A3(elm$json$Json$Decode$map2,
2629 | tag < 3
2630 | ? _VirtualDom_mapEventTuple
2631 | : _VirtualDom_mapEventRecord,
2632 | elm$json$Json$Decode$succeed(func),
2633 | handler.a
2634 | )
2635 | };
2636 | }
2637 |
2638 | var _VirtualDom_mapEventTuple = F2(function(func, tuple)
2639 | {
2640 | return _Utils_Tuple2(func(tuple.a), tuple.b);
2641 | });
2642 |
2643 | var _VirtualDom_mapEventRecord = F2(function(func, record)
2644 | {
2645 | return {
2646 | message: func(record.message),
2647 | stopPropagation: record.stopPropagation,
2648 | preventDefault: record.preventDefault
2649 | }
2650 | });
2651 |
2652 |
2653 |
2654 | // ORGANIZE FACTS
2655 |
2656 |
2657 | function _VirtualDom_organizeFacts(factList)
2658 | {
2659 | for (var facts = {}; factList.b; factList = factList.b) // WHILE_CONS
2660 | {
2661 | var entry = factList.a;
2662 |
2663 | var tag = entry.$;
2664 | var key = entry.n;
2665 | var value = entry.o;
2666 |
2667 | if (tag === 'a2')
2668 | {
2669 | (key === 'className')
2670 | ? _VirtualDom_addClass(facts, key, _Json_unwrap(value))
2671 | : facts[key] = _Json_unwrap(value);
2672 |
2673 | continue;
2674 | }
2675 |
2676 | var subFacts = facts[tag] || (facts[tag] = {});
2677 | (tag === 'a3' && key === 'class')
2678 | ? _VirtualDom_addClass(subFacts, key, value)
2679 | : subFacts[key] = value;
2680 | }
2681 |
2682 | return facts;
2683 | }
2684 |
2685 | function _VirtualDom_addClass(object, key, newClass)
2686 | {
2687 | var classes = object[key];
2688 | object[key] = classes ? classes + ' ' + newClass : newClass;
2689 | }
2690 |
2691 |
2692 |
2693 | // RENDER
2694 |
2695 |
2696 | function _VirtualDom_render(vNode, eventNode)
2697 | {
2698 | var tag = vNode.$;
2699 |
2700 | if (tag === 5)
2701 | {
2702 | return _VirtualDom_render(vNode.k || (vNode.k = vNode.m()), eventNode);
2703 | }
2704 |
2705 | if (tag === 0)
2706 | {
2707 | return _VirtualDom_doc.createTextNode(vNode.a);
2708 | }
2709 |
2710 | if (tag === 4)
2711 | {
2712 | var subNode = vNode.k;
2713 | var tagger = vNode.j;
2714 |
2715 | while (subNode.$ === 4)
2716 | {
2717 | typeof tagger !== 'object'
2718 | ? tagger = [tagger, subNode.j]
2719 | : tagger.push(subNode.j);
2720 |
2721 | subNode = subNode.k;
2722 | }
2723 |
2724 | var subEventRoot = { j: tagger, p: eventNode };
2725 | var domNode = _VirtualDom_render(subNode, subEventRoot);
2726 | domNode.elm_event_node_ref = subEventRoot;
2727 | return domNode;
2728 | }
2729 |
2730 | if (tag === 3)
2731 | {
2732 | var domNode = vNode.h(vNode.g);
2733 | _VirtualDom_applyFacts(domNode, eventNode, vNode.d);
2734 | return domNode;
2735 | }
2736 |
2737 | // at this point `tag` must be 1 or 2
2738 |
2739 | var domNode = vNode.f
2740 | ? _VirtualDom_doc.createElementNS(vNode.f, vNode.c)
2741 | : _VirtualDom_doc.createElement(vNode.c);
2742 |
2743 | if (_VirtualDom_divertHrefToApp && vNode.c == 'a')
2744 | {
2745 | domNode.addEventListener('click', _VirtualDom_divertHrefToApp(domNode));
2746 | }
2747 |
2748 | _VirtualDom_applyFacts(domNode, eventNode, vNode.d);
2749 |
2750 | for (var kids = vNode.e, i = 0; i < kids.length; i++)
2751 | {
2752 | _VirtualDom_appendChild(domNode, _VirtualDom_render(tag === 1 ? kids[i] : kids[i].b, eventNode));
2753 | }
2754 |
2755 | return domNode;
2756 | }
2757 |
2758 |
2759 |
2760 | // APPLY FACTS
2761 |
2762 |
2763 | function _VirtualDom_applyFacts(domNode, eventNode, facts)
2764 | {
2765 | for (var key in facts)
2766 | {
2767 | var value = facts[key];
2768 |
2769 | key === 'a1'
2770 | ? _VirtualDom_applyStyles(domNode, value)
2771 | :
2772 | key === 'a0'
2773 | ? _VirtualDom_applyEvents(domNode, eventNode, value)
2774 | :
2775 | key === 'a3'
2776 | ? _VirtualDom_applyAttrs(domNode, value)
2777 | :
2778 | key === 'a4'
2779 | ? _VirtualDom_applyAttrsNS(domNode, value)
2780 | :
2781 | (key !== 'value' || key !== 'checked' || domNode[key] !== value) && (domNode[key] = value);
2782 | }
2783 | }
2784 |
2785 |
2786 |
2787 | // APPLY STYLES
2788 |
2789 |
2790 | function _VirtualDom_applyStyles(domNode, styles)
2791 | {
2792 | var domNodeStyle = domNode.style;
2793 |
2794 | for (var key in styles)
2795 | {
2796 | domNodeStyle[key] = styles[key];
2797 | }
2798 | }
2799 |
2800 |
2801 |
2802 | // APPLY ATTRS
2803 |
2804 |
2805 | function _VirtualDom_applyAttrs(domNode, attrs)
2806 | {
2807 | for (var key in attrs)
2808 | {
2809 | var value = attrs[key];
2810 | value
2811 | ? domNode.setAttribute(key, value)
2812 | : domNode.removeAttribute(key);
2813 | }
2814 | }
2815 |
2816 |
2817 |
2818 | // APPLY NAMESPACED ATTRS
2819 |
2820 |
2821 | function _VirtualDom_applyAttrsNS(domNode, nsAttrs)
2822 | {
2823 | for (var key in nsAttrs)
2824 | {
2825 | var pair = nsAttrs[key];
2826 | var namespace = pair.f;
2827 | var value = pair.o;
2828 |
2829 | value
2830 | ? domNode.setAttributeNS(namespace, key, value)
2831 | : domNode.removeAttributeNS(namespace, key);
2832 | }
2833 | }
2834 |
2835 |
2836 |
2837 | // APPLY EVENTS
2838 |
2839 |
2840 | function _VirtualDom_applyEvents(domNode, eventNode, events)
2841 | {
2842 | var allCallbacks = domNode.elmFs || (domNode.elmFs = {});
2843 |
2844 | for (var key in events)
2845 | {
2846 | var newHandler = events[key];
2847 | var oldCallback = allCallbacks[key];
2848 |
2849 | if (!newHandler)
2850 | {
2851 | domNode.removeEventListener(key, oldCallback);
2852 | allCallbacks[key] = undefined;
2853 | continue;
2854 | }
2855 |
2856 | if (oldCallback)
2857 | {
2858 | var oldHandler = oldCallback.q;
2859 | if (oldHandler.$ === newHandler.$)
2860 | {
2861 | oldCallback.q = newHandler;
2862 | continue;
2863 | }
2864 | domNode.removeEventListener(key, oldCallback);
2865 | }
2866 |
2867 | oldCallback = _VirtualDom_makeCallback(eventNode, newHandler);
2868 | domNode.addEventListener(key, oldCallback,
2869 | _VirtualDom_passiveSupported
2870 | && { passive: elm$virtual_dom$VirtualDom$toHandlerInt(newHandler) < 2 }
2871 | );
2872 | allCallbacks[key] = oldCallback;
2873 | }
2874 | }
2875 |
2876 |
2877 |
2878 | // PASSIVE EVENTS
2879 |
2880 |
2881 | var _VirtualDom_passiveSupported;
2882 |
2883 | try
2884 | {
2885 | window.addEventListener('t', null, Object.defineProperty({}, 'passive', {
2886 | get: function() { _VirtualDom_passiveSupported = true; }
2887 | }));
2888 | }
2889 | catch(e) {}
2890 |
2891 |
2892 |
2893 | // EVENT HANDLERS
2894 |
2895 |
2896 | function _VirtualDom_makeCallback(eventNode, initialHandler)
2897 | {
2898 | function callback(event)
2899 | {
2900 | var handler = callback.q;
2901 | var result = _Json_runHelp(handler.a, event);
2902 |
2903 | if (!elm$core$Result$isOk(result))
2904 | {
2905 | return;
2906 | }
2907 |
2908 | var tag = elm$virtual_dom$VirtualDom$toHandlerInt(handler);
2909 |
2910 | // 0 = Normal
2911 | // 1 = MayStopPropagation
2912 | // 2 = MayPreventDefault
2913 | // 3 = Custom
2914 |
2915 | var value = result.a;
2916 | var message = !tag ? value : tag < 3 ? value.a : value.message;
2917 | var stopPropagation = tag == 1 ? value.b : tag == 3 && value.stopPropagation;
2918 | var currentEventNode = (
2919 | stopPropagation && event.stopPropagation(),
2920 | (tag == 2 ? value.b : tag == 3 && value.preventDefault) && event.preventDefault(),
2921 | eventNode
2922 | );
2923 | var tagger;
2924 | var i;
2925 | while (tagger = currentEventNode.j)
2926 | {
2927 | if (typeof tagger == 'function')
2928 | {
2929 | message = tagger(message);
2930 | }
2931 | else
2932 | {
2933 | for (var i = tagger.length; i--; )
2934 | {
2935 | message = tagger[i](message);
2936 | }
2937 | }
2938 | currentEventNode = currentEventNode.p;
2939 | }
2940 | currentEventNode(message, stopPropagation); // stopPropagation implies isSync
2941 | }
2942 |
2943 | callback.q = initialHandler;
2944 |
2945 | return callback;
2946 | }
2947 |
2948 | function _VirtualDom_equalEvents(x, y)
2949 | {
2950 | return x.$ == y.$ && _Json_equality(x.a, y.a);
2951 | }
2952 |
2953 |
2954 |
2955 | // DIFF
2956 |
2957 |
2958 | // TODO: Should we do patches like in iOS?
2959 | //
2960 | // type Patch
2961 | // = At Int Patch
2962 | // | Batch (List Patch)
2963 | // | Change ...
2964 | //
2965 | // How could it not be better?
2966 | //
2967 | function _VirtualDom_diff(x, y)
2968 | {
2969 | var patches = [];
2970 | _VirtualDom_diffHelp(x, y, patches, 0);
2971 | return patches;
2972 | }
2973 |
2974 |
2975 | function _VirtualDom_pushPatch(patches, type, index, data)
2976 | {
2977 | var patch = {
2978 | $: type,
2979 | r: index,
2980 | s: data,
2981 | t: undefined,
2982 | u: undefined
2983 | };
2984 | patches.push(patch);
2985 | return patch;
2986 | }
2987 |
2988 |
2989 | function _VirtualDom_diffHelp(x, y, patches, index)
2990 | {
2991 | if (x === y)
2992 | {
2993 | return;
2994 | }
2995 |
2996 | var xType = x.$;
2997 | var yType = y.$;
2998 |
2999 | // Bail if you run into different types of nodes. Implies that the
3000 | // structure has changed significantly and it's not worth a diff.
3001 | if (xType !== yType)
3002 | {
3003 | if (xType === 1 && yType === 2)
3004 | {
3005 | y = _VirtualDom_dekey(y);
3006 | yType = 1;
3007 | }
3008 | else
3009 | {
3010 | _VirtualDom_pushPatch(patches, 0, index, y);
3011 | return;
3012 | }
3013 | }
3014 |
3015 | // Now we know that both nodes are the same $.
3016 | switch (yType)
3017 | {
3018 | case 5:
3019 | var xRefs = x.l;
3020 | var yRefs = y.l;
3021 | var i = xRefs.length;
3022 | var same = i === yRefs.length;
3023 | while (same && i--)
3024 | {
3025 | same = xRefs[i] === yRefs[i];
3026 | }
3027 | if (same)
3028 | {
3029 | y.k = x.k;
3030 | return;
3031 | }
3032 | y.k = y.m();
3033 | var subPatches = [];
3034 | _VirtualDom_diffHelp(x.k, y.k, subPatches, 0);
3035 | subPatches.length > 0 && _VirtualDom_pushPatch(patches, 1, index, subPatches);
3036 | return;
3037 |
3038 | case 4:
3039 | // gather nested taggers
3040 | var xTaggers = x.j;
3041 | var yTaggers = y.j;
3042 | var nesting = false;
3043 |
3044 | var xSubNode = x.k;
3045 | while (xSubNode.$ === 4)
3046 | {
3047 | nesting = true;
3048 |
3049 | typeof xTaggers !== 'object'
3050 | ? xTaggers = [xTaggers, xSubNode.j]
3051 | : xTaggers.push(xSubNode.j);
3052 |
3053 | xSubNode = xSubNode.k;
3054 | }
3055 |
3056 | var ySubNode = y.k;
3057 | while (ySubNode.$ === 4)
3058 | {
3059 | nesting = true;
3060 |
3061 | typeof yTaggers !== 'object'
3062 | ? yTaggers = [yTaggers, ySubNode.j]
3063 | : yTaggers.push(ySubNode.j);
3064 |
3065 | ySubNode = ySubNode.k;
3066 | }
3067 |
3068 | // Just bail if different numbers of taggers. This implies the
3069 | // structure of the virtual DOM has changed.
3070 | if (nesting && xTaggers.length !== yTaggers.length)
3071 | {
3072 | _VirtualDom_pushPatch(patches, 0, index, y);
3073 | return;
3074 | }
3075 |
3076 | // check if taggers are "the same"
3077 | if (nesting ? !_VirtualDom_pairwiseRefEqual(xTaggers, yTaggers) : xTaggers !== yTaggers)
3078 | {
3079 | _VirtualDom_pushPatch(patches, 2, index, yTaggers);
3080 | }
3081 |
3082 | // diff everything below the taggers
3083 | _VirtualDom_diffHelp(xSubNode, ySubNode, patches, index + 1);
3084 | return;
3085 |
3086 | case 0:
3087 | if (x.a !== y.a)
3088 | {
3089 | _VirtualDom_pushPatch(patches, 3, index, y.a);
3090 | }
3091 | return;
3092 |
3093 | case 1:
3094 | _VirtualDom_diffNodes(x, y, patches, index, _VirtualDom_diffKids);
3095 | return;
3096 |
3097 | case 2:
3098 | _VirtualDom_diffNodes(x, y, patches, index, _VirtualDom_diffKeyedKids);
3099 | return;
3100 |
3101 | case 3:
3102 | if (x.h !== y.h)
3103 | {
3104 | _VirtualDom_pushPatch(patches, 0, index, y);
3105 | return;
3106 | }
3107 |
3108 | var factsDiff = _VirtualDom_diffFacts(x.d, y.d);
3109 | factsDiff && _VirtualDom_pushPatch(patches, 4, index, factsDiff);
3110 |
3111 | var patch = y.i(x.g, y.g);
3112 | patch && _VirtualDom_pushPatch(patches, 5, index, patch);
3113 |
3114 | return;
3115 | }
3116 | }
3117 |
3118 | // assumes the incoming arrays are the same length
3119 | function _VirtualDom_pairwiseRefEqual(as, bs)
3120 | {
3121 | for (var i = 0; i < as.length; i++)
3122 | {
3123 | if (as[i] !== bs[i])
3124 | {
3125 | return false;
3126 | }
3127 | }
3128 |
3129 | return true;
3130 | }
3131 |
3132 | function _VirtualDom_diffNodes(x, y, patches, index, diffKids)
3133 | {
3134 | // Bail if obvious indicators have changed. Implies more serious
3135 | // structural changes such that it's not worth it to diff.
3136 | if (x.c !== y.c || x.f !== y.f)
3137 | {
3138 | _VirtualDom_pushPatch(patches, 0, index, y);
3139 | return;
3140 | }
3141 |
3142 | var factsDiff = _VirtualDom_diffFacts(x.d, y.d);
3143 | factsDiff && _VirtualDom_pushPatch(patches, 4, index, factsDiff);
3144 |
3145 | diffKids(x, y, patches, index);
3146 | }
3147 |
3148 |
3149 |
3150 | // DIFF FACTS
3151 |
3152 |
3153 | // TODO Instead of creating a new diff object, it's possible to just test if
3154 | // there *is* a diff. During the actual patch, do the diff again and make the
3155 | // modifications directly. This way, there's no new allocations. Worth it?
3156 | function _VirtualDom_diffFacts(x, y, category)
3157 | {
3158 | var diff;
3159 |
3160 | // look for changes and removals
3161 | for (var xKey in x)
3162 | {
3163 | if (xKey === 'a1' || xKey === 'a0' || xKey === 'a3' || xKey === 'a4')
3164 | {
3165 | var subDiff = _VirtualDom_diffFacts(x[xKey], y[xKey] || {}, xKey);
3166 | if (subDiff)
3167 | {
3168 | diff = diff || {};
3169 | diff[xKey] = subDiff;
3170 | }
3171 | continue;
3172 | }
3173 |
3174 | // remove if not in the new facts
3175 | if (!(xKey in y))
3176 | {
3177 | diff = diff || {};
3178 | diff[xKey] =
3179 | !category
3180 | ? (typeof x[xKey] === 'string' ? '' : null)
3181 | :
3182 | (category === 'a1')
3183 | ? ''
3184 | :
3185 | (category === 'a0' || category === 'a3')
3186 | ? undefined
3187 | :
3188 | { f: x[xKey].f, o: undefined };
3189 |
3190 | continue;
3191 | }
3192 |
3193 | var xValue = x[xKey];
3194 | var yValue = y[xKey];
3195 |
3196 | // reference equal, so don't worry about it
3197 | if (xValue === yValue && xKey !== 'value' && xKey !== 'checked'
3198 | || category === 'a0' && _VirtualDom_equalEvents(xValue, yValue))
3199 | {
3200 | continue;
3201 | }
3202 |
3203 | diff = diff || {};
3204 | diff[xKey] = yValue;
3205 | }
3206 |
3207 | // add new stuff
3208 | for (var yKey in y)
3209 | {
3210 | if (!(yKey in x))
3211 | {
3212 | diff = diff || {};
3213 | diff[yKey] = y[yKey];
3214 | }
3215 | }
3216 |
3217 | return diff;
3218 | }
3219 |
3220 |
3221 |
3222 | // DIFF KIDS
3223 |
3224 |
3225 | function _VirtualDom_diffKids(xParent, yParent, patches, index)
3226 | {
3227 | var xKids = xParent.e;
3228 | var yKids = yParent.e;
3229 |
3230 | var xLen = xKids.length;
3231 | var yLen = yKids.length;
3232 |
3233 | // FIGURE OUT IF THERE ARE INSERTS OR REMOVALS
3234 |
3235 | if (xLen > yLen)
3236 | {
3237 | _VirtualDom_pushPatch(patches, 6, index, {
3238 | v: yLen,
3239 | i: xLen - yLen
3240 | });
3241 | }
3242 | else if (xLen < yLen)
3243 | {
3244 | _VirtualDom_pushPatch(patches, 7, index, {
3245 | v: xLen,
3246 | e: yKids
3247 | });
3248 | }
3249 |
3250 | // PAIRWISE DIFF EVERYTHING ELSE
3251 |
3252 | for (var minLen = xLen < yLen ? xLen : yLen, i = 0; i < minLen; i++)
3253 | {
3254 | var xKid = xKids[i];
3255 | _VirtualDom_diffHelp(xKid, yKids[i], patches, ++index);
3256 | index += xKid.b || 0;
3257 | }
3258 | }
3259 |
3260 |
3261 |
3262 | // KEYED DIFF
3263 |
3264 |
3265 | function _VirtualDom_diffKeyedKids(xParent, yParent, patches, rootIndex)
3266 | {
3267 | var localPatches = [];
3268 |
3269 | var changes = {}; // Dict String Entry
3270 | var inserts = []; // Array { index : Int, entry : Entry }
3271 | // type Entry = { tag : String, vnode : VNode, index : Int, data : _ }
3272 |
3273 | var xKids = xParent.e;
3274 | var yKids = yParent.e;
3275 | var xLen = xKids.length;
3276 | var yLen = yKids.length;
3277 | var xIndex = 0;
3278 | var yIndex = 0;
3279 |
3280 | var index = rootIndex;
3281 |
3282 | while (xIndex < xLen && yIndex < yLen)
3283 | {
3284 | var x = xKids[xIndex];
3285 | var y = yKids[yIndex];
3286 |
3287 | var xKey = x.a;
3288 | var yKey = y.a;
3289 | var xNode = x.b;
3290 | var yNode = y.b;
3291 |
3292 | // check if keys match
3293 |
3294 | if (xKey === yKey)
3295 | {
3296 | index++;
3297 | _VirtualDom_diffHelp(xNode, yNode, localPatches, index);
3298 | index += xNode.b || 0;
3299 |
3300 | xIndex++;
3301 | yIndex++;
3302 | continue;
3303 | }
3304 |
3305 | // look ahead 1 to detect insertions and removals.
3306 |
3307 | var xNext = xKids[xIndex + 1];
3308 | var yNext = yKids[yIndex + 1];
3309 |
3310 | if (xNext)
3311 | {
3312 | var xNextKey = xNext.a;
3313 | var xNextNode = xNext.b;
3314 | var oldMatch = yKey === xNextKey;
3315 | }
3316 |
3317 | if (yNext)
3318 | {
3319 | var yNextKey = yNext.a;
3320 | var yNextNode = yNext.b;
3321 | var newMatch = xKey === yNextKey;
3322 | }
3323 |
3324 |
3325 | // swap x and y
3326 | if (newMatch && oldMatch)
3327 | {
3328 | index++;
3329 | _VirtualDom_diffHelp(xNode, yNextNode, localPatches, index);
3330 | _VirtualDom_insertNode(changes, localPatches, xKey, yNode, yIndex, inserts);
3331 | index += xNode.b || 0;
3332 |
3333 | index++;
3334 | _VirtualDom_removeNode(changes, localPatches, xKey, xNextNode, index);
3335 | index += xNextNode.b || 0;
3336 |
3337 | xIndex += 2;
3338 | yIndex += 2;
3339 | continue;
3340 | }
3341 |
3342 | // insert y
3343 | if (newMatch)
3344 | {
3345 | index++;
3346 | _VirtualDom_insertNode(changes, localPatches, yKey, yNode, yIndex, inserts);
3347 | _VirtualDom_diffHelp(xNode, yNextNode, localPatches, index);
3348 | index += xNode.b || 0;
3349 |
3350 | xIndex += 1;
3351 | yIndex += 2;
3352 | continue;
3353 | }
3354 |
3355 | // remove x
3356 | if (oldMatch)
3357 | {
3358 | index++;
3359 | _VirtualDom_removeNode(changes, localPatches, xKey, xNode, index);
3360 | index += xNode.b || 0;
3361 |
3362 | index++;
3363 | _VirtualDom_diffHelp(xNextNode, yNode, localPatches, index);
3364 | index += xNextNode.b || 0;
3365 |
3366 | xIndex += 2;
3367 | yIndex += 1;
3368 | continue;
3369 | }
3370 |
3371 | // remove x, insert y
3372 | if (xNext && xNextKey === yNextKey)
3373 | {
3374 | index++;
3375 | _VirtualDom_removeNode(changes, localPatches, xKey, xNode, index);
3376 | _VirtualDom_insertNode(changes, localPatches, yKey, yNode, yIndex, inserts);
3377 | index += xNode.b || 0;
3378 |
3379 | index++;
3380 | _VirtualDom_diffHelp(xNextNode, yNextNode, localPatches, index);
3381 | index += xNextNode.b || 0;
3382 |
3383 | xIndex += 2;
3384 | yIndex += 2;
3385 | continue;
3386 | }
3387 |
3388 | break;
3389 | }
3390 |
3391 | // eat up any remaining nodes with removeNode and insertNode
3392 |
3393 | while (xIndex < xLen)
3394 | {
3395 | index++;
3396 | var x = xKids[xIndex];
3397 | var xNode = x.b;
3398 | _VirtualDom_removeNode(changes, localPatches, x.a, xNode, index);
3399 | index += xNode.b || 0;
3400 | xIndex++;
3401 | }
3402 |
3403 | while (yIndex < yLen)
3404 | {
3405 | var endInserts = endInserts || [];
3406 | var y = yKids[yIndex];
3407 | _VirtualDom_insertNode(changes, localPatches, y.a, y.b, undefined, endInserts);
3408 | yIndex++;
3409 | }
3410 |
3411 | if (localPatches.length > 0 || inserts.length > 0 || endInserts)
3412 | {
3413 | _VirtualDom_pushPatch(patches, 8, rootIndex, {
3414 | w: localPatches,
3415 | x: inserts,
3416 | y: endInserts
3417 | });
3418 | }
3419 | }
3420 |
3421 |
3422 |
3423 | // CHANGES FROM KEYED DIFF
3424 |
3425 |
3426 | var _VirtualDom_POSTFIX = '_elmW6BL';
3427 |
3428 |
3429 | function _VirtualDom_insertNode(changes, localPatches, key, vnode, yIndex, inserts)
3430 | {
3431 | var entry = changes[key];
3432 |
3433 | // never seen this key before
3434 | if (!entry)
3435 | {
3436 | entry = {
3437 | c: 0,
3438 | z: vnode,
3439 | r: yIndex,
3440 | s: undefined
3441 | };
3442 |
3443 | inserts.push({ r: yIndex, A: entry });
3444 | changes[key] = entry;
3445 |
3446 | return;
3447 | }
3448 |
3449 | // this key was removed earlier, a match!
3450 | if (entry.c === 1)
3451 | {
3452 | inserts.push({ r: yIndex, A: entry });
3453 |
3454 | entry.c = 2;
3455 | var subPatches = [];
3456 | _VirtualDom_diffHelp(entry.z, vnode, subPatches, entry.r);
3457 | entry.r = yIndex;
3458 | entry.s.s = {
3459 | w: subPatches,
3460 | A: entry
3461 | };
3462 |
3463 | return;
3464 | }
3465 |
3466 | // this key has already been inserted or moved, a duplicate!
3467 | _VirtualDom_insertNode(changes, localPatches, key + _VirtualDom_POSTFIX, vnode, yIndex, inserts);
3468 | }
3469 |
3470 |
3471 | function _VirtualDom_removeNode(changes, localPatches, key, vnode, index)
3472 | {
3473 | var entry = changes[key];
3474 |
3475 | // never seen this key before
3476 | if (!entry)
3477 | {
3478 | var patch = _VirtualDom_pushPatch(localPatches, 9, index, undefined);
3479 |
3480 | changes[key] = {
3481 | c: 1,
3482 | z: vnode,
3483 | r: index,
3484 | s: patch
3485 | };
3486 |
3487 | return;
3488 | }
3489 |
3490 | // this key was inserted earlier, a match!
3491 | if (entry.c === 0)
3492 | {
3493 | entry.c = 2;
3494 | var subPatches = [];
3495 | _VirtualDom_diffHelp(vnode, entry.z, subPatches, index);
3496 |
3497 | _VirtualDom_pushPatch(localPatches, 9, index, {
3498 | w: subPatches,
3499 | A: entry
3500 | });
3501 |
3502 | return;
3503 | }
3504 |
3505 | // this key has already been removed or moved, a duplicate!
3506 | _VirtualDom_removeNode(changes, localPatches, key + _VirtualDom_POSTFIX, vnode, index);
3507 | }
3508 |
3509 |
3510 |
3511 | // ADD DOM NODES
3512 | //
3513 | // Each DOM node has an "index" assigned in order of traversal. It is important
3514 | // to minimize our crawl over the actual DOM, so these indexes (along with the
3515 | // descendantsCount of virtual nodes) let us skip touching entire subtrees of
3516 | // the DOM if we know there are no patches there.
3517 |
3518 |
3519 | function _VirtualDom_addDomNodes(domNode, vNode, patches, eventNode)
3520 | {
3521 | _VirtualDom_addDomNodesHelp(domNode, vNode, patches, 0, 0, vNode.b, eventNode);
3522 | }
3523 |
3524 |
3525 | // assumes `patches` is non-empty and indexes increase monotonically.
3526 | function _VirtualDom_addDomNodesHelp(domNode, vNode, patches, i, low, high, eventNode)
3527 | {
3528 | var patch = patches[i];
3529 | var index = patch.r;
3530 |
3531 | while (index === low)
3532 | {
3533 | var patchType = patch.$;
3534 |
3535 | if (patchType === 1)
3536 | {
3537 | _VirtualDom_addDomNodes(domNode, vNode.k, patch.s, eventNode);
3538 | }
3539 | else if (patchType === 8)
3540 | {
3541 | patch.t = domNode;
3542 | patch.u = eventNode;
3543 |
3544 | var subPatches = patch.s.w;
3545 | if (subPatches.length > 0)
3546 | {
3547 | _VirtualDom_addDomNodesHelp(domNode, vNode, subPatches, 0, low, high, eventNode);
3548 | }
3549 | }
3550 | else if (patchType === 9)
3551 | {
3552 | patch.t = domNode;
3553 | patch.u = eventNode;
3554 |
3555 | var data = patch.s;
3556 | if (data)
3557 | {
3558 | data.A.s = domNode;
3559 | var subPatches = data.w;
3560 | if (subPatches.length > 0)
3561 | {
3562 | _VirtualDom_addDomNodesHelp(domNode, vNode, subPatches, 0, low, high, eventNode);
3563 | }
3564 | }
3565 | }
3566 | else
3567 | {
3568 | patch.t = domNode;
3569 | patch.u = eventNode;
3570 | }
3571 |
3572 | i++;
3573 |
3574 | if (!(patch = patches[i]) || (index = patch.r) > high)
3575 | {
3576 | return i;
3577 | }
3578 | }
3579 |
3580 | var tag = vNode.$;
3581 |
3582 | if (tag === 4)
3583 | {
3584 | var subNode = vNode.k;
3585 |
3586 | while (subNode.$ === 4)
3587 | {
3588 | subNode = subNode.k;
3589 | }
3590 |
3591 | return _VirtualDom_addDomNodesHelp(domNode, subNode, patches, i, low + 1, high, domNode.elm_event_node_ref);
3592 | }
3593 |
3594 | // tag must be 1 or 2 at this point
3595 |
3596 | var vKids = vNode.e;
3597 | var childNodes = domNode.childNodes;
3598 | for (var j = 0; j < vKids.length; j++)
3599 | {
3600 | low++;
3601 | var vKid = tag === 1 ? vKids[j] : vKids[j].b;
3602 | var nextLow = low + (vKid.b || 0);
3603 | if (low <= index && index <= nextLow)
3604 | {
3605 | i = _VirtualDom_addDomNodesHelp(childNodes[j], vKid, patches, i, low, nextLow, eventNode);
3606 | if (!(patch = patches[i]) || (index = patch.r) > high)
3607 | {
3608 | return i;
3609 | }
3610 | }
3611 | low = nextLow;
3612 | }
3613 | return i;
3614 | }
3615 |
3616 |
3617 |
3618 | // APPLY PATCHES
3619 |
3620 |
3621 | function _VirtualDom_applyPatches(rootDomNode, oldVirtualNode, patches, eventNode)
3622 | {
3623 | if (patches.length === 0)
3624 | {
3625 | return rootDomNode;
3626 | }
3627 |
3628 | _VirtualDom_addDomNodes(rootDomNode, oldVirtualNode, patches, eventNode);
3629 | return _VirtualDom_applyPatchesHelp(rootDomNode, patches);
3630 | }
3631 |
3632 | function _VirtualDom_applyPatchesHelp(rootDomNode, patches)
3633 | {
3634 | for (var i = 0; i < patches.length; i++)
3635 | {
3636 | var patch = patches[i];
3637 | var localDomNode = patch.t
3638 | var newNode = _VirtualDom_applyPatch(localDomNode, patch);
3639 | if (localDomNode === rootDomNode)
3640 | {
3641 | rootDomNode = newNode;
3642 | }
3643 | }
3644 | return rootDomNode;
3645 | }
3646 |
3647 | function _VirtualDom_applyPatch(domNode, patch)
3648 | {
3649 | switch (patch.$)
3650 | {
3651 | case 0:
3652 | return _VirtualDom_applyPatchRedraw(domNode, patch.s, patch.u);
3653 |
3654 | case 4:
3655 | _VirtualDom_applyFacts(domNode, patch.u, patch.s);
3656 | return domNode;
3657 |
3658 | case 3:
3659 | domNode.replaceData(0, domNode.length, patch.s);
3660 | return domNode;
3661 |
3662 | case 1:
3663 | return _VirtualDom_applyPatchesHelp(domNode, patch.s);
3664 |
3665 | case 2:
3666 | if (domNode.elm_event_node_ref)
3667 | {
3668 | domNode.elm_event_node_ref.j = patch.s;
3669 | }
3670 | else
3671 | {
3672 | domNode.elm_event_node_ref = { j: patch.s, p: patch.u };
3673 | }
3674 | return domNode;
3675 |
3676 | case 6:
3677 | var data = patch.s;
3678 | for (var i = 0; i < data.i; i++)
3679 | {
3680 | domNode.removeChild(domNode.childNodes[data.v]);
3681 | }
3682 | return domNode;
3683 |
3684 | case 7:
3685 | var data = patch.s;
3686 | var kids = data.e;
3687 | var i = data.v;
3688 | var theEnd = domNode.childNodes[i];
3689 | for (; i < kids.length; i++)
3690 | {
3691 | domNode.insertBefore(_VirtualDom_render(kids[i], patch.u), theEnd);
3692 | }
3693 | return domNode;
3694 |
3695 | case 9:
3696 | var data = patch.s;
3697 | if (!data)
3698 | {
3699 | domNode.parentNode.removeChild(domNode);
3700 | return domNode;
3701 | }
3702 | var entry = data.A;
3703 | if (typeof entry.r !== 'undefined')
3704 | {
3705 | domNode.parentNode.removeChild(domNode);
3706 | }
3707 | entry.s = _VirtualDom_applyPatchesHelp(domNode, data.w);
3708 | return domNode;
3709 |
3710 | case 8:
3711 | return _VirtualDom_applyPatchReorder(domNode, patch);
3712 |
3713 | case 5:
3714 | return patch.s(domNode);
3715 |
3716 | default:
3717 | _Debug_crash(10); // 'Ran into an unknown patch!'
3718 | }
3719 | }
3720 |
3721 |
3722 | function _VirtualDom_applyPatchRedraw(domNode, vNode, eventNode)
3723 | {
3724 | var parentNode = domNode.parentNode;
3725 | var newNode = _VirtualDom_render(vNode, eventNode);
3726 |
3727 | if (!newNode.elm_event_node_ref)
3728 | {
3729 | newNode.elm_event_node_ref = domNode.elm_event_node_ref;
3730 | }
3731 |
3732 | if (parentNode && newNode !== domNode)
3733 | {
3734 | parentNode.replaceChild(newNode, domNode);
3735 | }
3736 | return newNode;
3737 | }
3738 |
3739 |
3740 | function _VirtualDom_applyPatchReorder(domNode, patch)
3741 | {
3742 | var data = patch.s;
3743 |
3744 | // remove end inserts
3745 | var frag = _VirtualDom_applyPatchReorderEndInsertsHelp(data.y, patch);
3746 |
3747 | // removals
3748 | domNode = _VirtualDom_applyPatchesHelp(domNode, data.w);
3749 |
3750 | // inserts
3751 | var inserts = data.x;
3752 | for (var i = 0; i < inserts.length; i++)
3753 | {
3754 | var insert = inserts[i];
3755 | var entry = insert.A;
3756 | var node = entry.c === 2
3757 | ? entry.s
3758 | : _VirtualDom_render(entry.z, patch.u);
3759 | domNode.insertBefore(node, domNode.childNodes[insert.r]);
3760 | }
3761 |
3762 | // add end inserts
3763 | if (frag)
3764 | {
3765 | _VirtualDom_appendChild(domNode, frag);
3766 | }
3767 |
3768 | return domNode;
3769 | }
3770 |
3771 |
3772 | function _VirtualDom_applyPatchReorderEndInsertsHelp(endInserts, patch)
3773 | {
3774 | if (!endInserts)
3775 | {
3776 | return;
3777 | }
3778 |
3779 | var frag = _VirtualDom_doc.createDocumentFragment();
3780 | for (var i = 0; i < endInserts.length; i++)
3781 | {
3782 | var insert = endInserts[i];
3783 | var entry = insert.A;
3784 | _VirtualDom_appendChild(frag, entry.c === 2
3785 | ? entry.s
3786 | : _VirtualDom_render(entry.z, patch.u)
3787 | );
3788 | }
3789 | return frag;
3790 | }
3791 |
3792 |
3793 | function _VirtualDom_virtualize(node)
3794 | {
3795 | // TEXT NODES
3796 |
3797 | if (node.nodeType === 3)
3798 | {
3799 | return _VirtualDom_text(node.textContent);
3800 | }
3801 |
3802 |
3803 | // WEIRD NODES
3804 |
3805 | if (node.nodeType !== 1)
3806 | {
3807 | return _VirtualDom_text('');
3808 | }
3809 |
3810 |
3811 | // ELEMENT NODES
3812 |
3813 | var attrList = _List_Nil;
3814 | var attrs = node.attributes;
3815 | for (var i = attrs.length; i--; )
3816 | {
3817 | var attr = attrs[i];
3818 | var name = attr.name;
3819 | var value = attr.value;
3820 | attrList = _List_Cons( A2(_VirtualDom_attribute, name, value), attrList );
3821 | }
3822 |
3823 | var tag = node.tagName.toLowerCase();
3824 | var kidList = _List_Nil;
3825 | var kids = node.childNodes;
3826 |
3827 | for (var i = kids.length; i--; )
3828 | {
3829 | kidList = _List_Cons(_VirtualDom_virtualize(kids[i]), kidList);
3830 | }
3831 | return A3(_VirtualDom_node, tag, attrList, kidList);
3832 | }
3833 |
3834 | function _VirtualDom_dekey(keyedNode)
3835 | {
3836 | var keyedKids = keyedNode.e;
3837 | var len = keyedKids.length;
3838 | var kids = new Array(len);
3839 | for (var i = 0; i < len; i++)
3840 | {
3841 | kids[i] = keyedKids[i].b;
3842 | }
3843 |
3844 | return {
3845 | $: 1,
3846 | c: keyedNode.c,
3847 | d: keyedNode.d,
3848 | e: kids,
3849 | f: keyedNode.f,
3850 | b: keyedNode.b
3851 | };
3852 | }
3853 |
3854 |
3855 |
3856 | // ELEMENT
3857 |
3858 |
3859 | var _Debugger_element;
3860 |
3861 | var _Browser_element = _Debugger_element || F4(function(impl, flagDecoder, debugMetadata, args)
3862 | {
3863 | return _Platform_initialize(
3864 | flagDecoder,
3865 | args,
3866 | impl.init,
3867 | impl.update,
3868 | impl.subscriptions,
3869 | function(sendToApp, initialModel) {
3870 | var view = impl.view;
3871 | /**_UNUSED/
3872 | var domNode = args['node'];
3873 | //*/
3874 | /**/
3875 | var domNode = args && args['node'] ? args['node'] : _Debug_crash(0);
3876 | //*/
3877 | var currNode = _VirtualDom_virtualize(domNode);
3878 |
3879 | return _Browser_makeAnimator(initialModel, function(model)
3880 | {
3881 | var nextNode = view(model);
3882 | var patches = _VirtualDom_diff(currNode, nextNode);
3883 | domNode = _VirtualDom_applyPatches(domNode, currNode, patches, sendToApp);
3884 | currNode = nextNode;
3885 | });
3886 | }
3887 | );
3888 | });
3889 |
3890 |
3891 |
3892 | // DOCUMENT
3893 |
3894 |
3895 | var _Debugger_document;
3896 |
3897 | var _Browser_document = _Debugger_document || F4(function(impl, flagDecoder, debugMetadata, args)
3898 | {
3899 | return _Platform_initialize(
3900 | flagDecoder,
3901 | args,
3902 | impl.init,
3903 | impl.update,
3904 | impl.subscriptions,
3905 | function(sendToApp, initialModel) {
3906 | var divertHrefToApp = impl.setup && impl.setup(sendToApp)
3907 | var view = impl.view;
3908 | var title = _VirtualDom_doc.title;
3909 | var bodyNode = _VirtualDom_doc.body;
3910 | var currNode = _VirtualDom_virtualize(bodyNode);
3911 | return _Browser_makeAnimator(initialModel, function(model)
3912 | {
3913 | _VirtualDom_divertHrefToApp = divertHrefToApp;
3914 | var doc = view(model);
3915 | var nextNode = _VirtualDom_node('body')(_List_Nil)(doc.body);
3916 | var patches = _VirtualDom_diff(currNode, nextNode);
3917 | bodyNode = _VirtualDom_applyPatches(bodyNode, currNode, patches, sendToApp);
3918 | currNode = nextNode;
3919 | _VirtualDom_divertHrefToApp = 0;
3920 | (title !== doc.title) && (_VirtualDom_doc.title = title = doc.title);
3921 | });
3922 | }
3923 | );
3924 | });
3925 |
3926 |
3927 |
3928 | // ANIMATION
3929 |
3930 |
3931 | var _Browser_requestAnimationFrame =
3932 | typeof requestAnimationFrame !== 'undefined'
3933 | ? requestAnimationFrame
3934 | : function(callback) { setTimeout(callback, 1000 / 60); };
3935 |
3936 |
3937 | function _Browser_makeAnimator(model, draw)
3938 | {
3939 | draw(model);
3940 |
3941 | var state = 0;
3942 |
3943 | function updateIfNeeded()
3944 | {
3945 | state = state === 1
3946 | ? 0
3947 | : ( _Browser_requestAnimationFrame(updateIfNeeded), draw(model), 1 );
3948 | }
3949 |
3950 | return function(nextModel, isSync)
3951 | {
3952 | model = nextModel;
3953 |
3954 | isSync
3955 | ? ( draw(model),
3956 | state === 2 && (state = 1)
3957 | )
3958 | : ( state === 0 && _Browser_requestAnimationFrame(updateIfNeeded),
3959 | state = 2
3960 | );
3961 | };
3962 | }
3963 |
3964 |
3965 |
3966 | // APPLICATION
3967 |
3968 |
3969 | function _Browser_application(impl)
3970 | {
3971 | var onUrlChange = impl.onUrlChange;
3972 | var onUrlRequest = impl.onUrlRequest;
3973 | var key = function() { key.a(onUrlChange(_Browser_getUrl())); };
3974 |
3975 | return _Browser_document({
3976 | setup: function(sendToApp)
3977 | {
3978 | key.a = sendToApp;
3979 | _Browser_window.addEventListener('popstate', key);
3980 | _Browser_window.navigator.userAgent.indexOf('Trident') < 0 || _Browser_window.addEventListener('hashchange', key);
3981 |
3982 | return F2(function(domNode, event)
3983 | {
3984 | if (!event.ctrlKey && !event.metaKey && !event.shiftKey && event.button < 1 && !domNode.target && !domNode.download)
3985 | {
3986 | event.preventDefault();
3987 | var href = domNode.href;
3988 | var curr = _Browser_getUrl();
3989 | var next = elm$url$Url$fromString(href).a;
3990 | sendToApp(onUrlRequest(
3991 | (next
3992 | && curr.protocol === next.protocol
3993 | && curr.host === next.host
3994 | && curr.port_.a === next.port_.a
3995 | )
3996 | ? elm$browser$Browser$Internal(next)
3997 | : elm$browser$Browser$External(href)
3998 | ));
3999 | }
4000 | });
4001 | },
4002 | init: function(flags)
4003 | {
4004 | return A3(impl.init, flags, _Browser_getUrl(), key);
4005 | },
4006 | view: impl.view,
4007 | update: impl.update,
4008 | subscriptions: impl.subscriptions
4009 | });
4010 | }
4011 |
4012 | function _Browser_getUrl()
4013 | {
4014 | return elm$url$Url$fromString(_VirtualDom_doc.location.href).a || _Debug_crash(1);
4015 | }
4016 |
4017 | var _Browser_go = F2(function(key, n)
4018 | {
4019 | return A2(elm$core$Task$perform, elm$core$Basics$never, _Scheduler_binding(function() {
4020 | n && history.go(n);
4021 | key();
4022 | }));
4023 | });
4024 |
4025 | var _Browser_pushUrl = F2(function(key, url)
4026 | {
4027 | return A2(elm$core$Task$perform, elm$core$Basics$never, _Scheduler_binding(function() {
4028 | history.pushState({}, '', url);
4029 | key();
4030 | }));
4031 | });
4032 |
4033 | var _Browser_replaceUrl = F2(function(key, url)
4034 | {
4035 | return A2(elm$core$Task$perform, elm$core$Basics$never, _Scheduler_binding(function() {
4036 | history.replaceState({}, '', url);
4037 | key();
4038 | }));
4039 | });
4040 |
4041 |
4042 |
4043 | // GLOBAL EVENTS
4044 |
4045 |
4046 | var _Browser_fakeNode = { addEventListener: function() {}, removeEventListener: function() {} };
4047 | var _Browser_doc = typeof document !== 'undefined' ? document : _Browser_fakeNode;
4048 | var _Browser_window = typeof window !== 'undefined' ? window : _Browser_fakeNode;
4049 |
4050 | var _Browser_on = F3(function(node, eventName, sendToSelf)
4051 | {
4052 | return _Scheduler_spawn(_Scheduler_binding(function(callback)
4053 | {
4054 | function handler(event) { _Scheduler_rawSpawn(sendToSelf(event)); }
4055 | node.addEventListener(eventName, handler, _VirtualDom_passiveSupported && { passive: true });
4056 | return function() { node.removeEventListener(eventName, handler); };
4057 | }));
4058 | });
4059 |
4060 | var _Browser_decodeEvent = F2(function(decoder, event)
4061 | {
4062 | var result = _Json_runHelp(decoder, event);
4063 | return elm$core$Result$isOk(result) ? elm$core$Maybe$Just(result.a) : elm$core$Maybe$Nothing;
4064 | });
4065 |
4066 |
4067 |
4068 | // PAGE VISIBILITY
4069 |
4070 |
4071 | function _Browser_visibilityInfo()
4072 | {
4073 | return (typeof _VirtualDom_doc.hidden !== 'undefined')
4074 | ? { hidden: 'hidden', change: 'visibilitychange' }
4075 | :
4076 | (typeof _VirtualDom_doc.mozHidden !== 'undefined')
4077 | ? { hidden: 'mozHidden', change: 'mozvisibilitychange' }
4078 | :
4079 | (typeof _VirtualDom_doc.msHidden !== 'undefined')
4080 | ? { hidden: 'msHidden', change: 'msvisibilitychange' }
4081 | :
4082 | (typeof _VirtualDom_doc.webkitHidden !== 'undefined')
4083 | ? { hidden: 'webkitHidden', change: 'webkitvisibilitychange' }
4084 | : { hidden: 'hidden', change: 'visibilitychange' };
4085 | }
4086 |
4087 |
4088 |
4089 | // ANIMATION FRAMES
4090 |
4091 |
4092 | function _Browser_rAF()
4093 | {
4094 | return _Scheduler_binding(function(callback)
4095 | {
4096 | var id = requestAnimationFrame(function() {
4097 | callback(_Scheduler_succeed(Date.now()));
4098 | });
4099 |
4100 | return function() {
4101 | cancelAnimationFrame(id);
4102 | };
4103 | });
4104 | }
4105 |
4106 |
4107 | function _Browser_now()
4108 | {
4109 | return _Scheduler_binding(function(callback)
4110 | {
4111 | callback(_Scheduler_succeed(Date.now()));
4112 | });
4113 | }
4114 |
4115 |
4116 |
4117 | // DOM STUFF
4118 |
4119 |
4120 | function _Browser_withNode(id, doStuff)
4121 | {
4122 | return _Scheduler_binding(function(callback)
4123 | {
4124 | _Browser_requestAnimationFrame(function() {
4125 | var node = document.getElementById(id);
4126 | callback(node
4127 | ? _Scheduler_succeed(doStuff(node))
4128 | : _Scheduler_fail(elm$browser$Browser$Dom$NotFound(id))
4129 | );
4130 | });
4131 | });
4132 | }
4133 |
4134 |
4135 | function _Browser_withWindow(doStuff)
4136 | {
4137 | return _Scheduler_binding(function(callback)
4138 | {
4139 | _Browser_requestAnimationFrame(function() {
4140 | callback(_Scheduler_succeed(doStuff()));
4141 | });
4142 | });
4143 | }
4144 |
4145 |
4146 | // FOCUS and BLUR
4147 |
4148 |
4149 | var _Browser_call = F2(function(functionName, id)
4150 | {
4151 | return _Browser_withNode(id, function(node) {
4152 | node[functionName]();
4153 | return _Utils_Tuple0;
4154 | });
4155 | });
4156 |
4157 |
4158 |
4159 | // WINDOW VIEWPORT
4160 |
4161 |
4162 | function _Browser_getViewport()
4163 | {
4164 | return {
4165 | scene: _Browser_getScene(),
4166 | viewport: {
4167 | x: _Browser_window.pageXOffset,
4168 | y: _Browser_window.pageYOffset,
4169 | width: _Browser_doc.documentElement.clientWidth,
4170 | height: _Browser_doc.documentElement.clientHeight
4171 | }
4172 | };
4173 | }
4174 |
4175 | function _Browser_getScene()
4176 | {
4177 | var body = _Browser_doc.body;
4178 | var elem = _Browser_doc.documentElement;
4179 | return {
4180 | width: Math.max(body.scrollWidth, body.offsetWidth, elem.scrollWidth, elem.offsetWidth, elem.clientWidth),
4181 | height: Math.max(body.scrollHeight, body.offsetHeight, elem.scrollHeight, elem.offsetHeight, elem.clientHeight)
4182 | };
4183 | }
4184 |
4185 | var _Browser_setViewport = F2(function(x, y)
4186 | {
4187 | return _Browser_withWindow(function()
4188 | {
4189 | _Browser_window.scroll(x, y);
4190 | return _Utils_Tuple0;
4191 | });
4192 | });
4193 |
4194 |
4195 |
4196 | // ELEMENT VIEWPORT
4197 |
4198 |
4199 | function _Browser_getViewportOf(id)
4200 | {
4201 | return _Browser_withNode(id, function(node)
4202 | {
4203 | return {
4204 | scene: {
4205 | width: node.scrollWidth,
4206 | height: node.scrollHeight
4207 | },
4208 | viewport: {
4209 | x: node.scrollLeft,
4210 | y: node.scrollTop,
4211 | width: node.clientWidth,
4212 | height: node.clientHeight
4213 | }
4214 | };
4215 | });
4216 | }
4217 |
4218 |
4219 | var _Browser_setViewportOf = F3(function(id, x, y)
4220 | {
4221 | return _Browser_withNode(id, function(node)
4222 | {
4223 | node.scrollLeft = x;
4224 | node.scrollTop = y;
4225 | return _Utils_Tuple0;
4226 | });
4227 | });
4228 |
4229 |
4230 |
4231 | // ELEMENT
4232 |
4233 |
4234 | function _Browser_getElement(id)
4235 | {
4236 | return _Browser_withNode(id, function(node)
4237 | {
4238 | var rect = node.getBoundingClientRect();
4239 | var x = _Browser_window.pageXOffset;
4240 | var y = _Browser_window.pageYOffset;
4241 | return {
4242 | scene: _Browser_getScene(),
4243 | viewport: {
4244 | x: x,
4245 | y: y,
4246 | width: _Browser_doc.documentElement.clientWidth,
4247 | height: _Browser_doc.documentElement.clientHeight
4248 | },
4249 | element: {
4250 | x: x + rect.left,
4251 | y: y + rect.top,
4252 | width: rect.width,
4253 | height: rect.height
4254 | }
4255 | };
4256 | });
4257 | }
4258 |
4259 |
4260 |
4261 | // LOAD and RELOAD
4262 |
4263 |
4264 | function _Browser_reload(skipCache)
4265 | {
4266 | return A2(elm$core$Task$perform, elm$core$Basics$never, _Scheduler_binding(function(callback)
4267 | {
4268 | _VirtualDom_doc.location.reload(skipCache);
4269 | }));
4270 | }
4271 |
4272 | function _Browser_load(url)
4273 | {
4274 | return A2(elm$core$Task$perform, elm$core$Basics$never, _Scheduler_binding(function(callback)
4275 | {
4276 | try
4277 | {
4278 | _Browser_window.location = url;
4279 | }
4280 | catch(err)
4281 | {
4282 | // Only Firefox can throw a NS_ERROR_MALFORMED_URI exception here.
4283 | // Other browsers reload the page, so let's be consistent about that.
4284 | _VirtualDom_doc.location.reload(false);
4285 | }
4286 | }));
4287 | }
4288 | var author$project$Configs$lightGray = 'rgb(238, 238, 238)';
4289 | var author$project$Configs$white = 'rgb(255, 255, 255)';
4290 | var author$project$ContextMenu$Arrow = {$: 'Arrow'};
4291 | var author$project$ContextMenu$Mirror = {$: 'Mirror'};
4292 | var author$project$ContextMenu$RightBottom = {$: 'RightBottom'};
4293 | var author$project$ContextMenu$Shift = {$: 'Shift'};
4294 | var author$project$ContextMenu$Pointer = {$: 'Pointer'};
4295 | var elm$core$Basics$False = {$: 'False'};
4296 | var author$project$ContextMenu$defaultConfig = {containerColor: 'white', cursor: author$project$ContextMenu$Pointer, direction: author$project$ContextMenu$RightBottom, fontFamily: 'initial', hoverColor: 'rgb(240 240 240)', invertText: false, overflowX: author$project$ContextMenu$Mirror, overflowY: author$project$ContextMenu$Mirror, rounded: false, width: 300};
4297 | var author$project$Configs$winChrome = _Utils_update(
4298 | author$project$ContextMenu$defaultConfig,
4299 | {containerColor: author$project$Configs$white, cursor: author$project$ContextMenu$Arrow, direction: author$project$ContextMenu$RightBottom, hoverColor: author$project$Configs$lightGray, invertText: false, overflowX: author$project$ContextMenu$Shift, overflowY: author$project$ContextMenu$Mirror, rounded: false});
4300 | var author$project$ContextMenu$ContextMenu = function (a) {
4301 | return {$: 'ContextMenu', a: a};
4302 | };
4303 | var elm$core$Basics$identity = function (x) {
4304 | return x;
4305 | };
4306 | var elm$core$Maybe$Nothing = {$: 'Nothing'};
4307 | var elm$core$Basics$True = {$: 'True'};
4308 | var elm$core$Result$isOk = function (result) {
4309 | if (result.$ === 'Ok') {
4310 | return true;
4311 | } else {
4312 | return false;
4313 | }
4314 | };
4315 | var elm$core$Basics$EQ = {$: 'EQ'};
4316 | var elm$core$Basics$GT = {$: 'GT'};
4317 | var elm$core$Basics$LT = {$: 'LT'};
4318 | var elm$core$Dict$foldr = F3(
4319 | function (func, acc, t) {
4320 | foldr:
4321 | while (true) {
4322 | if (t.$ === 'RBEmpty_elm_builtin') {
4323 | return acc;
4324 | } else {
4325 | var key = t.b;
4326 | var value = t.c;
4327 | var left = t.d;
4328 | var right = t.e;
4329 | var $temp$func = func,
4330 | $temp$acc = A3(
4331 | func,
4332 | key,
4333 | value,
4334 | A3(elm$core$Dict$foldr, func, acc, right)),
4335 | $temp$t = left;
4336 | func = $temp$func;
4337 | acc = $temp$acc;
4338 | t = $temp$t;
4339 | continue foldr;
4340 | }
4341 | }
4342 | });
4343 | var elm$core$List$cons = _List_cons;
4344 | var elm$core$Dict$toList = function (dict) {
4345 | return A3(
4346 | elm$core$Dict$foldr,
4347 | F3(
4348 | function (key, value, list) {
4349 | return A2(
4350 | elm$core$List$cons,
4351 | _Utils_Tuple2(key, value),
4352 | list);
4353 | }),
4354 | _List_Nil,
4355 | dict);
4356 | };
4357 | var elm$core$Dict$keys = function (dict) {
4358 | return A3(
4359 | elm$core$Dict$foldr,
4360 | F3(
4361 | function (key, value, keyList) {
4362 | return A2(elm$core$List$cons, key, keyList);
4363 | }),
4364 | _List_Nil,
4365 | dict);
4366 | };
4367 | var elm$core$Set$toList = function (_n0) {
4368 | var dict = _n0.a;
4369 | return elm$core$Dict$keys(dict);
4370 | };
4371 | var elm$core$Elm$JsArray$foldr = _JsArray_foldr;
4372 | var elm$core$Array$foldr = F3(
4373 | function (func, baseCase, _n0) {
4374 | var tree = _n0.c;
4375 | var tail = _n0.d;
4376 | var helper = F2(
4377 | function (node, acc) {
4378 | if (node.$ === 'SubTree') {
4379 | var subTree = node.a;
4380 | return A3(elm$core$Elm$JsArray$foldr, helper, acc, subTree);
4381 | } else {
4382 | var values = node.a;
4383 | return A3(elm$core$Elm$JsArray$foldr, func, acc, values);
4384 | }
4385 | });
4386 | return A3(
4387 | elm$core$Elm$JsArray$foldr,
4388 | helper,
4389 | A3(elm$core$Elm$JsArray$foldr, func, baseCase, tail),
4390 | tree);
4391 | });
4392 | var elm$core$Array$toList = function (array) {
4393 | return A3(elm$core$Array$foldr, elm$core$List$cons, _List_Nil, array);
4394 | };
4395 | var elm$core$Array$branchFactor = 32;
4396 | var elm$core$Array$Array_elm_builtin = F4(
4397 | function (a, b, c, d) {
4398 | return {$: 'Array_elm_builtin', a: a, b: b, c: c, d: d};
4399 | });
4400 | var elm$core$Basics$ceiling = _Basics_ceiling;
4401 | var elm$core$Basics$fdiv = _Basics_fdiv;
4402 | var elm$core$Basics$logBase = F2(
4403 | function (base, number) {
4404 | return _Basics_log(number) / _Basics_log(base);
4405 | });
4406 | var elm$core$Basics$toFloat = _Basics_toFloat;
4407 | var elm$core$Array$shiftStep = elm$core$Basics$ceiling(
4408 | A2(elm$core$Basics$logBase, 2, elm$core$Array$branchFactor));
4409 | var elm$core$Elm$JsArray$empty = _JsArray_empty;
4410 | var elm$core$Array$empty = A4(elm$core$Array$Array_elm_builtin, 0, elm$core$Array$shiftStep, elm$core$Elm$JsArray$empty, elm$core$Elm$JsArray$empty);
4411 | var elm$core$Array$Leaf = function (a) {
4412 | return {$: 'Leaf', a: a};
4413 | };
4414 | var elm$core$Array$SubTree = function (a) {
4415 | return {$: 'SubTree', a: a};
4416 | };
4417 | var elm$core$Elm$JsArray$initializeFromList = _JsArray_initializeFromList;
4418 | var elm$core$List$foldl = F3(
4419 | function (func, acc, list) {
4420 | foldl:
4421 | while (true) {
4422 | if (!list.b) {
4423 | return acc;
4424 | } else {
4425 | var x = list.a;
4426 | var xs = list.b;
4427 | var $temp$func = func,
4428 | $temp$acc = A2(func, x, acc),
4429 | $temp$list = xs;
4430 | func = $temp$func;
4431 | acc = $temp$acc;
4432 | list = $temp$list;
4433 | continue foldl;
4434 | }
4435 | }
4436 | });
4437 | var elm$core$List$reverse = function (list) {
4438 | return A3(elm$core$List$foldl, elm$core$List$cons, _List_Nil, list);
4439 | };
4440 | var elm$core$Array$compressNodes = F2(
4441 | function (nodes, acc) {
4442 | compressNodes:
4443 | while (true) {
4444 | var _n0 = A2(elm$core$Elm$JsArray$initializeFromList, elm$core$Array$branchFactor, nodes);
4445 | var node = _n0.a;
4446 | var remainingNodes = _n0.b;
4447 | var newAcc = A2(
4448 | elm$core$List$cons,
4449 | elm$core$Array$SubTree(node),
4450 | acc);
4451 | if (!remainingNodes.b) {
4452 | return elm$core$List$reverse(newAcc);
4453 | } else {
4454 | var $temp$nodes = remainingNodes,
4455 | $temp$acc = newAcc;
4456 | nodes = $temp$nodes;
4457 | acc = $temp$acc;
4458 | continue compressNodes;
4459 | }
4460 | }
4461 | });
4462 | var elm$core$Basics$apR = F2(
4463 | function (x, f) {
4464 | return f(x);
4465 | });
4466 | var elm$core$Basics$eq = _Utils_equal;
4467 | var elm$core$Tuple$first = function (_n0) {
4468 | var x = _n0.a;
4469 | return x;
4470 | };
4471 | var elm$core$Array$treeFromBuilder = F2(
4472 | function (nodeList, nodeListSize) {
4473 | treeFromBuilder:
4474 | while (true) {
4475 | var newNodeSize = elm$core$Basics$ceiling(nodeListSize / elm$core$Array$branchFactor);
4476 | if (newNodeSize === 1) {
4477 | return A2(elm$core$Elm$JsArray$initializeFromList, elm$core$Array$branchFactor, nodeList).a;
4478 | } else {
4479 | var $temp$nodeList = A2(elm$core$Array$compressNodes, nodeList, _List_Nil),
4480 | $temp$nodeListSize = newNodeSize;
4481 | nodeList = $temp$nodeList;
4482 | nodeListSize = $temp$nodeListSize;
4483 | continue treeFromBuilder;
4484 | }
4485 | }
4486 | });
4487 | var elm$core$Basics$add = _Basics_add;
4488 | var elm$core$Basics$apL = F2(
4489 | function (f, x) {
4490 | return f(x);
4491 | });
4492 | var elm$core$Basics$floor = _Basics_floor;
4493 | var elm$core$Basics$gt = _Utils_gt;
4494 | var elm$core$Basics$max = F2(
4495 | function (x, y) {
4496 | return (_Utils_cmp(x, y) > 0) ? x : y;
4497 | });
4498 | var elm$core$Basics$mul = _Basics_mul;
4499 | var elm$core$Basics$sub = _Basics_sub;
4500 | var elm$core$Elm$JsArray$length = _JsArray_length;
4501 | var elm$core$Array$builderToArray = F2(
4502 | function (reverseNodeList, builder) {
4503 | if (!builder.nodeListSize) {
4504 | return A4(
4505 | elm$core$Array$Array_elm_builtin,
4506 | elm$core$Elm$JsArray$length(builder.tail),
4507 | elm$core$Array$shiftStep,
4508 | elm$core$Elm$JsArray$empty,
4509 | builder.tail);
4510 | } else {
4511 | var treeLen = builder.nodeListSize * elm$core$Array$branchFactor;
4512 | var depth = elm$core$Basics$floor(
4513 | A2(elm$core$Basics$logBase, elm$core$Array$branchFactor, treeLen - 1));
4514 | var correctNodeList = reverseNodeList ? elm$core$List$reverse(builder.nodeList) : builder.nodeList;
4515 | var tree = A2(elm$core$Array$treeFromBuilder, correctNodeList, builder.nodeListSize);
4516 | return A4(
4517 | elm$core$Array$Array_elm_builtin,
4518 | elm$core$Elm$JsArray$length(builder.tail) + treeLen,
4519 | A2(elm$core$Basics$max, 5, depth * elm$core$Array$shiftStep),
4520 | tree,
4521 | builder.tail);
4522 | }
4523 | });
4524 | var elm$core$Basics$idiv = _Basics_idiv;
4525 | var elm$core$Basics$lt = _Utils_lt;
4526 | var elm$core$Elm$JsArray$initialize = _JsArray_initialize;
4527 | var elm$core$Array$initializeHelp = F5(
4528 | function (fn, fromIndex, len, nodeList, tail) {
4529 | initializeHelp:
4530 | while (true) {
4531 | if (fromIndex < 0) {
4532 | return A2(
4533 | elm$core$Array$builderToArray,
4534 | false,
4535 | {nodeList: nodeList, nodeListSize: (len / elm$core$Array$branchFactor) | 0, tail: tail});
4536 | } else {
4537 | var leaf = elm$core$Array$Leaf(
4538 | A3(elm$core$Elm$JsArray$initialize, elm$core$Array$branchFactor, fromIndex, fn));
4539 | var $temp$fn = fn,
4540 | $temp$fromIndex = fromIndex - elm$core$Array$branchFactor,
4541 | $temp$len = len,
4542 | $temp$nodeList = A2(elm$core$List$cons, leaf, nodeList),
4543 | $temp$tail = tail;
4544 | fn = $temp$fn;
4545 | fromIndex = $temp$fromIndex;
4546 | len = $temp$len;
4547 | nodeList = $temp$nodeList;
4548 | tail = $temp$tail;
4549 | continue initializeHelp;
4550 | }
4551 | }
4552 | });
4553 | var elm$core$Basics$le = _Utils_le;
4554 | var elm$core$Basics$remainderBy = _Basics_remainderBy;
4555 | var elm$core$Array$initialize = F2(
4556 | function (len, fn) {
4557 | if (len <= 0) {
4558 | return elm$core$Array$empty;
4559 | } else {
4560 | var tailLen = len % elm$core$Array$branchFactor;
4561 | var tail = A3(elm$core$Elm$JsArray$initialize, tailLen, len - tailLen, fn);
4562 | var initialFromIndex = (len - tailLen) - elm$core$Array$branchFactor;
4563 | return A5(elm$core$Array$initializeHelp, fn, initialFromIndex, len, _List_Nil, tail);
4564 | }
4565 | });
4566 | var elm$core$Maybe$Just = function (a) {
4567 | return {$: 'Just', a: a};
4568 | };
4569 | var elm$core$Result$Err = function (a) {
4570 | return {$: 'Err', a: a};
4571 | };
4572 | var elm$core$Result$Ok = function (a) {
4573 | return {$: 'Ok', a: a};
4574 | };
4575 | var elm$json$Json$Decode$Failure = F2(
4576 | function (a, b) {
4577 | return {$: 'Failure', a: a, b: b};
4578 | });
4579 | var elm$json$Json$Decode$Field = F2(
4580 | function (a, b) {
4581 | return {$: 'Field', a: a, b: b};
4582 | });
4583 | var elm$json$Json$Decode$Index = F2(
4584 | function (a, b) {
4585 | return {$: 'Index', a: a, b: b};
4586 | });
4587 | var elm$json$Json$Decode$OneOf = function (a) {
4588 | return {$: 'OneOf', a: a};
4589 | };
4590 | var elm$core$Basics$and = _Basics_and;
4591 | var elm$core$Basics$append = _Utils_append;
4592 | var elm$core$Basics$or = _Basics_or;
4593 | var elm$core$Char$toCode = _Char_toCode;
4594 | var elm$core$Char$isLower = function (_char) {
4595 | var code = elm$core$Char$toCode(_char);
4596 | return (97 <= code) && (code <= 122);
4597 | };
4598 | var elm$core$Char$isUpper = function (_char) {
4599 | var code = elm$core$Char$toCode(_char);
4600 | return (code <= 90) && (65 <= code);
4601 | };
4602 | var elm$core$Char$isAlpha = function (_char) {
4603 | return elm$core$Char$isLower(_char) || elm$core$Char$isUpper(_char);
4604 | };
4605 | var elm$core$Char$isDigit = function (_char) {
4606 | var code = elm$core$Char$toCode(_char);
4607 | return (code <= 57) && (48 <= code);
4608 | };
4609 | var elm$core$Char$isAlphaNum = function (_char) {
4610 | return elm$core$Char$isLower(_char) || (elm$core$Char$isUpper(_char) || elm$core$Char$isDigit(_char));
4611 | };
4612 | var elm$core$List$length = function (xs) {
4613 | return A3(
4614 | elm$core$List$foldl,
4615 | F2(
4616 | function (_n0, i) {
4617 | return i + 1;
4618 | }),
4619 | 0,
4620 | xs);
4621 | };
4622 | var elm$core$List$map2 = _List_map2;
4623 | var elm$core$List$rangeHelp = F3(
4624 | function (lo, hi, list) {
4625 | rangeHelp:
4626 | while (true) {
4627 | if (_Utils_cmp(lo, hi) < 1) {
4628 | var $temp$lo = lo,
4629 | $temp$hi = hi - 1,
4630 | $temp$list = A2(elm$core$List$cons, hi, list);
4631 | lo = $temp$lo;
4632 | hi = $temp$hi;
4633 | list = $temp$list;
4634 | continue rangeHelp;
4635 | } else {
4636 | return list;
4637 | }
4638 | }
4639 | });
4640 | var elm$core$List$range = F2(
4641 | function (lo, hi) {
4642 | return A3(elm$core$List$rangeHelp, lo, hi, _List_Nil);
4643 | });
4644 | var elm$core$List$indexedMap = F2(
4645 | function (f, xs) {
4646 | return A3(
4647 | elm$core$List$map2,
4648 | f,
4649 | A2(
4650 | elm$core$List$range,
4651 | 0,
4652 | elm$core$List$length(xs) - 1),
4653 | xs);
4654 | });
4655 | var elm$core$String$all = _String_all;
4656 | var elm$core$String$fromInt = _String_fromNumber;
4657 | var elm$core$String$join = F2(
4658 | function (sep, chunks) {
4659 | return A2(
4660 | _String_join,
4661 | sep,
4662 | _List_toArray(chunks));
4663 | });
4664 | var elm$core$String$uncons = _String_uncons;
4665 | var elm$core$String$split = F2(
4666 | function (sep, string) {
4667 | return _List_fromArray(
4668 | A2(_String_split, sep, string));
4669 | });
4670 | var elm$json$Json$Decode$indent = function (str) {
4671 | return A2(
4672 | elm$core$String$join,
4673 | '\n ',
4674 | A2(elm$core$String$split, '\n', str));
4675 | };
4676 | var elm$json$Json$Encode$encode = _Json_encode;
4677 | var elm$json$Json$Decode$errorOneOf = F2(
4678 | function (i, error) {
4679 | return '\n\n(' + (elm$core$String$fromInt(i + 1) + (') ' + elm$json$Json$Decode$indent(
4680 | elm$json$Json$Decode$errorToString(error))));
4681 | });
4682 | var elm$json$Json$Decode$errorToString = function (error) {
4683 | return A2(elm$json$Json$Decode$errorToStringHelp, error, _List_Nil);
4684 | };
4685 | var elm$json$Json$Decode$errorToStringHelp = F2(
4686 | function (error, context) {
4687 | errorToStringHelp:
4688 | while (true) {
4689 | switch (error.$) {
4690 | case 'Field':
4691 | var f = error.a;
4692 | var err = error.b;
4693 | var isSimple = function () {
4694 | var _n1 = elm$core$String$uncons(f);
4695 | if (_n1.$ === 'Nothing') {
4696 | return false;
4697 | } else {
4698 | var _n2 = _n1.a;
4699 | var _char = _n2.a;
4700 | var rest = _n2.b;
4701 | return elm$core$Char$isAlpha(_char) && A2(elm$core$String$all, elm$core$Char$isAlphaNum, rest);
4702 | }
4703 | }();
4704 | var fieldName = isSimple ? ('.' + f) : ('[\'' + (f + '\']'));
4705 | var $temp$error = err,
4706 | $temp$context = A2(elm$core$List$cons, fieldName, context);
4707 | error = $temp$error;
4708 | context = $temp$context;
4709 | continue errorToStringHelp;
4710 | case 'Index':
4711 | var i = error.a;
4712 | var err = error.b;
4713 | var indexName = '[' + (elm$core$String$fromInt(i) + ']');
4714 | var $temp$error = err,
4715 | $temp$context = A2(elm$core$List$cons, indexName, context);
4716 | error = $temp$error;
4717 | context = $temp$context;
4718 | continue errorToStringHelp;
4719 | case 'OneOf':
4720 | var errors = error.a;
4721 | if (!errors.b) {
4722 | return 'Ran into a Json.Decode.oneOf with no possibilities' + function () {
4723 | if (!context.b) {
4724 | return '!';
4725 | } else {
4726 | return ' at json' + A2(
4727 | elm$core$String$join,
4728 | '',
4729 | elm$core$List$reverse(context));
4730 | }
4731 | }();
4732 | } else {
4733 | if (!errors.b.b) {
4734 | var err = errors.a;
4735 | var $temp$error = err,
4736 | $temp$context = context;
4737 | error = $temp$error;
4738 | context = $temp$context;
4739 | continue errorToStringHelp;
4740 | } else {
4741 | var starter = function () {
4742 | if (!context.b) {
4743 | return 'Json.Decode.oneOf';
4744 | } else {
4745 | return 'The Json.Decode.oneOf at json' + A2(
4746 | elm$core$String$join,
4747 | '',
4748 | elm$core$List$reverse(context));
4749 | }
4750 | }();
4751 | var introduction = starter + (' failed in the following ' + (elm$core$String$fromInt(
4752 | elm$core$List$length(errors)) + ' ways:'));
4753 | return A2(
4754 | elm$core$String$join,
4755 | '\n\n',
4756 | A2(
4757 | elm$core$List$cons,
4758 | introduction,
4759 | A2(elm$core$List$indexedMap, elm$json$Json$Decode$errorOneOf, errors)));
4760 | }
4761 | }
4762 | default:
4763 | var msg = error.a;
4764 | var json = error.b;
4765 | var introduction = function () {
4766 | if (!context.b) {
4767 | return 'Problem with the given value:\n\n';
4768 | } else {
4769 | return 'Problem with the value at json' + (A2(
4770 | elm$core$String$join,
4771 | '',
4772 | elm$core$List$reverse(context)) + ':\n\n ');
4773 | }
4774 | }();
4775 | return introduction + (elm$json$Json$Decode$indent(
4776 | A2(elm$json$Json$Encode$encode, 4, json)) + ('\n\n' + msg));
4777 | }
4778 | }
4779 | });
4780 | var elm$core$Platform$Cmd$batch = _Platform_batch;
4781 | var elm$core$Platform$Cmd$none = elm$core$Platform$Cmd$batch(_List_Nil);
4782 | var author$project$ContextMenu$init = _Utils_Tuple2(
4783 | author$project$ContextMenu$ContextMenu(
4784 | {closeOnDehover: false, openState: elm$core$Maybe$Nothing}),
4785 | elm$core$Platform$Cmd$none);
4786 | var author$project$Main$ContextMenuMsg = function (a) {
4787 | return {$: 'ContextMenuMsg', a: a};
4788 | };
4789 | var elm$core$Platform$Cmd$map = _Platform_map;
4790 | var author$project$Main$init = function (_n0) {
4791 | var _n1 = author$project$ContextMenu$init;
4792 | var contextMenu = _n1.a;
4793 | var msg = _n1.b;
4794 | return _Utils_Tuple2(
4795 | {config: author$project$Configs$winChrome, contextMenu: contextMenu, message: ''},
4796 | A2(elm$core$Platform$Cmd$map, author$project$Main$ContextMenuMsg, msg));
4797 | };
4798 | var author$project$ContextMenu$Close = {$: 'Close'};
4799 | var author$project$ContextMenu$Container = {$: 'Container'};
4800 | var elm$core$Basics$neq = _Utils_notEqual;
4801 | var author$project$ContextMenu$shouldCloseOnClick = F2(
4802 | function (closeOnDehover, openState) {
4803 | if (openState.$ === 'Just') {
4804 | var hover = openState.a.hover;
4805 | return closeOnDehover ? false : (!_Utils_eq(hover, author$project$ContextMenu$Container));
4806 | } else {
4807 | return true;
4808 | }
4809 | });
4810 | var elm$browser$Browser$Events$Document = {$: 'Document'};
4811 | var elm$browser$Browser$Events$MySub = F3(
4812 | function (a, b, c) {
4813 | return {$: 'MySub', a: a, b: b, c: c};
4814 | });
4815 | var elm$browser$Browser$Events$State = F2(
4816 | function (subs, pids) {
4817 | return {pids: pids, subs: subs};
4818 | });
4819 | var elm$core$Dict$RBEmpty_elm_builtin = {$: 'RBEmpty_elm_builtin'};
4820 | var elm$core$Dict$empty = elm$core$Dict$RBEmpty_elm_builtin;
4821 | var elm$core$Task$succeed = _Scheduler_succeed;
4822 | var elm$browser$Browser$Events$init = elm$core$Task$succeed(
4823 | A2(elm$browser$Browser$Events$State, _List_Nil, elm$core$Dict$empty));
4824 | var elm$browser$Browser$Events$nodeToKey = function (node) {
4825 | if (node.$ === 'Document') {
4826 | return 'd_';
4827 | } else {
4828 | return 'w_';
4829 | }
4830 | };
4831 | var elm$browser$Browser$Events$addKey = function (sub) {
4832 | var node = sub.a;
4833 | var name = sub.b;
4834 | return _Utils_Tuple2(
4835 | _Utils_ap(
4836 | elm$browser$Browser$Events$nodeToKey(node),
4837 | name),
4838 | sub);
4839 | };
4840 | var elm$browser$Browser$Events$Event = F2(
4841 | function (key, event) {
4842 | return {event: event, key: key};
4843 | });
4844 | var elm$core$Platform$sendToSelf = _Platform_sendToSelf;
4845 | var elm$core$Task$andThen = _Scheduler_andThen;
4846 | var elm$core$Task$map = F2(
4847 | function (func, taskA) {
4848 | return A2(
4849 | elm$core$Task$andThen,
4850 | function (a) {
4851 | return elm$core$Task$succeed(
4852 | func(a));
4853 | },
4854 | taskA);
4855 | });
4856 | var elm$browser$Browser$External = function (a) {
4857 | return {$: 'External', a: a};
4858 | };
4859 | var elm$browser$Browser$Internal = function (a) {
4860 | return {$: 'Internal', a: a};
4861 | };
4862 | var elm$browser$Browser$Dom$NotFound = function (a) {
4863 | return {$: 'NotFound', a: a};
4864 | };
4865 | var elm$core$Basics$never = function (_n0) {
4866 | never:
4867 | while (true) {
4868 | var nvr = _n0.a;
4869 | var $temp$_n0 = nvr;
4870 | _n0 = $temp$_n0;
4871 | continue never;
4872 | }
4873 | };
4874 | var elm$core$Task$Perform = function (a) {
4875 | return {$: 'Perform', a: a};
4876 | };
4877 | var elm$core$Task$init = elm$core$Task$succeed(_Utils_Tuple0);
4878 | var elm$core$List$foldrHelper = F4(
4879 | function (fn, acc, ctr, ls) {
4880 | if (!ls.b) {
4881 | return acc;
4882 | } else {
4883 | var a = ls.a;
4884 | var r1 = ls.b;
4885 | if (!r1.b) {
4886 | return A2(fn, a, acc);
4887 | } else {
4888 | var b = r1.a;
4889 | var r2 = r1.b;
4890 | if (!r2.b) {
4891 | return A2(
4892 | fn,
4893 | a,
4894 | A2(fn, b, acc));
4895 | } else {
4896 | var c = r2.a;
4897 | var r3 = r2.b;
4898 | if (!r3.b) {
4899 | return A2(
4900 | fn,
4901 | a,
4902 | A2(
4903 | fn,
4904 | b,
4905 | A2(fn, c, acc)));
4906 | } else {
4907 | var d = r3.a;
4908 | var r4 = r3.b;
4909 | var res = (ctr > 500) ? A3(
4910 | elm$core$List$foldl,
4911 | fn,
4912 | acc,
4913 | elm$core$List$reverse(r4)) : A4(elm$core$List$foldrHelper, fn, acc, ctr + 1, r4);
4914 | return A2(
4915 | fn,
4916 | a,
4917 | A2(
4918 | fn,
4919 | b,
4920 | A2(
4921 | fn,
4922 | c,
4923 | A2(fn, d, res))));
4924 | }
4925 | }
4926 | }
4927 | }
4928 | });
4929 | var elm$core$List$foldr = F3(
4930 | function (fn, acc, ls) {
4931 | return A4(elm$core$List$foldrHelper, fn, acc, 0, ls);
4932 | });
4933 | var elm$core$List$map = F2(
4934 | function (f, xs) {
4935 | return A3(
4936 | elm$core$List$foldr,
4937 | F2(
4938 | function (x, acc) {
4939 | return A2(
4940 | elm$core$List$cons,
4941 | f(x),
4942 | acc);
4943 | }),
4944 | _List_Nil,
4945 | xs);
4946 | });
4947 | var elm$core$Task$map2 = F3(
4948 | function (func, taskA, taskB) {
4949 | return A2(
4950 | elm$core$Task$andThen,
4951 | function (a) {
4952 | return A2(
4953 | elm$core$Task$andThen,
4954 | function (b) {
4955 | return elm$core$Task$succeed(
4956 | A2(func, a, b));
4957 | },
4958 | taskB);
4959 | },
4960 | taskA);
4961 | });
4962 | var elm$core$Task$sequence = function (tasks) {
4963 | return A3(
4964 | elm$core$List$foldr,
4965 | elm$core$Task$map2(elm$core$List$cons),
4966 | elm$core$Task$succeed(_List_Nil),
4967 | tasks);
4968 | };
4969 | var elm$core$Platform$sendToApp = _Platform_sendToApp;
4970 | var elm$core$Task$spawnCmd = F2(
4971 | function (router, _n0) {
4972 | var task = _n0.a;
4973 | return _Scheduler_spawn(
4974 | A2(
4975 | elm$core$Task$andThen,
4976 | elm$core$Platform$sendToApp(router),
4977 | task));
4978 | });
4979 | var elm$core$Task$onEffects = F3(
4980 | function (router, commands, state) {
4981 | return A2(
4982 | elm$core$Task$map,
4983 | function (_n0) {
4984 | return _Utils_Tuple0;
4985 | },
4986 | elm$core$Task$sequence(
4987 | A2(
4988 | elm$core$List$map,
4989 | elm$core$Task$spawnCmd(router),
4990 | commands)));
4991 | });
4992 | var elm$core$Task$onSelfMsg = F3(
4993 | function (_n0, _n1, _n2) {
4994 | return elm$core$Task$succeed(_Utils_Tuple0);
4995 | });
4996 | var elm$core$Task$cmdMap = F2(
4997 | function (tagger, _n0) {
4998 | var task = _n0.a;
4999 | return elm$core$Task$Perform(
5000 | A2(elm$core$Task$map, tagger, task));
5001 | });
5002 | _Platform_effectManagers['Task'] = _Platform_createManager(elm$core$Task$init, elm$core$Task$onEffects, elm$core$Task$onSelfMsg, elm$core$Task$cmdMap);
5003 | var elm$core$Task$command = _Platform_leaf('Task');
5004 | var elm$core$Task$perform = F2(
5005 | function (toMessage, task) {
5006 | return elm$core$Task$command(
5007 | elm$core$Task$Perform(
5008 | A2(elm$core$Task$map, toMessage, task)));
5009 | });
5010 | var elm$json$Json$Decode$map = _Json_map1;
5011 | var elm$json$Json$Decode$map2 = _Json_map2;
5012 | var elm$json$Json$Decode$succeed = _Json_succeed;
5013 | var elm$virtual_dom$VirtualDom$toHandlerInt = function (handler) {
5014 | switch (handler.$) {
5015 | case 'Normal':
5016 | return 0;
5017 | case 'MayStopPropagation':
5018 | return 1;
5019 | case 'MayPreventDefault':
5020 | return 2;
5021 | default:
5022 | return 3;
5023 | }
5024 | };
5025 | var elm$core$String$length = _String_length;
5026 | var elm$core$String$slice = _String_slice;
5027 | var elm$core$String$dropLeft = F2(
5028 | function (n, string) {
5029 | return (n < 1) ? string : A3(
5030 | elm$core$String$slice,
5031 | n,
5032 | elm$core$String$length(string),
5033 | string);
5034 | });
5035 | var elm$core$String$startsWith = _String_startsWith;
5036 | var elm$url$Url$Http = {$: 'Http'};
5037 | var elm$url$Url$Https = {$: 'Https'};
5038 | var elm$core$String$indexes = _String_indexes;
5039 | var elm$core$String$isEmpty = function (string) {
5040 | return string === '';
5041 | };
5042 | var elm$core$String$left = F2(
5043 | function (n, string) {
5044 | return (n < 1) ? '' : A3(elm$core$String$slice, 0, n, string);
5045 | });
5046 | var elm$core$String$contains = _String_contains;
5047 | var elm$core$String$toInt = _String_toInt;
5048 | var elm$url$Url$Url = F6(
5049 | function (protocol, host, port_, path, query, fragment) {
5050 | return {fragment: fragment, host: host, path: path, port_: port_, protocol: protocol, query: query};
5051 | });
5052 | var elm$url$Url$chompBeforePath = F5(
5053 | function (protocol, path, params, frag, str) {
5054 | if (elm$core$String$isEmpty(str) || A2(elm$core$String$contains, '@', str)) {
5055 | return elm$core$Maybe$Nothing;
5056 | } else {
5057 | var _n0 = A2(elm$core$String$indexes, ':', str);
5058 | if (!_n0.b) {
5059 | return elm$core$Maybe$Just(
5060 | A6(elm$url$Url$Url, protocol, str, elm$core$Maybe$Nothing, path, params, frag));
5061 | } else {
5062 | if (!_n0.b.b) {
5063 | var i = _n0.a;
5064 | var _n1 = elm$core$String$toInt(
5065 | A2(elm$core$String$dropLeft, i + 1, str));
5066 | if (_n1.$ === 'Nothing') {
5067 | return elm$core$Maybe$Nothing;
5068 | } else {
5069 | var port_ = _n1;
5070 | return elm$core$Maybe$Just(
5071 | A6(
5072 | elm$url$Url$Url,
5073 | protocol,
5074 | A2(elm$core$String$left, i, str),
5075 | port_,
5076 | path,
5077 | params,
5078 | frag));
5079 | }
5080 | } else {
5081 | return elm$core$Maybe$Nothing;
5082 | }
5083 | }
5084 | }
5085 | });
5086 | var elm$url$Url$chompBeforeQuery = F4(
5087 | function (protocol, params, frag, str) {
5088 | if (elm$core$String$isEmpty(str)) {
5089 | return elm$core$Maybe$Nothing;
5090 | } else {
5091 | var _n0 = A2(elm$core$String$indexes, '/', str);
5092 | if (!_n0.b) {
5093 | return A5(elm$url$Url$chompBeforePath, protocol, '/', params, frag, str);
5094 | } else {
5095 | var i = _n0.a;
5096 | return A5(
5097 | elm$url$Url$chompBeforePath,
5098 | protocol,
5099 | A2(elm$core$String$dropLeft, i, str),
5100 | params,
5101 | frag,
5102 | A2(elm$core$String$left, i, str));
5103 | }
5104 | }
5105 | });
5106 | var elm$url$Url$chompBeforeFragment = F3(
5107 | function (protocol, frag, str) {
5108 | if (elm$core$String$isEmpty(str)) {
5109 | return elm$core$Maybe$Nothing;
5110 | } else {
5111 | var _n0 = A2(elm$core$String$indexes, '?', str);
5112 | if (!_n0.b) {
5113 | return A4(elm$url$Url$chompBeforeQuery, protocol, elm$core$Maybe$Nothing, frag, str);
5114 | } else {
5115 | var i = _n0.a;
5116 | return A4(
5117 | elm$url$Url$chompBeforeQuery,
5118 | protocol,
5119 | elm$core$Maybe$Just(
5120 | A2(elm$core$String$dropLeft, i + 1, str)),
5121 | frag,
5122 | A2(elm$core$String$left, i, str));
5123 | }
5124 | }
5125 | });
5126 | var elm$url$Url$chompAfterProtocol = F2(
5127 | function (protocol, str) {
5128 | if (elm$core$String$isEmpty(str)) {
5129 | return elm$core$Maybe$Nothing;
5130 | } else {
5131 | var _n0 = A2(elm$core$String$indexes, '#', str);
5132 | if (!_n0.b) {
5133 | return A3(elm$url$Url$chompBeforeFragment, protocol, elm$core$Maybe$Nothing, str);
5134 | } else {
5135 | var i = _n0.a;
5136 | return A3(
5137 | elm$url$Url$chompBeforeFragment,
5138 | protocol,
5139 | elm$core$Maybe$Just(
5140 | A2(elm$core$String$dropLeft, i + 1, str)),
5141 | A2(elm$core$String$left, i, str));
5142 | }
5143 | }
5144 | });
5145 | var elm$url$Url$fromString = function (str) {
5146 | return A2(elm$core$String$startsWith, 'http://', str) ? A2(
5147 | elm$url$Url$chompAfterProtocol,
5148 | elm$url$Url$Http,
5149 | A2(elm$core$String$dropLeft, 7, str)) : (A2(elm$core$String$startsWith, 'https://', str) ? A2(
5150 | elm$url$Url$chompAfterProtocol,
5151 | elm$url$Url$Https,
5152 | A2(elm$core$String$dropLeft, 8, str)) : elm$core$Maybe$Nothing);
5153 | };
5154 | var elm$browser$Browser$Events$spawn = F3(
5155 | function (router, key, _n0) {
5156 | var node = _n0.a;
5157 | var name = _n0.b;
5158 | var actualNode = function () {
5159 | if (node.$ === 'Document') {
5160 | return _Browser_doc;
5161 | } else {
5162 | return _Browser_window;
5163 | }
5164 | }();
5165 | return A2(
5166 | elm$core$Task$map,
5167 | function (value) {
5168 | return _Utils_Tuple2(key, value);
5169 | },
5170 | A3(
5171 | _Browser_on,
5172 | actualNode,
5173 | name,
5174 | function (event) {
5175 | return A2(
5176 | elm$core$Platform$sendToSelf,
5177 | router,
5178 | A2(elm$browser$Browser$Events$Event, key, event));
5179 | }));
5180 | });
5181 | var elm$core$Dict$Black = {$: 'Black'};
5182 | var elm$core$Dict$RBNode_elm_builtin = F5(
5183 | function (a, b, c, d, e) {
5184 | return {$: 'RBNode_elm_builtin', a: a, b: b, c: c, d: d, e: e};
5185 | });
5186 | var elm$core$Basics$compare = _Utils_compare;
5187 | var elm$core$Dict$Red = {$: 'Red'};
5188 | var elm$core$Dict$balance = F5(
5189 | function (color, key, value, left, right) {
5190 | if ((right.$ === 'RBNode_elm_builtin') && (right.a.$ === 'Red')) {
5191 | var _n1 = right.a;
5192 | var rK = right.b;
5193 | var rV = right.c;
5194 | var rLeft = right.d;
5195 | var rRight = right.e;
5196 | if ((left.$ === 'RBNode_elm_builtin') && (left.a.$ === 'Red')) {
5197 | var _n3 = left.a;
5198 | var lK = left.b;
5199 | var lV = left.c;
5200 | var lLeft = left.d;
5201 | var lRight = left.e;
5202 | return A5(
5203 | elm$core$Dict$RBNode_elm_builtin,
5204 | elm$core$Dict$Red,
5205 | key,
5206 | value,
5207 | A5(elm$core$Dict$RBNode_elm_builtin, elm$core$Dict$Black, lK, lV, lLeft, lRight),
5208 | A5(elm$core$Dict$RBNode_elm_builtin, elm$core$Dict$Black, rK, rV, rLeft, rRight));
5209 | } else {
5210 | return A5(
5211 | elm$core$Dict$RBNode_elm_builtin,
5212 | color,
5213 | rK,
5214 | rV,
5215 | A5(elm$core$Dict$RBNode_elm_builtin, elm$core$Dict$Red, key, value, left, rLeft),
5216 | rRight);
5217 | }
5218 | } else {
5219 | if ((((left.$ === 'RBNode_elm_builtin') && (left.a.$ === 'Red')) && (left.d.$ === 'RBNode_elm_builtin')) && (left.d.a.$ === 'Red')) {
5220 | var _n5 = left.a;
5221 | var lK = left.b;
5222 | var lV = left.c;
5223 | var _n6 = left.d;
5224 | var _n7 = _n6.a;
5225 | var llK = _n6.b;
5226 | var llV = _n6.c;
5227 | var llLeft = _n6.d;
5228 | var llRight = _n6.e;
5229 | var lRight = left.e;
5230 | return A5(
5231 | elm$core$Dict$RBNode_elm_builtin,
5232 | elm$core$Dict$Red,
5233 | lK,
5234 | lV,
5235 | A5(elm$core$Dict$RBNode_elm_builtin, elm$core$Dict$Black, llK, llV, llLeft, llRight),
5236 | A5(elm$core$Dict$RBNode_elm_builtin, elm$core$Dict$Black, key, value, lRight, right));
5237 | } else {
5238 | return A5(elm$core$Dict$RBNode_elm_builtin, color, key, value, left, right);
5239 | }
5240 | }
5241 | });
5242 | var elm$core$Dict$insertHelp = F3(
5243 | function (key, value, dict) {
5244 | if (dict.$ === 'RBEmpty_elm_builtin') {
5245 | return A5(elm$core$Dict$RBNode_elm_builtin, elm$core$Dict$Red, key, value, elm$core$Dict$RBEmpty_elm_builtin, elm$core$Dict$RBEmpty_elm_builtin);
5246 | } else {
5247 | var nColor = dict.a;
5248 | var nKey = dict.b;
5249 | var nValue = dict.c;
5250 | var nLeft = dict.d;
5251 | var nRight = dict.e;
5252 | var _n1 = A2(elm$core$Basics$compare, key, nKey);
5253 | switch (_n1.$) {
5254 | case 'LT':
5255 | return A5(
5256 | elm$core$Dict$balance,
5257 | nColor,
5258 | nKey,
5259 | nValue,
5260 | A3(elm$core$Dict$insertHelp, key, value, nLeft),
5261 | nRight);
5262 | case 'EQ':
5263 | return A5(elm$core$Dict$RBNode_elm_builtin, nColor, nKey, value, nLeft, nRight);
5264 | default:
5265 | return A5(
5266 | elm$core$Dict$balance,
5267 | nColor,
5268 | nKey,
5269 | nValue,
5270 | nLeft,
5271 | A3(elm$core$Dict$insertHelp, key, value, nRight));
5272 | }
5273 | }
5274 | });
5275 | var elm$core$Dict$insert = F3(
5276 | function (key, value, dict) {
5277 | var _n0 = A3(elm$core$Dict$insertHelp, key, value, dict);
5278 | if ((_n0.$ === 'RBNode_elm_builtin') && (_n0.a.$ === 'Red')) {
5279 | var _n1 = _n0.a;
5280 | var k = _n0.b;
5281 | var v = _n0.c;
5282 | var l = _n0.d;
5283 | var r = _n0.e;
5284 | return A5(elm$core$Dict$RBNode_elm_builtin, elm$core$Dict$Black, k, v, l, r);
5285 | } else {
5286 | var x = _n0;
5287 | return x;
5288 | }
5289 | });
5290 | var elm$core$Dict$fromList = function (assocs) {
5291 | return A3(
5292 | elm$core$List$foldl,
5293 | F2(
5294 | function (_n0, dict) {
5295 | var key = _n0.a;
5296 | var value = _n0.b;
5297 | return A3(elm$core$Dict$insert, key, value, dict);
5298 | }),
5299 | elm$core$Dict$empty,
5300 | assocs);
5301 | };
5302 | var elm$core$Dict$foldl = F3(
5303 | function (func, acc, dict) {
5304 | foldl:
5305 | while (true) {
5306 | if (dict.$ === 'RBEmpty_elm_builtin') {
5307 | return acc;
5308 | } else {
5309 | var key = dict.b;
5310 | var value = dict.c;
5311 | var left = dict.d;
5312 | var right = dict.e;
5313 | var $temp$func = func,
5314 | $temp$acc = A3(
5315 | func,
5316 | key,
5317 | value,
5318 | A3(elm$core$Dict$foldl, func, acc, left)),
5319 | $temp$dict = right;
5320 | func = $temp$func;
5321 | acc = $temp$acc;
5322 | dict = $temp$dict;
5323 | continue foldl;
5324 | }
5325 | }
5326 | });
5327 | var elm$core$Dict$merge = F6(
5328 | function (leftStep, bothStep, rightStep, leftDict, rightDict, initialResult) {
5329 | var stepState = F3(
5330 | function (rKey, rValue, _n0) {
5331 | stepState:
5332 | while (true) {
5333 | var list = _n0.a;
5334 | var result = _n0.b;
5335 | if (!list.b) {
5336 | return _Utils_Tuple2(
5337 | list,
5338 | A3(rightStep, rKey, rValue, result));
5339 | } else {
5340 | var _n2 = list.a;
5341 | var lKey = _n2.a;
5342 | var lValue = _n2.b;
5343 | var rest = list.b;
5344 | if (_Utils_cmp(lKey, rKey) < 0) {
5345 | var $temp$rKey = rKey,
5346 | $temp$rValue = rValue,
5347 | $temp$_n0 = _Utils_Tuple2(
5348 | rest,
5349 | A3(leftStep, lKey, lValue, result));
5350 | rKey = $temp$rKey;
5351 | rValue = $temp$rValue;
5352 | _n0 = $temp$_n0;
5353 | continue stepState;
5354 | } else {
5355 | if (_Utils_cmp(lKey, rKey) > 0) {
5356 | return _Utils_Tuple2(
5357 | list,
5358 | A3(rightStep, rKey, rValue, result));
5359 | } else {
5360 | return _Utils_Tuple2(
5361 | rest,
5362 | A4(bothStep, lKey, lValue, rValue, result));
5363 | }
5364 | }
5365 | }
5366 | }
5367 | });
5368 | var _n3 = A3(
5369 | elm$core$Dict$foldl,
5370 | stepState,
5371 | _Utils_Tuple2(
5372 | elm$core$Dict$toList(leftDict),
5373 | initialResult),
5374 | rightDict);
5375 | var leftovers = _n3.a;
5376 | var intermediateResult = _n3.b;
5377 | return A3(
5378 | elm$core$List$foldl,
5379 | F2(
5380 | function (_n4, result) {
5381 | var k = _n4.a;
5382 | var v = _n4.b;
5383 | return A3(leftStep, k, v, result);
5384 | }),
5385 | intermediateResult,
5386 | leftovers);
5387 | });
5388 | var elm$core$Dict$union = F2(
5389 | function (t1, t2) {
5390 | return A3(elm$core$Dict$foldl, elm$core$Dict$insert, t2, t1);
5391 | });
5392 | var elm$core$Process$kill = _Scheduler_kill;
5393 | var elm$browser$Browser$Events$onEffects = F3(
5394 | function (router, subs, state) {
5395 | var stepRight = F3(
5396 | function (key, sub, _n6) {
5397 | var deads = _n6.a;
5398 | var lives = _n6.b;
5399 | var news = _n6.c;
5400 | return _Utils_Tuple3(
5401 | deads,
5402 | lives,
5403 | A2(
5404 | elm$core$List$cons,
5405 | A3(elm$browser$Browser$Events$spawn, router, key, sub),
5406 | news));
5407 | });
5408 | var stepLeft = F3(
5409 | function (_n4, pid, _n5) {
5410 | var deads = _n5.a;
5411 | var lives = _n5.b;
5412 | var news = _n5.c;
5413 | return _Utils_Tuple3(
5414 | A2(elm$core$List$cons, pid, deads),
5415 | lives,
5416 | news);
5417 | });
5418 | var stepBoth = F4(
5419 | function (key, pid, _n2, _n3) {
5420 | var deads = _n3.a;
5421 | var lives = _n3.b;
5422 | var news = _n3.c;
5423 | return _Utils_Tuple3(
5424 | deads,
5425 | A3(elm$core$Dict$insert, key, pid, lives),
5426 | news);
5427 | });
5428 | var newSubs = A2(elm$core$List$map, elm$browser$Browser$Events$addKey, subs);
5429 | var _n0 = A6(
5430 | elm$core$Dict$merge,
5431 | stepLeft,
5432 | stepBoth,
5433 | stepRight,
5434 | state.pids,
5435 | elm$core$Dict$fromList(newSubs),
5436 | _Utils_Tuple3(_List_Nil, elm$core$Dict$empty, _List_Nil));
5437 | var deadPids = _n0.a;
5438 | var livePids = _n0.b;
5439 | var makeNewPids = _n0.c;
5440 | return A2(
5441 | elm$core$Task$andThen,
5442 | function (pids) {
5443 | return elm$core$Task$succeed(
5444 | A2(
5445 | elm$browser$Browser$Events$State,
5446 | newSubs,
5447 | A2(
5448 | elm$core$Dict$union,
5449 | livePids,
5450 | elm$core$Dict$fromList(pids))));
5451 | },
5452 | A2(
5453 | elm$core$Task$andThen,
5454 | function (_n1) {
5455 | return elm$core$Task$sequence(makeNewPids);
5456 | },
5457 | elm$core$Task$sequence(
5458 | A2(elm$core$List$map, elm$core$Process$kill, deadPids))));
5459 | });
5460 | var elm$core$List$maybeCons = F3(
5461 | function (f, mx, xs) {
5462 | var _n0 = f(mx);
5463 | if (_n0.$ === 'Just') {
5464 | var x = _n0.a;
5465 | return A2(elm$core$List$cons, x, xs);
5466 | } else {
5467 | return xs;
5468 | }
5469 | });
5470 | var elm$core$List$filterMap = F2(
5471 | function (f, xs) {
5472 | return A3(
5473 | elm$core$List$foldr,
5474 | elm$core$List$maybeCons(f),
5475 | _List_Nil,
5476 | xs);
5477 | });
5478 | var elm$browser$Browser$Events$onSelfMsg = F3(
5479 | function (router, _n0, state) {
5480 | var key = _n0.key;
5481 | var event = _n0.event;
5482 | var toMessage = function (_n2) {
5483 | var subKey = _n2.a;
5484 | var _n3 = _n2.b;
5485 | var node = _n3.a;
5486 | var name = _n3.b;
5487 | var decoder = _n3.c;
5488 | return _Utils_eq(subKey, key) ? A2(_Browser_decodeEvent, decoder, event) : elm$core$Maybe$Nothing;
5489 | };
5490 | var messages = A2(elm$core$List$filterMap, toMessage, state.subs);
5491 | return A2(
5492 | elm$core$Task$andThen,
5493 | function (_n1) {
5494 | return elm$core$Task$succeed(state);
5495 | },
5496 | elm$core$Task$sequence(
5497 | A2(
5498 | elm$core$List$map,
5499 | elm$core$Platform$sendToApp(router),
5500 | messages)));
5501 | });
5502 | var elm$browser$Browser$Events$subMap = F2(
5503 | function (func, _n0) {
5504 | var node = _n0.a;
5505 | var name = _n0.b;
5506 | var decoder = _n0.c;
5507 | return A3(
5508 | elm$browser$Browser$Events$MySub,
5509 | node,
5510 | name,
5511 | A2(elm$json$Json$Decode$map, func, decoder));
5512 | });
5513 | _Platform_effectManagers['Browser.Events'] = _Platform_createManager(elm$browser$Browser$Events$init, elm$browser$Browser$Events$onEffects, elm$browser$Browser$Events$onSelfMsg, 0, elm$browser$Browser$Events$subMap);
5514 | var elm$browser$Browser$Events$subscription = _Platform_leaf('Browser.Events');
5515 | var elm$browser$Browser$Events$on = F3(
5516 | function (node, name, decoder) {
5517 | return elm$browser$Browser$Events$subscription(
5518 | A3(elm$browser$Browser$Events$MySub, node, name, decoder));
5519 | });
5520 | var elm$browser$Browser$Events$onMouseDown = A2(elm$browser$Browser$Events$on, elm$browser$Browser$Events$Document, 'mousedown');
5521 | var elm$core$Platform$Sub$batch = _Platform_batch;
5522 | var elm$core$Platform$Sub$none = elm$core$Platform$Sub$batch(_List_Nil);
5523 | var author$project$ContextMenu$subscriptions = function (_n0) {
5524 | var model = _n0.a;
5525 | return elm$core$Platform$Sub$batch(
5526 | _List_fromArray(
5527 | [
5528 | A2(author$project$ContextMenu$shouldCloseOnClick, model.closeOnDehover, model.openState) ? elm$browser$Browser$Events$onMouseDown(
5529 | elm$json$Json$Decode$succeed(author$project$ContextMenu$Close)) : elm$core$Platform$Sub$none
5530 | ]));
5531 | };
5532 | var elm$core$Platform$Sub$map = _Platform_map;
5533 | var author$project$Main$subscriptions = function (model) {
5534 | return A2(
5535 | elm$core$Platform$Sub$map,
5536 | author$project$Main$ContextMenuMsg,
5537 | author$project$ContextMenu$subscriptions(model.contextMenu));
5538 | };
5539 | var author$project$ContextMenu$None = {$: 'None'};
5540 | var author$project$ContextMenu$Open = F3(
5541 | function (a, b, c) {
5542 | return {$: 'Open', a: a, b: b, c: c};
5543 | });
5544 | var elm$core$Maybe$map = F2(
5545 | function (f, maybe) {
5546 | if (maybe.$ === 'Just') {
5547 | var value = maybe.a;
5548 | return elm$core$Maybe$Just(
5549 | f(value));
5550 | } else {
5551 | return elm$core$Maybe$Nothing;
5552 | }
5553 | });
5554 | var author$project$ContextMenu$setHoverState = F2(
5555 | function (hover, openState) {
5556 | return A2(
5557 | elm$core$Maybe$map,
5558 | function (_n0) {
5559 | var mouse = _n0.mouse;
5560 | var window = _n0.window;
5561 | var context = _n0.context;
5562 | return {context: context, hover: hover, mouse: mouse, window: window};
5563 | },
5564 | openState);
5565 | });
5566 | var author$project$ContextMenu$enterContainer = function (openState) {
5567 | return A2(author$project$ContextMenu$setHoverState, author$project$ContextMenu$Container, openState);
5568 | };
5569 | var author$project$ContextMenu$ItemIndex = function (a) {
5570 | return {$: 'ItemIndex', a: a};
5571 | };
5572 | var author$project$ContextMenu$enterItem = F2(
5573 | function (index, openState) {
5574 | return A2(
5575 | author$project$ContextMenu$setHoverState,
5576 | author$project$ContextMenu$ItemIndex(index),
5577 | openState);
5578 | });
5579 | var author$project$ContextMenu$leaveContainer = function (openState) {
5580 | return A2(author$project$ContextMenu$setHoverState, author$project$ContextMenu$None, openState);
5581 | };
5582 | var author$project$ContextMenu$leaveItem = function (openState) {
5583 | return A2(author$project$ContextMenu$setHoverState, author$project$ContextMenu$Container, openState);
5584 | };
5585 | var author$project$ContextMenu$Size = F2(
5586 | function (width, height) {
5587 | return {height: height, width: width};
5588 | });
5589 | var elm$browser$Browser$Dom$getViewport = _Browser_withWindow(_Browser_getViewport);
5590 | var author$project$ContextMenu$windowSize = A2(
5591 | elm$core$Task$map,
5592 | function (v) {
5593 | return A2(author$project$ContextMenu$Size, v.viewport.width, v.viewport.height);
5594 | },
5595 | elm$browser$Browser$Dom$getViewport);
5596 | var author$project$ContextMenu$update = F2(
5597 | function (msg, _n0) {
5598 | update:
5599 | while (true) {
5600 | var model = _n0.a;
5601 | switch (msg.$) {
5602 | case 'NoOp':
5603 | return _Utils_Tuple2(
5604 | author$project$ContextMenu$ContextMenu(model),
5605 | elm$core$Platform$Cmd$none);
5606 | case 'RequestOpen':
5607 | var context = msg.a;
5608 | var mouse = msg.b;
5609 | return _Utils_Tuple2(
5610 | author$project$ContextMenu$ContextMenu(model),
5611 | A2(
5612 | elm$core$Task$perform,
5613 | A2(author$project$ContextMenu$Open, context, mouse),
5614 | author$project$ContextMenu$windowSize));
5615 | case 'Open':
5616 | var context = msg.a;
5617 | var mouse = msg.b;
5618 | var window = msg.c;
5619 | return _Utils_Tuple2(
5620 | author$project$ContextMenu$ContextMenu(
5621 | _Utils_update(
5622 | model,
5623 | {
5624 | openState: elm$core$Maybe$Just(
5625 | {context: context, hover: author$project$ContextMenu$None, mouse: mouse, window: window})
5626 | })),
5627 | elm$core$Platform$Cmd$none);
5628 | case 'Close':
5629 | return _Utils_Tuple2(
5630 | author$project$ContextMenu$ContextMenu(
5631 | _Utils_update(
5632 | model,
5633 | {openState: elm$core$Maybe$Nothing})),
5634 | elm$core$Platform$Cmd$none);
5635 | case 'EnterItem':
5636 | var index = msg.a;
5637 | return _Utils_Tuple2(
5638 | author$project$ContextMenu$ContextMenu(
5639 | _Utils_update(
5640 | model,
5641 | {
5642 | openState: A2(author$project$ContextMenu$enterItem, index, model.openState)
5643 | })),
5644 | elm$core$Platform$Cmd$none);
5645 | case 'LeaveItem':
5646 | return _Utils_Tuple2(
5647 | author$project$ContextMenu$ContextMenu(
5648 | _Utils_update(
5649 | model,
5650 | {
5651 | openState: author$project$ContextMenu$leaveItem(model.openState)
5652 | })),
5653 | elm$core$Platform$Cmd$none);
5654 | case 'EnterContainer':
5655 | return _Utils_Tuple2(
5656 | author$project$ContextMenu$ContextMenu(
5657 | _Utils_update(
5658 | model,
5659 | {
5660 | openState: author$project$ContextMenu$enterContainer(model.openState)
5661 | })),
5662 | elm$core$Platform$Cmd$none);
5663 | default:
5664 | if (model.closeOnDehover) {
5665 | var $temp$msg = author$project$ContextMenu$Close,
5666 | $temp$_n0 = author$project$ContextMenu$ContextMenu(
5667 | _Utils_update(
5668 | model,
5669 | {
5670 | openState: author$project$ContextMenu$leaveContainer(model.openState)
5671 | }));
5672 | msg = $temp$msg;
5673 | _n0 = $temp$_n0;
5674 | continue update;
5675 | } else {
5676 | return _Utils_Tuple2(
5677 | author$project$ContextMenu$ContextMenu(
5678 | _Utils_update(
5679 | model,
5680 | {
5681 | openState: author$project$ContextMenu$leaveContainer(model.openState)
5682 | })),
5683 | elm$core$Platform$Cmd$none);
5684 | }
5685 | }
5686 | }
5687 | });
5688 | var author$project$Main$update = F2(
5689 | function (msg, model) {
5690 | if (msg.$ === 'ContextMenuMsg') {
5691 | var msg_ = msg.a;
5692 | var _n1 = A2(author$project$ContextMenu$update, msg_, model.contextMenu);
5693 | var contextMenu = _n1.a;
5694 | var cmd = _n1.b;
5695 | return _Utils_Tuple2(
5696 | _Utils_update(
5697 | model,
5698 | {contextMenu: contextMenu}),
5699 | A2(elm$core$Platform$Cmd$map, author$project$Main$ContextMenuMsg, cmd));
5700 | } else {
5701 | var num = msg.a;
5702 | return _Utils_Tuple2(
5703 | _Utils_update(
5704 | model,
5705 | {
5706 | message: 'Item[' + (elm$core$String$fromInt(num) + '] was clicked.')
5707 | }),
5708 | elm$core$Platform$Cmd$none);
5709 | }
5710 | });
5711 | var author$project$ContextMenu$NoOp = {$: 'NoOp'};
5712 | var author$project$ContextMenu$RequestOpen = F2(
5713 | function (a, b) {
5714 | return {$: 'RequestOpen', a: a, b: b};
5715 | });
5716 | var author$project$ContextMenu$Position = F2(
5717 | function (x, y) {
5718 | return {x: x, y: y};
5719 | });
5720 | var elm$json$Json$Decode$field = _Json_decodeField;
5721 | var elm$json$Json$Decode$float = _Json_decodeFloat;
5722 | var author$project$ContextMenu$position = A3(
5723 | elm$json$Json$Decode$map2,
5724 | author$project$ContextMenu$Position,
5725 | A2(elm$json$Json$Decode$field, 'clientX', elm$json$Json$Decode$float),
5726 | A2(elm$json$Json$Decode$field, 'clientY', elm$json$Json$Decode$float));
5727 | var elm$virtual_dom$VirtualDom$Custom = function (a) {
5728 | return {$: 'Custom', a: a};
5729 | };
5730 | var elm$virtual_dom$VirtualDom$on = _VirtualDom_on;
5731 | var elm$html$Html$Events$custom = F2(
5732 | function (event, decoder) {
5733 | return A2(
5734 | elm$virtual_dom$VirtualDom$on,
5735 | event,
5736 | elm$virtual_dom$VirtualDom$Custom(decoder));
5737 | });
5738 | var elm$virtual_dom$VirtualDom$Normal = function (a) {
5739 | return {$: 'Normal', a: a};
5740 | };
5741 | var elm$html$Html$Events$on = F2(
5742 | function (event, decoder) {
5743 | return A2(
5744 | elm$virtual_dom$VirtualDom$on,
5745 | event,
5746 | elm$virtual_dom$VirtualDom$Normal(decoder));
5747 | });
5748 | var author$project$ContextMenu$openIf = F3(
5749 | function (condition, transform, context) {
5750 | return condition ? A2(
5751 | elm$html$Html$Events$custom,
5752 | 'contextmenu',
5753 | A2(
5754 | elm$json$Json$Decode$map,
5755 | function (msg) {
5756 | return {message: msg, preventDefault: true, stopPropagation: true};
5757 | },
5758 | A2(
5759 | elm$json$Json$Decode$map,
5760 | transform,
5761 | A2(
5762 | elm$json$Json$Decode$map,
5763 | author$project$ContextMenu$RequestOpen(context),
5764 | author$project$ContextMenu$position)))) : A2(
5765 | elm$html$Html$Events$on,
5766 | 'contextmenu',
5767 | elm$json$Json$Decode$succeed(
5768 | transform(author$project$ContextMenu$NoOp)));
5769 | });
5770 | var author$project$ContextMenu$open = F2(
5771 | function (transform, context) {
5772 | return A3(author$project$ContextMenu$openIf, true, transform, context);
5773 | });
5774 | var author$project$ContextMenu$EnterContainer = {$: 'EnterContainer'};
5775 | var author$project$ContextMenu$LeaveContainer = {$: 'LeaveContainer'};
5776 | var author$project$ContextMenu$containerBorderWidth = 1;
5777 | var author$project$ContextMenu$containerPadding = 4;
5778 | var author$project$ContextMenu$partitionMargin = 6;
5779 | var author$project$ContextMenu$partitionWidth = 1;
5780 | var elm$core$List$sum = function (numbers) {
5781 | return A3(elm$core$List$foldl, elm$core$Basics$add, 0, numbers);
5782 | };
5783 | var author$project$ContextMenu$calculateMenuHeight = function (groups) {
5784 | var partitions = (elm$core$List$length(groups) - 1) * ((author$project$ContextMenu$partitionMargin * 2) + author$project$ContextMenu$partitionWidth);
5785 | var items = elm$core$List$sum(
5786 | A2(
5787 | elm$core$List$map,
5788 | function (items_) {
5789 | return elm$core$List$sum(
5790 | A2(
5791 | elm$core$List$map,
5792 | function (_n0) {
5793 | var item_ = _n0.a;
5794 | return item_.height;
5795 | },
5796 | items_));
5797 | },
5798 | groups));
5799 | var containerPaddings = author$project$ContextMenu$containerPadding * 2;
5800 | var containerBorders = author$project$ContextMenu$containerBorderWidth * 2;
5801 | return ((containerBorders + containerPaddings) + partitions) + items;
5802 | };
5803 | var author$project$ContextMenu$calculateX = F5(
5804 | function (direction, overflow, windowWidth, menuWidth, x) {
5805 | return A2(
5806 | elm$core$Basics$max,
5807 | 0,
5808 | function () {
5809 | if (direction.$ === 'LeftBottom') {
5810 | return ((x - menuWidth) < 0) ? (_Utils_eq(overflow, author$project$ContextMenu$Shift) ? 0 : x) : (x - menuWidth);
5811 | } else {
5812 | return (_Utils_cmp(x + menuWidth, windowWidth) > 0) ? (_Utils_eq(overflow, author$project$ContextMenu$Shift) ? (windowWidth - menuWidth) : (x - menuWidth)) : x;
5813 | }
5814 | }());
5815 | });
5816 | var author$project$ContextMenu$calculateY = F4(
5817 | function (overflow, windowHeight, menuHeight, y) {
5818 | return A2(
5819 | elm$core$Basics$max,
5820 | 0,
5821 | (_Utils_cmp(y + menuHeight, windowHeight) > 0) ? (_Utils_eq(overflow, author$project$ContextMenu$Shift) ? (windowHeight - menuHeight) : (y - menuHeight)) : y);
5822 | });
5823 | var author$project$ContextMenu$fontSize = 13;
5824 | var author$project$ContextMenu$getItemIndex = function (hover) {
5825 | if (hover.$ === 'ItemIndex') {
5826 | var index = hover.a;
5827 | return elm$core$Maybe$Just(index);
5828 | } else {
5829 | return elm$core$Maybe$Nothing;
5830 | }
5831 | };
5832 | var author$project$ContextMenu$EnterItem = function (a) {
5833 | return {$: 'EnterItem', a: a};
5834 | };
5835 | var author$project$ContextMenu$LeaveItem = {$: 'LeaveItem'};
5836 | var author$project$ContextMenu$disabledTextColor = 'rgb(200, 200, 200)';
5837 | var author$project$ContextMenu$shortcutTextColor = 'rgb(200, 200, 200)';
5838 | var elm$core$String$fromFloat = _String_fromNumber;
5839 | var author$project$Styles$px = function (n) {
5840 | return elm$core$String$fromFloat(n) + 'px';
5841 | };
5842 | var elm$core$Basics$negate = function (n) {
5843 | return -n;
5844 | };
5845 | var elm$virtual_dom$VirtualDom$style = _VirtualDom_style;
5846 | var elm$html$Html$Attributes$style = elm$virtual_dom$VirtualDom$style;
5847 | var author$project$Styles$icon = function (size) {
5848 | return _List_fromArray(
5849 | [
5850 | A2(elm$html$Html$Attributes$style, 'position', 'absolute'),
5851 | A2(
5852 | elm$html$Html$Attributes$style,
5853 | 'margin-left',
5854 | author$project$Styles$px((-size) - 4)),
5855 | A2(elm$html$Html$Attributes$style, 'top', '2px')
5856 | ]);
5857 | };
5858 | var elm$core$Basics$not = _Basics_not;
5859 | var author$project$Styles$row = F8(
5860 | function (hoverColor, disabledTextColor, invertText, usePointer, lineHeight, hovered, disabled, hasShortCut) {
5861 | return _List_fromArray(
5862 | [
5863 | A2(elm$html$Html$Attributes$style, 'position', 'relative'),
5864 | A2(elm$html$Html$Attributes$style, 'padding', '0 18px 0 28px'),
5865 | A2(
5866 | elm$html$Html$Attributes$style,
5867 | 'background-color',
5868 | hovered ? hoverColor : ''),
5869 | A2(
5870 | elm$html$Html$Attributes$style,
5871 | 'height',
5872 | author$project$Styles$px(lineHeight)),
5873 | A2(
5874 | elm$html$Html$Attributes$style,
5875 | 'color',
5876 | disabled ? disabledTextColor : ((hovered && invertText) ? '#fff' : '')),
5877 | A2(
5878 | elm$html$Html$Attributes$style,
5879 | 'cursor',
5880 | ((!disabled) && usePointer) ? 'pointer' : ''),
5881 | A2(elm$html$Html$Attributes$style, 'display', 'flex'),
5882 | A2(
5883 | elm$html$Html$Attributes$style,
5884 | 'justify-content',
5885 | hasShortCut ? 'space-between' : '')
5886 | ]);
5887 | });
5888 | var author$project$Styles$shortcut = F3(
5889 | function (color, lineHeight, hovered) {
5890 | return _List_fromArray(
5891 | [
5892 | A2(
5893 | elm$html$Html$Attributes$style,
5894 | 'line-height',
5895 | author$project$Styles$px(lineHeight)),
5896 | A2(
5897 | elm$html$Html$Attributes$style,
5898 | 'color',
5899 | hovered ? '' : color)
5900 | ]);
5901 | });
5902 | var author$project$Styles$text = function (lineHeight) {
5903 | return _List_fromArray(
5904 | [
5905 | A2(
5906 | elm$html$Html$Attributes$style,
5907 | 'line-height',
5908 | author$project$Styles$px(lineHeight)),
5909 | A2(elm$html$Html$Attributes$style, 'text-overflow', 'ellipsis'),
5910 | A2(elm$html$Html$Attributes$style, 'overflow', 'hidden'),
5911 | A2(elm$html$Html$Attributes$style, 'white-space', 'nowrap')
5912 | ]);
5913 | };
5914 | var elm$core$String$trim = _String_trim;
5915 | var elm$html$Html$div = _VirtualDom_node('div');
5916 | var elm$virtual_dom$VirtualDom$map = _VirtualDom_map;
5917 | var elm$html$Html$map = elm$virtual_dom$VirtualDom$map;
5918 | var elm$virtual_dom$VirtualDom$text = _VirtualDom_text;
5919 | var elm$html$Html$text = elm$virtual_dom$VirtualDom$text;
5920 | var elm$html$Html$Events$onMouseDown = function (msg) {
5921 | return A2(
5922 | elm$html$Html$Events$on,
5923 | 'mousedown',
5924 | elm$json$Json$Decode$succeed(msg));
5925 | };
5926 | var elm$html$Html$Events$onMouseEnter = function (msg) {
5927 | return A2(
5928 | elm$html$Html$Events$on,
5929 | 'mouseenter',
5930 | elm$json$Json$Decode$succeed(msg));
5931 | };
5932 | var elm$html$Html$Events$onMouseLeave = function (msg) {
5933 | return A2(
5934 | elm$html$Html$Events$on,
5935 | 'mouseleave',
5936 | elm$json$Json$Decode$succeed(msg));
5937 | };
5938 | var author$project$ContextMenu$itemView = F6(
5939 | function (config, transform, hoverIndex, groupIndex, index, _n0) {
5940 | var item_ = _n0.a.a;
5941 | var msg = _n0.b;
5942 | var icon_ = function () {
5943 | var _n2 = item_.icon;
5944 | if (_n2.$ === 'Just') {
5945 | var _n3 = _n2.a;
5946 | var icon__ = _n3.a;
5947 | var color = _n3.b;
5948 | return A2(
5949 | elm$html$Html$map,
5950 | elm$core$Basics$never,
5951 | A2(
5952 | elm$html$Html$div,
5953 | author$project$Styles$icon(author$project$ContextMenu$fontSize),
5954 | _List_fromArray(
5955 | [
5956 | A2(
5957 | icon__,
5958 | item_.disabled ? author$project$ContextMenu$disabledTextColor : color,
5959 | elm$core$Basics$floor(author$project$ContextMenu$fontSize))
5960 | ])));
5961 | } else {
5962 | return elm$html$Html$text('');
5963 | }
5964 | }();
5965 | var hovered = _Utils_eq(
5966 | hoverIndex,
5967 | elm$core$Maybe$Just(
5968 | _Utils_Tuple2(groupIndex, index)));
5969 | var shortCut = A2(
5970 | elm$html$Html$div,
5971 | A3(author$project$Styles$shortcut, author$project$ContextMenu$shortcutTextColor, item_.height, hovered),
5972 | _List_fromArray(
5973 | [
5974 | elm$html$Html$text(item_.shortcut)
5975 | ]));
5976 | var styles = A8(
5977 | author$project$Styles$row,
5978 | config.hoverColor,
5979 | author$project$ContextMenu$disabledTextColor,
5980 | config.invertText,
5981 | _Utils_eq(config.cursor, author$project$ContextMenu$Pointer),
5982 | item_.height,
5983 | hovered,
5984 | item_.disabled,
5985 | elm$core$String$trim(item_.shortcut) !== '');
5986 | var events = item_.disabled ? _List_Nil : _List_fromArray(
5987 | [
5988 | elm$html$Html$Events$onMouseEnter(
5989 | transform(
5990 | author$project$ContextMenu$EnterItem(
5991 | _Utils_Tuple2(groupIndex, index)))),
5992 | elm$html$Html$Events$onMouseLeave(
5993 | transform(author$project$ContextMenu$LeaveItem)),
5994 | elm$html$Html$Events$onMouseDown(msg)
5995 | ]);
5996 | var content = function () {
5997 | var _n1 = item_.content;
5998 | if (_n1.$ === 'Text') {
5999 | var s = _n1.a;
6000 | return A2(
6001 | elm$html$Html$div,
6002 | author$project$Styles$text(item_.height),
6003 | _List_fromArray(
6004 | [
6005 | elm$html$Html$text(s)
6006 | ]));
6007 | } else {
6008 | var toHtml = _n1.a;
6009 | return toHtml(item_.disabled);
6010 | }
6011 | }();
6012 | return A2(
6013 | elm$html$Html$div,
6014 | _Utils_ap(styles, events),
6015 | _List_fromArray(
6016 | [
6017 | icon_,
6018 | A2(elm$html$Html$map, elm$core$Basics$never, content),
6019 | shortCut
6020 | ]));
6021 | });
6022 | var author$project$ContextMenu$itemGroupView = F5(
6023 | function (config, transform, hoverIndex, groupIndex, items) {
6024 | return A2(
6025 | elm$core$List$indexedMap,
6026 | A4(author$project$ContextMenu$itemView, config, transform, hoverIndex, groupIndex),
6027 | items);
6028 | });
6029 | var author$project$Styles$borderColor = '#ccc';
6030 | var author$project$Styles$partition = F2(
6031 | function (borderWidth, margin) {
6032 | return _List_fromArray(
6033 | [
6034 | A2(elm$html$Html$Attributes$style, 'border-bottom-style', 'solid'),
6035 | A2(
6036 | elm$html$Html$Attributes$style,
6037 | 'border-bottom-width',
6038 | author$project$Styles$px(1)),
6039 | A2(elm$html$Html$Attributes$style, 'border-bottom-color', author$project$Styles$borderColor),
6040 | A2(elm$html$Html$Attributes$style, 'border-top', 'none'),
6041 | A2(
6042 | elm$html$Html$Attributes$style,
6043 | 'margin',
6044 | author$project$Styles$px(margin) + ' 0')
6045 | ]);
6046 | });
6047 | var elm$html$Html$hr = _VirtualDom_node('hr');
6048 | var author$project$ContextMenu$partition = A2(
6049 | elm$html$Html$hr,
6050 | A2(author$project$Styles$partition, author$project$ContextMenu$partitionWidth, author$project$ContextMenu$partitionMargin),
6051 | _List_Nil);
6052 | var author$project$ContextMenu$joinGroupsWithPartition = function (groups) {
6053 | return A3(
6054 | elm$core$List$foldr,
6055 | F2(
6056 | function (group, prev) {
6057 | if (prev.$ === 'Just') {
6058 | var items = prev.a;
6059 | return elm$core$Maybe$Just(
6060 | _Utils_ap(
6061 | group,
6062 | A2(elm$core$List$cons, author$project$ContextMenu$partition, items)));
6063 | } else {
6064 | return elm$core$Maybe$Just(group);
6065 | }
6066 | }),
6067 | elm$core$Maybe$Nothing,
6068 | groups);
6069 | };
6070 | var author$project$ContextMenu$menuWidthWithBorders = function (menuWidth) {
6071 | return menuWidth + (author$project$ContextMenu$containerBorderWidth * 2);
6072 | };
6073 | var author$project$Styles$container = F9(
6074 | function (containerColor, borderWidth, padding, rounded, width, left, top, fontFamily, fontSize) {
6075 | return _List_fromArray(
6076 | [
6077 | A2(elm$html$Html$Attributes$style, 'border-style', 'solid'),
6078 | A2(
6079 | elm$html$Html$Attributes$style,
6080 | 'border-width',
6081 | author$project$Styles$px(borderWidth)),
6082 | A2(elm$html$Html$Attributes$style, 'border-color', author$project$Styles$borderColor),
6083 | A2(elm$html$Html$Attributes$style, 'position', 'fixed'),
6084 | A2(
6085 | elm$html$Html$Attributes$style,
6086 | 'top',
6087 | author$project$Styles$px(top)),
6088 | A2(
6089 | elm$html$Html$Attributes$style,
6090 | 'left',
6091 | author$project$Styles$px(left)),
6092 | A2(
6093 | elm$html$Html$Attributes$style,
6094 | 'width',
6095 | author$project$Styles$px(width)),
6096 | A2(
6097 | elm$html$Html$Attributes$style,
6098 | 'z-index',
6099 | elm$core$String$fromFloat(2147483647 - 10)),
6100 | A2(elm$html$Html$Attributes$style, 'background-color', containerColor),
6101 | A2(elm$html$Html$Attributes$style, 'cursor', 'default'),
6102 | A2(elm$html$Html$Attributes$style, 'box-shadow', '0px 3px 8px 0px rgba(0,0,0,0.3)'),
6103 | A2(
6104 | elm$html$Html$Attributes$style,
6105 | 'padding',
6106 | author$project$Styles$px(padding) + ' 0'),
6107 | A2(
6108 | elm$html$Html$Attributes$style,
6109 | 'border-radius',
6110 | rounded ? author$project$Styles$px(padding) : ''),
6111 | A2(elm$html$Html$Attributes$style, 'font-family', fontFamily),
6112 | A2(
6113 | elm$html$Html$Attributes$style,
6114 | 'font-size',
6115 | author$project$Styles$px(fontSize))
6116 | ]);
6117 | });
6118 | var author$project$ContextMenu$view = F4(
6119 | function (config, transform, toItemGroups, _n0) {
6120 | var model = _n0.a;
6121 | var _n1 = model.openState;
6122 | if (_n1.$ === 'Just') {
6123 | var mouse = _n1.a.mouse;
6124 | var window = _n1.a.window;
6125 | var hover = _n1.a.hover;
6126 | var context = _n1.a.context;
6127 | var groups = toItemGroups(context);
6128 | var groupsView = A2(
6129 | elm$core$List$indexedMap,
6130 | A3(
6131 | author$project$ContextMenu$itemGroupView,
6132 | config,
6133 | transform,
6134 | author$project$ContextMenu$getItemIndex(hover)),
6135 | groups);
6136 | var itemGroups = A2(
6137 | elm$core$List$map,
6138 | elm$core$List$map(elm$core$Tuple$first),
6139 | groups);
6140 | var _n2 = author$project$ContextMenu$joinGroupsWithPartition(groupsView);
6141 | if (_n2.$ === 'Just') {
6142 | var items = _n2.a;
6143 | var y_ = A4(
6144 | author$project$ContextMenu$calculateY,
6145 | config.overflowY,
6146 | window.height,
6147 | author$project$ContextMenu$calculateMenuHeight(itemGroups),
6148 | mouse.y);
6149 | var x_ = A5(
6150 | author$project$ContextMenu$calculateX,
6151 | config.direction,
6152 | config.overflowX,
6153 | window.width,
6154 | author$project$ContextMenu$menuWidthWithBorders(config.width),
6155 | mouse.x);
6156 | return A2(
6157 | elm$html$Html$div,
6158 | _Utils_ap(
6159 | A9(author$project$Styles$container, config.containerColor, author$project$ContextMenu$containerBorderWidth, author$project$ContextMenu$containerPadding, config.rounded, config.width, x_, y_, config.fontFamily, author$project$ContextMenu$fontSize),
6160 | _List_fromArray(
6161 | [
6162 | elm$html$Html$Events$onMouseEnter(
6163 | transform(author$project$ContextMenu$EnterContainer)),
6164 | elm$html$Html$Events$onMouseLeave(
6165 | transform(author$project$ContextMenu$LeaveContainer))
6166 | ])),
6167 | items);
6168 | } else {
6169 | return elm$html$Html$text('');
6170 | }
6171 | } else {
6172 | return elm$html$Html$text('');
6173 | }
6174 | });
6175 | var author$project$Main$Background = {$: 'Background'};
6176 | var author$project$Main$Object = {$: 'Object'};
6177 | var author$project$Main$backgroundStyles = _List_fromArray(
6178 | [
6179 | A2(elm$html$Html$Attributes$style, 'left', '10%'),
6180 | A2(elm$html$Html$Attributes$style, 'right', '10%'),
6181 | A2(elm$html$Html$Attributes$style, 'top', '10%'),
6182 | A2(elm$html$Html$Attributes$style, 'bottom', '-10%'),
6183 | A2(elm$html$Html$Attributes$style, 'position', 'absolute'),
6184 | A2(elm$html$Html$Attributes$style, 'background-color', '#cdb')
6185 | ]);
6186 | var author$project$Main$objectStyles = _List_fromArray(
6187 | [
6188 | A2(elm$html$Html$Attributes$style, 'position', 'absolute'),
6189 | A2(elm$html$Html$Attributes$style, 'top', '100px'),
6190 | A2(elm$html$Html$Attributes$style, 'left', '150px'),
6191 | A2(elm$html$Html$Attributes$style, 'width', '100px'),
6192 | A2(elm$html$Html$Attributes$style, 'height', '100px'),
6193 | A2(elm$html$Html$Attributes$style, 'background-color', '#976')
6194 | ]);
6195 | var author$project$ContextMenu$Item = function (a) {
6196 | return {$: 'Item', a: a};
6197 | };
6198 | var author$project$ContextMenu$disabled = F2(
6199 | function (disabled_, _n0) {
6200 | var item_ = _n0.a;
6201 | return author$project$ContextMenu$Item(
6202 | _Utils_update(
6203 | item_,
6204 | {disabled: disabled_}));
6205 | });
6206 | var author$project$ContextMenu$Text = function (a) {
6207 | return {$: 'Text', a: a};
6208 | };
6209 | var author$project$ContextMenu$defaultItemHeight = 20;
6210 | var author$project$ContextMenu$item = function (s) {
6211 | return author$project$ContextMenu$Item(
6212 | {
6213 | content: author$project$ContextMenu$Text(s),
6214 | disabled: false,
6215 | height: elm$core$Basics$floor(author$project$ContextMenu$defaultItemHeight),
6216 | icon: elm$core$Maybe$Nothing,
6217 | shortcut: ''
6218 | });
6219 | };
6220 | var author$project$ContextMenu$annotationHeight = 12;
6221 | var author$project$ContextMenu$annotationFontSize = 10;
6222 | var author$project$ContextMenu$annotationTextColor = 'rgb(200, 200, 200)';
6223 | var author$project$Styles$annotation = F4(
6224 | function (color, annotationHeight, fontSize, disabled) {
6225 | return _List_fromArray(
6226 | [
6227 | A2(elm$html$Html$Attributes$style, 'margin-top', '-2px'),
6228 | A2(
6229 | elm$html$Html$Attributes$style,
6230 | 'line-height',
6231 | author$project$Styles$px(annotationHeight)),
6232 | A2(
6233 | elm$html$Html$Attributes$style,
6234 | 'font-size',
6235 | author$project$Styles$px(fontSize)),
6236 | A2(elm$html$Html$Attributes$style, 'color', color)
6237 | ]);
6238 | });
6239 | var author$project$ContextMenu$annotationView = F3(
6240 | function (s, ann, disabled_) {
6241 | return A2(
6242 | elm$html$Html$div,
6243 | _List_Nil,
6244 | _List_fromArray(
6245 | [
6246 | A2(
6247 | elm$html$Html$div,
6248 | author$project$Styles$text(author$project$ContextMenu$defaultItemHeight),
6249 | _List_fromArray(
6250 | [
6251 | elm$html$Html$text(s)
6252 | ])),
6253 | A2(
6254 | elm$html$Html$div,
6255 | A4(author$project$Styles$annotation, author$project$ContextMenu$annotationTextColor, author$project$ContextMenu$annotationHeight, author$project$ContextMenu$annotationFontSize, disabled_),
6256 | _List_fromArray(
6257 | [
6258 | elm$html$Html$text(ann)
6259 | ]))
6260 | ]));
6261 | });
6262 | var author$project$ContextMenu$Custom = function (a) {
6263 | return {$: 'Custom', a: a};
6264 | };
6265 | var author$project$ContextMenu$custom = F2(
6266 | function (height, content) {
6267 | return author$project$ContextMenu$Item(
6268 | {
6269 | content: author$project$ContextMenu$Custom(content),
6270 | disabled: false,
6271 | height: A2(
6272 | elm$core$Basics$max,
6273 | elm$core$Basics$floor(author$project$ContextMenu$defaultItemHeight),
6274 | height),
6275 | icon: elm$core$Maybe$Nothing,
6276 | shortcut: ''
6277 | });
6278 | });
6279 | var author$project$ContextMenu$itemWithAnnotation = F2(
6280 | function (s, ann) {
6281 | return A2(
6282 | author$project$ContextMenu$custom,
6283 | elm$core$Basics$floor((author$project$ContextMenu$defaultItemHeight + author$project$ContextMenu$annotationHeight) - 2),
6284 | A2(author$project$ContextMenu$annotationView, s, ann));
6285 | });
6286 | var author$project$ContextMenu$shortcut = F2(
6287 | function (shortcutName, _n0) {
6288 | var item_ = _n0.a;
6289 | return author$project$ContextMenu$Item(
6290 | _Utils_update(
6291 | item_,
6292 | {shortcut: shortcutName}));
6293 | });
6294 | var author$project$Main$Item = function (a) {
6295 | return {$: 'Item', a: a};
6296 | };
6297 | var author$project$Main$toItemGroups = function (context) {
6298 | if (context.$ === 'Background') {
6299 | return _List_fromArray(
6300 | [
6301 | _List_fromArray(
6302 | [
6303 | _Utils_Tuple2(
6304 | author$project$ContextMenu$item('Hey'),
6305 | author$project$Main$Item(1)),
6306 | _Utils_Tuple2(
6307 | author$project$ContextMenu$item('Yo!'),
6308 | author$project$Main$Item(2))
6309 | ]),
6310 | _List_fromArray(
6311 | [
6312 | _Utils_Tuple2(
6313 | A2(
6314 | author$project$ContextMenu$disabled,
6315 | true,
6316 | author$project$ContextMenu$item('Take photos')),
6317 | author$project$Main$Item(3)),
6318 | _Utils_Tuple2(
6319 | A2(
6320 | author$project$ContextMenu$disabled,
6321 | false,
6322 | author$project$ContextMenu$item('Have a break')),
6323 | author$project$Main$Item(4)),
6324 | _Utils_Tuple2(
6325 | author$project$ContextMenu$item('Pneumonoultramicroscopicsilicovolcanoconiosis'),
6326 | author$project$Main$Item(5)),
6327 | _Utils_Tuple2(
6328 | A2(
6329 | author$project$ContextMenu$shortcut,
6330 | 'Ctrl+S',
6331 | author$project$ContextMenu$item('Save')),
6332 | author$project$Main$Item(6)),
6333 | _Utils_Tuple2(
6334 | A2(
6335 | author$project$ContextMenu$disabled,
6336 | false,
6337 | A2(author$project$ContextMenu$itemWithAnnotation, 'Item with annotation', 'Some annotation here')),
6338 | author$project$Main$Item(7))
6339 | ])
6340 | ]);
6341 | } else {
6342 | return _List_fromArray(
6343 | [
6344 | _List_fromArray(
6345 | [
6346 | _Utils_Tuple2(
6347 | author$project$ContextMenu$item('Pen'),
6348 | author$project$Main$Item(8)),
6349 | _Utils_Tuple2(
6350 | author$project$ContextMenu$item('Pineapple'),
6351 | author$project$Main$Item(9)),
6352 | _Utils_Tuple2(
6353 | author$project$ContextMenu$item('Apple'),
6354 | author$project$Main$Item(10))
6355 | ])
6356 | ]);
6357 | }
6358 | };
6359 | var author$project$Main$view = function (model) {
6360 | return A2(
6361 | elm$html$Html$div,
6362 | _List_Nil,
6363 | _List_fromArray(
6364 | [
6365 | A2(
6366 | elm$html$Html$div,
6367 | A2(
6368 | elm$core$List$cons,
6369 | A2(author$project$ContextMenu$open, author$project$Main$ContextMenuMsg, author$project$Main$Background),
6370 | author$project$Main$backgroundStyles),
6371 | _List_fromArray(
6372 | [
6373 | A2(
6374 | elm$html$Html$div,
6375 | A2(
6376 | elm$core$List$cons,
6377 | A2(author$project$ContextMenu$open, author$project$Main$ContextMenuMsg, author$project$Main$Object),
6378 | author$project$Main$objectStyles),
6379 | _List_Nil)
6380 | ])),
6381 | A2(
6382 | elm$html$Html$div,
6383 | _List_Nil,
6384 | _List_fromArray(
6385 | [
6386 | elm$html$Html$text(model.message)
6387 | ])),
6388 | A4(author$project$ContextMenu$view, model.config, author$project$Main$ContextMenuMsg, author$project$Main$toItemGroups, model.contextMenu)
6389 | ]));
6390 | };
6391 | var elm$browser$Browser$element = _Browser_element;
6392 | var author$project$Main$main = elm$browser$Browser$element(
6393 | {init: author$project$Main$init, subscriptions: author$project$Main$subscriptions, update: author$project$Main$update, view: author$project$Main$view});
6394 | _Platform_export({'Main':{'init':author$project$Main$main(
6395 | elm$json$Json$Decode$succeed(_Utils_Tuple0))(0)}});}(this));
--------------------------------------------------------------------------------