diff --git a/submissions/mattjbray/Dockerfile b/submissions/mattjbray/Dockerfile index 9d4adb8..57f5db0 100644 --- a/submissions/mattjbray/Dockerfile +++ b/submissions/mattjbray/Dockerfile @@ -1,8 +1,7 @@ FROM node:4.1 # Install Elm -RUN npm install --global elm@0.15.1 -ENV ELM_HOME /usr/local/lib/node_modules/elm/share +RUN npm install --global elm@0.16.0 # Fix locales RUN apt-get update && \ diff --git a/submissions/mattjbray/dist/app.js b/submissions/mattjbray/dist/app.js index cc6474f..7772de1 100644 --- a/submissions/mattjbray/dist/app.js +++ b/submissions/mattjbray/dist/app.js @@ -1,5503 +1,4 @@ var Elm = Elm || { Native: {} }; -Elm.Array = Elm.Array || {}; -Elm.Array.make = function (_elm) { - "use strict"; - _elm.Array = _elm.Array || {}; - if (_elm.Array.values) - return _elm.Array.values; - var _op = {}, - _N = Elm.Native, - _U = _N.Utils.make(_elm), - _L = _N.List.make(_elm), - $moduleName = "Array", - $Basics = Elm.Basics.make(_elm), - $List = Elm.List.make(_elm), - $Maybe = Elm.Maybe.make(_elm), - $Native$Array = Elm.Native.Array.make(_elm); - var append = $Native$Array.append; - var length = $Native$Array.length; - var isEmpty = function (array) { - return _U.eq(length(array), - 0); - }; - var slice = $Native$Array.slice; - var set = $Native$Array.set; - var get = F2(function (i, - array) { - return _U.cmp(0, - i) < 1 && _U.cmp(i, - $Native$Array.length(array)) < 0 ? $Maybe.Just(A2($Native$Array.get, - i, - array)) : $Maybe.Nothing; - }); - var push = $Native$Array.push; - var empty = $Native$Array.empty; - var filter = F2(function (isOkay, - arr) { - return function () { - var update = F2(function (x, - xs) { - return isOkay(x) ? A2($Native$Array.push, - x, - xs) : xs; - }); - return A3($Native$Array.foldl, - update, - $Native$Array.empty, - arr); - }(); - }); - var foldr = $Native$Array.foldr; - var foldl = $Native$Array.foldl; - var indexedMap = $Native$Array.indexedMap; - var map = $Native$Array.map; - var toIndexedList = function (array) { - return A3($List.map2, - F2(function (v0,v1) { - return {ctor: "_Tuple2" - ,_0: v0 - ,_1: v1}; - }), - _L.range(0, - $Native$Array.length(array) - 1), - $Native$Array.toList(array)); - }; - var toList = $Native$Array.toList; - var fromList = $Native$Array.fromList; - var initialize = $Native$Array.initialize; - var repeat = F2(function (n,e) { - return A2(initialize, - n, - $Basics.always(e)); - }); - var Array = {ctor: "Array"}; - _elm.Array.values = {_op: _op - ,empty: empty - ,repeat: repeat - ,initialize: initialize - ,fromList: fromList - ,isEmpty: isEmpty - ,length: length - ,push: push - ,append: append - ,get: get - ,set: set - ,slice: slice - ,toList: toList - ,toIndexedList: toIndexedList - ,map: map - ,indexedMap: indexedMap - ,filter: filter - ,foldl: foldl - ,foldr: foldr}; - return _elm.Array.values; -}; -Elm.Basics = Elm.Basics || {}; -Elm.Basics.make = function (_elm) { - "use strict"; - _elm.Basics = _elm.Basics || {}; - if (_elm.Basics.values) - return _elm.Basics.values; - var _op = {}, - _N = Elm.Native, - _U = _N.Utils.make(_elm), - _L = _N.List.make(_elm), - $moduleName = "Basics", - $Native$Basics = Elm.Native.Basics.make(_elm), - $Native$Show = Elm.Native.Show.make(_elm), - $Native$Utils = Elm.Native.Utils.make(_elm); - var uncurry = F2(function (f, - _v0) { - return function () { - switch (_v0.ctor) - {case "_Tuple2": return A2(f, - _v0._0, - _v0._1);} - _U.badCase($moduleName, - "on line 595, column 3 to 8"); - }(); - }); - var curry = F3(function (f, - a, - b) { - return f({ctor: "_Tuple2" - ,_0: a - ,_1: b}); - }); - var flip = F3(function (f,b,a) { - return A2(f,a,b); - }); - var snd = function (_v4) { - return function () { - switch (_v4.ctor) - {case "_Tuple2": return _v4._1;} - _U.badCase($moduleName, - "on line 573, column 3 to 4"); - }(); - }; - var fst = function (_v8) { - return function () { - switch (_v8.ctor) - {case "_Tuple2": return _v8._0;} - _U.badCase($moduleName, - "on line 567, column 3 to 4"); - }(); - }; - var always = F2(function (a, - _v12) { - return function () { - return a; - }(); - }); - var identity = function (x) { - return x; - }; - _op["<|"] = F2(function (f,x) { - return f(x); - }); - _op["|>"] = F2(function (x,f) { - return f(x); - }); - _op[">>"] = F3(function (f, - g, - x) { - return g(f(x)); - }); - _op["<<"] = F3(function (g, - f, - x) { - return g(f(x)); - }); - _op["++"] = $Native$Utils.append; - var toString = $Native$Show.toString; - var isInfinite = $Native$Basics.isInfinite; - var isNaN = $Native$Basics.isNaN; - var toFloat = $Native$Basics.toFloat; - var ceiling = $Native$Basics.ceiling; - var floor = $Native$Basics.floor; - var truncate = $Native$Basics.truncate; - var round = $Native$Basics.round; - var otherwise = true; - var not = $Native$Basics.not; - var xor = $Native$Basics.xor; - _op["||"] = $Native$Basics.or; - _op["&&"] = $Native$Basics.and; - var max = $Native$Basics.max; - var min = $Native$Basics.min; - var GT = {ctor: "GT"}; - var EQ = {ctor: "EQ"}; - var LT = {ctor: "LT"}; - var compare = $Native$Basics.compare; - _op[">="] = $Native$Basics.ge; - _op["<="] = $Native$Basics.le; - _op[">"] = $Native$Basics.gt; - _op["<"] = $Native$Basics.lt; - _op["/="] = $Native$Basics.neq; - _op["=="] = $Native$Basics.eq; - var e = $Native$Basics.e; - var pi = $Native$Basics.pi; - var clamp = $Native$Basics.clamp; - var logBase = $Native$Basics.logBase; - var abs = $Native$Basics.abs; - var negate = $Native$Basics.negate; - var sqrt = $Native$Basics.sqrt; - var atan2 = $Native$Basics.atan2; - var atan = $Native$Basics.atan; - var asin = $Native$Basics.asin; - var acos = $Native$Basics.acos; - var tan = $Native$Basics.tan; - var sin = $Native$Basics.sin; - var cos = $Native$Basics.cos; - _op["^"] = $Native$Basics.exp; - _op["%"] = $Native$Basics.mod; - var rem = $Native$Basics.rem; - _op["//"] = $Native$Basics.div; - _op["/"] = $Native$Basics.floatDiv; - _op["*"] = $Native$Basics.mul; - _op["-"] = $Native$Basics.sub; - _op["+"] = $Native$Basics.add; - var toPolar = $Native$Basics.toPolar; - var fromPolar = $Native$Basics.fromPolar; - var turns = $Native$Basics.turns; - var degrees = $Native$Basics.degrees; - var radians = function (t) { - return t; - }; - _elm.Basics.values = {_op: _op - ,max: max - ,min: min - ,compare: compare - ,not: not - ,xor: xor - ,otherwise: otherwise - ,rem: rem - ,negate: negate - ,abs: abs - ,sqrt: sqrt - ,clamp: clamp - ,logBase: logBase - ,e: e - ,pi: pi - ,cos: cos - ,sin: sin - ,tan: tan - ,acos: acos - ,asin: asin - ,atan: atan - ,atan2: atan2 - ,round: round - ,floor: floor - ,ceiling: ceiling - ,truncate: truncate - ,toFloat: toFloat - ,degrees: degrees - ,radians: radians - ,turns: turns - ,toPolar: toPolar - ,fromPolar: fromPolar - ,isNaN: isNaN - ,isInfinite: isInfinite - ,toString: toString - ,fst: fst - ,snd: snd - ,identity: identity - ,always: always - ,flip: flip - ,curry: curry - ,uncurry: uncurry - ,LT: LT - ,EQ: EQ - ,GT: GT}; - return _elm.Basics.values; -}; -Elm.Char = Elm.Char || {}; -Elm.Char.make = function (_elm) { - "use strict"; - _elm.Char = _elm.Char || {}; - if (_elm.Char.values) - return _elm.Char.values; - var _op = {}, - _N = Elm.Native, - _U = _N.Utils.make(_elm), - _L = _N.List.make(_elm), - $moduleName = "Char", - $Basics = Elm.Basics.make(_elm), - $Native$Char = Elm.Native.Char.make(_elm); - var fromCode = $Native$Char.fromCode; - var toCode = $Native$Char.toCode; - var toLocaleLower = $Native$Char.toLocaleLower; - var toLocaleUpper = $Native$Char.toLocaleUpper; - var toLower = $Native$Char.toLower; - var toUpper = $Native$Char.toUpper; - var isBetween = F3(function (low, - high, - $char) { - return function () { - var code = toCode($char); - return _U.cmp(code, - toCode(low)) > -1 && _U.cmp(code, - toCode(high)) < 1; - }(); - }); - var isUpper = A2(isBetween, - _U.chr("A"), - _U.chr("Z")); - var isLower = A2(isBetween, - _U.chr("a"), - _U.chr("z")); - var isDigit = A2(isBetween, - _U.chr("0"), - _U.chr("9")); - var isOctDigit = A2(isBetween, - _U.chr("0"), - _U.chr("7")); - var isHexDigit = function ($char) { - return isDigit($char) || (A3(isBetween, - _U.chr("a"), - _U.chr("f"), - $char) || A3(isBetween, - _U.chr("A"), - _U.chr("F"), - $char)); - }; - _elm.Char.values = {_op: _op - ,isUpper: isUpper - ,isLower: isLower - ,isDigit: isDigit - ,isOctDigit: isOctDigit - ,isHexDigit: isHexDigit - ,toUpper: toUpper - ,toLower: toLower - ,toLocaleUpper: toLocaleUpper - ,toLocaleLower: toLocaleLower - ,toCode: toCode - ,fromCode: fromCode}; - return _elm.Char.values; -}; -Elm.Color = Elm.Color || {}; -Elm.Color.make = function (_elm) { - "use strict"; - _elm.Color = _elm.Color || {}; - if (_elm.Color.values) - return _elm.Color.values; - var _op = {}, - _N = Elm.Native, - _U = _N.Utils.make(_elm), - _L = _N.List.make(_elm), - $moduleName = "Color", - $Basics = Elm.Basics.make(_elm); - var Radial = F5(function (a, - b, - c, - d, - e) { - return {ctor: "Radial" - ,_0: a - ,_1: b - ,_2: c - ,_3: d - ,_4: e}; - }); - var radial = Radial; - var Linear = F3(function (a, - b, - c) { - return {ctor: "Linear" - ,_0: a - ,_1: b - ,_2: c}; - }); - var linear = Linear; - var fmod = F2(function (f,n) { - return function () { - var integer = $Basics.floor(f); - return $Basics.toFloat(A2($Basics._op["%"], - integer, - n)) + f - $Basics.toFloat(integer); - }(); - }); - var rgbToHsl = F3(function (red, - green, - blue) { - return function () { - var b = $Basics.toFloat(blue) / 255; - var g = $Basics.toFloat(green) / 255; - var r = $Basics.toFloat(red) / 255; - var cMax = A2($Basics.max, - A2($Basics.max,r,g), - b); - var cMin = A2($Basics.min, - A2($Basics.min,r,g), - b); - var c = cMax - cMin; - var lightness = (cMax + cMin) / 2; - var saturation = _U.eq(lightness, - 0) ? 0 : c / (1 - $Basics.abs(2 * lightness - 1)); - var hue = $Basics.degrees(60) * (_U.eq(cMax, - r) ? A2(fmod, - (g - b) / c, - 6) : _U.eq(cMax, - g) ? (b - r) / c + 2 : _U.eq(cMax, - b) ? (r - g) / c + 4 : _U.badIf($moduleName, - "between lines 150 and 152")); - return {ctor: "_Tuple3" - ,_0: hue - ,_1: saturation - ,_2: lightness}; - }(); - }); - var hslToRgb = F3(function (hue, - saturation, - lightness) { - return function () { - var hue$ = hue / $Basics.degrees(60); - var chroma = (1 - $Basics.abs(2 * lightness - 1)) * saturation; - var x = chroma * (1 - $Basics.abs(A2(fmod, - hue$, - 2) - 1)); - var $ = _U.cmp(hue$, - 0) < 0 ? {ctor: "_Tuple3" - ,_0: 0 - ,_1: 0 - ,_2: 0} : _U.cmp(hue$, - 1) < 0 ? {ctor: "_Tuple3" - ,_0: chroma - ,_1: x - ,_2: 0} : _U.cmp(hue$, - 2) < 0 ? {ctor: "_Tuple3" - ,_0: x - ,_1: chroma - ,_2: 0} : _U.cmp(hue$, - 3) < 0 ? {ctor: "_Tuple3" - ,_0: 0 - ,_1: chroma - ,_2: x} : _U.cmp(hue$, - 4) < 0 ? {ctor: "_Tuple3" - ,_0: 0 - ,_1: x - ,_2: chroma} : _U.cmp(hue$, - 5) < 0 ? {ctor: "_Tuple3" - ,_0: x - ,_1: 0 - ,_2: chroma} : _U.cmp(hue$, - 6) < 0 ? {ctor: "_Tuple3" - ,_0: chroma - ,_1: 0 - ,_2: x} : {ctor: "_Tuple3" - ,_0: 0 - ,_1: 0 - ,_2: 0}, - r = $._0, - g = $._1, - b = $._2; - var m = lightness - chroma / 2; - return {ctor: "_Tuple3" - ,_0: r + m - ,_1: g + m - ,_2: b + m}; - }(); - }); - var toRgb = function (color) { - return function () { - switch (color.ctor) - {case "HSLA": - return function () { - var $ = A3(hslToRgb, - color._0, - color._1, - color._2), - r = $._0, - g = $._1, - b = $._2; - return {_: {} - ,alpha: color._3 - ,blue: $Basics.round(255 * b) - ,green: $Basics.round(255 * g) - ,red: $Basics.round(255 * r)}; - }(); - case "RGBA": return {_: {} - ,alpha: color._3 - ,blue: color._2 - ,green: color._1 - ,red: color._0};} - _U.badCase($moduleName, - "between lines 124 and 132"); - }(); - }; - var toHsl = function (color) { - return function () { - switch (color.ctor) - {case "HSLA": return {_: {} - ,alpha: color._3 - ,hue: color._0 - ,lightness: color._2 - ,saturation: color._1}; - case "RGBA": - return function () { - var $ = A3(rgbToHsl, - color._0, - color._1, - color._2), - h = $._0, - s = $._1, - l = $._2; - return {_: {} - ,alpha: color._3 - ,hue: h - ,lightness: l - ,saturation: s}; - }();} - _U.badCase($moduleName, - "between lines 114 and 118"); - }(); - }; - var HSLA = F4(function (a, - b, - c, - d) { - return {ctor: "HSLA" - ,_0: a - ,_1: b - ,_2: c - ,_3: d}; - }); - var hsla = F4(function (hue, - saturation, - lightness, - alpha) { - return A4(HSLA, - hue - $Basics.turns($Basics.toFloat($Basics.floor(hue / (2 * $Basics.pi)))), - saturation, - lightness, - alpha); - }); - var hsl = F3(function (hue, - saturation, - lightness) { - return A4(hsla, - hue, - saturation, - lightness, - 1); - }); - var complement = function (color) { - return function () { - switch (color.ctor) - {case "HSLA": return A4(hsla, - color._0 + $Basics.degrees(180), - color._1, - color._2, - color._3); - case "RGBA": - return function () { - var $ = A3(rgbToHsl, - color._0, - color._1, - color._2), - h = $._0, - s = $._1, - l = $._2; - return A4(hsla, - h + $Basics.degrees(180), - s, - l, - color._3); - }();} - _U.badCase($moduleName, - "between lines 105 and 108"); - }(); - }; - var grayscale = function (p) { - return A4(HSLA,0,0,1 - p,1); - }; - var greyscale = function (p) { - return A4(HSLA,0,0,1 - p,1); - }; - var RGBA = F4(function (a, - b, - c, - d) { - return {ctor: "RGBA" - ,_0: a - ,_1: b - ,_2: c - ,_3: d}; - }); - var rgba = RGBA; - var rgb = F3(function (r,g,b) { - return A4(RGBA,r,g,b,1); - }); - var lightRed = A4(RGBA, - 239, - 41, - 41, - 1); - var red = A4(RGBA,204,0,0,1); - var darkRed = A4(RGBA, - 164, - 0, - 0, - 1); - var lightOrange = A4(RGBA, - 252, - 175, - 62, - 1); - var orange = A4(RGBA, - 245, - 121, - 0, - 1); - var darkOrange = A4(RGBA, - 206, - 92, - 0, - 1); - var lightYellow = A4(RGBA, - 255, - 233, - 79, - 1); - var yellow = A4(RGBA, - 237, - 212, - 0, - 1); - var darkYellow = A4(RGBA, - 196, - 160, - 0, - 1); - var lightGreen = A4(RGBA, - 138, - 226, - 52, - 1); - var green = A4(RGBA, - 115, - 210, - 22, - 1); - var darkGreen = A4(RGBA, - 78, - 154, - 6, - 1); - var lightBlue = A4(RGBA, - 114, - 159, - 207, - 1); - var blue = A4(RGBA, - 52, - 101, - 164, - 1); - var darkBlue = A4(RGBA, - 32, - 74, - 135, - 1); - var lightPurple = A4(RGBA, - 173, - 127, - 168, - 1); - var purple = A4(RGBA, - 117, - 80, - 123, - 1); - var darkPurple = A4(RGBA, - 92, - 53, - 102, - 1); - var lightBrown = A4(RGBA, - 233, - 185, - 110, - 1); - var brown = A4(RGBA, - 193, - 125, - 17, - 1); - var darkBrown = A4(RGBA, - 143, - 89, - 2, - 1); - var black = A4(RGBA,0,0,0,1); - var white = A4(RGBA, - 255, - 255, - 255, - 1); - var lightGrey = A4(RGBA, - 238, - 238, - 236, - 1); - var grey = A4(RGBA, - 211, - 215, - 207, - 1); - var darkGrey = A4(RGBA, - 186, - 189, - 182, - 1); - var lightGray = A4(RGBA, - 238, - 238, - 236, - 1); - var gray = A4(RGBA, - 211, - 215, - 207, - 1); - var darkGray = A4(RGBA, - 186, - 189, - 182, - 1); - var lightCharcoal = A4(RGBA, - 136, - 138, - 133, - 1); - var charcoal = A4(RGBA, - 85, - 87, - 83, - 1); - var darkCharcoal = A4(RGBA, - 46, - 52, - 54, - 1); - _elm.Color.values = {_op: _op - ,rgb: rgb - ,rgba: rgba - ,hsl: hsl - ,hsla: hsla - ,greyscale: greyscale - ,grayscale: grayscale - ,complement: complement - ,linear: linear - ,radial: radial - ,toRgb: toRgb - ,toHsl: toHsl - ,red: red - ,orange: orange - ,yellow: yellow - ,green: green - ,blue: blue - ,purple: purple - ,brown: brown - ,lightRed: lightRed - ,lightOrange: lightOrange - ,lightYellow: lightYellow - ,lightGreen: lightGreen - ,lightBlue: lightBlue - ,lightPurple: lightPurple - ,lightBrown: lightBrown - ,darkRed: darkRed - ,darkOrange: darkOrange - ,darkYellow: darkYellow - ,darkGreen: darkGreen - ,darkBlue: darkBlue - ,darkPurple: darkPurple - ,darkBrown: darkBrown - ,white: white - ,lightGrey: lightGrey - ,grey: grey - ,darkGrey: darkGrey - ,lightCharcoal: lightCharcoal - ,charcoal: charcoal - ,darkCharcoal: darkCharcoal - ,black: black - ,lightGray: lightGray - ,gray: gray - ,darkGray: darkGray}; - return _elm.Color.values; -}; -Elm.Debug = Elm.Debug || {}; -Elm.Debug.make = function (_elm) { - "use strict"; - _elm.Debug = _elm.Debug || {}; - if (_elm.Debug.values) - return _elm.Debug.values; - var _op = {}, - _N = Elm.Native, - _U = _N.Utils.make(_elm), - _L = _N.List.make(_elm), - $moduleName = "Debug", - $Graphics$Collage = Elm.Graphics.Collage.make(_elm), - $Native$Debug = Elm.Native.Debug.make(_elm); - var trace = $Native$Debug.tracePath; - var watchSummary = $Native$Debug.watchSummary; - var watch = $Native$Debug.watch; - var crash = $Native$Debug.crash; - var log = $Native$Debug.log; - _elm.Debug.values = {_op: _op - ,log: log - ,crash: crash - ,watch: watch - ,watchSummary: watchSummary - ,trace: trace}; - return _elm.Debug.values; -}; -Elm.Dict = Elm.Dict || {}; -Elm.Dict.make = function (_elm) { - "use strict"; - _elm.Dict = _elm.Dict || {}; - if (_elm.Dict.values) - return _elm.Dict.values; - var _op = {}, - _N = Elm.Native, - _U = _N.Utils.make(_elm), - _L = _N.List.make(_elm), - $moduleName = "Dict", - $Basics = Elm.Basics.make(_elm), - $List = Elm.List.make(_elm), - $Maybe = Elm.Maybe.make(_elm), - $Native$Debug = Elm.Native.Debug.make(_elm), - $String = Elm.String.make(_elm); - var foldr = F3(function (f, - acc, - t) { - return function () { - switch (t.ctor) - {case "RBEmpty": - switch (t._0.ctor) - {case "LBlack": return acc;} - break; - case "RBNode": return A3(foldr, - f, - A3(f, - t._1, - t._2, - A3(foldr,f,acc,t._4)), - t._3);} - _U.badCase($moduleName, - "between lines 417 and 421"); - }(); - }); - var keys = function (dict) { - return A3(foldr, - F3(function (key, - value, - keyList) { - return A2($List._op["::"], - key, - keyList); - }), - _L.fromArray([]), - dict); - }; - var values = function (dict) { - return A3(foldr, - F3(function (key, - value, - valueList) { - return A2($List._op["::"], - value, - valueList); - }), - _L.fromArray([]), - dict); - }; - var toList = function (dict) { - return A3(foldr, - F3(function (key,value,list) { - return A2($List._op["::"], - {ctor: "_Tuple2" - ,_0: key - ,_1: value}, - list); - }), - _L.fromArray([]), - dict); - }; - var foldl = F3(function (f, - acc, - dict) { - return function () { - switch (dict.ctor) - {case "RBEmpty": - switch (dict._0.ctor) - {case "LBlack": return acc;} - break; - case "RBNode": return A3(foldl, - f, - A3(f, - dict._1, - dict._2, - A3(foldl,f,acc,dict._3)), - dict._4);} - _U.badCase($moduleName, - "between lines 406 and 410"); - }(); - }); - var isBBlack = function (dict) { - return function () { - switch (dict.ctor) - {case "RBEmpty": - switch (dict._0.ctor) - {case "LBBlack": return true;} - break; - case "RBNode": - switch (dict._0.ctor) - {case "BBlack": return true;} - break;} - return false; - }(); - }; - var showFlag = function (f) { - return function () { - switch (f.ctor) - {case "Insert": return "Insert"; - case "Remove": return "Remove"; - case "Same": return "Same";} - _U.badCase($moduleName, - "between lines 182 and 185"); - }(); - }; - var Same = {ctor: "Same"}; - var Remove = {ctor: "Remove"}; - var Insert = {ctor: "Insert"}; - var get = F2(function (targetKey, - dict) { - return function () { - switch (dict.ctor) - {case "RBEmpty": - switch (dict._0.ctor) - {case "LBlack": - return $Maybe.Nothing;} - break; - case "RBNode": - return function () { - var _v29 = A2($Basics.compare, - targetKey, - dict._1); - switch (_v29.ctor) - {case "EQ": - return $Maybe.Just(dict._2); - case "GT": return A2(get, - targetKey, - dict._4); - case "LT": return A2(get, - targetKey, - dict._3);} - _U.badCase($moduleName, - "between lines 129 and 132"); - }();} - _U.badCase($moduleName, - "between lines 124 and 132"); - }(); - }); - var member = F2(function (key, - dict) { - return function () { - var _v30 = A2(get,key,dict); - switch (_v30.ctor) - {case "Just": return true; - case "Nothing": return false;} - _U.badCase($moduleName, - "between lines 138 and 140"); - }(); - }); - var max = function (dict) { - return function () { - switch (dict.ctor) - {case "RBEmpty": - return $Native$Debug.crash("(max Empty) is not defined"); - case "RBNode": - switch (dict._4.ctor) - {case "RBEmpty": - return {ctor: "_Tuple2" - ,_0: dict._1 - ,_1: dict._2};} - return max(dict._4);} - _U.badCase($moduleName, - "between lines 100 and 108"); - }(); - }; - var min = function (dict) { - return function () { - switch (dict.ctor) - {case "RBEmpty": - switch (dict._0.ctor) - {case "LBlack": - return $Native$Debug.crash("(min Empty) is not defined");} - break; - case "RBNode": - switch (dict._3.ctor) - {case "RBEmpty": - switch (dict._3._0.ctor) - {case "LBlack": - return {ctor: "_Tuple2" - ,_0: dict._1 - ,_1: dict._2};} - break;} - return min(dict._3);} - _U.badCase($moduleName, - "between lines 87 and 95"); - }(); - }; - var RBEmpty = function (a) { - return {ctor: "RBEmpty" - ,_0: a}; - }; - var RBNode = F5(function (a, - b, - c, - d, - e) { - return {ctor: "RBNode" - ,_0: a - ,_1: b - ,_2: c - ,_3: d - ,_4: e}; - }); - var showLColor = function (color) { - return function () { - switch (color.ctor) - {case "LBBlack": - return "LBBlack"; - case "LBlack": return "LBlack";} - _U.badCase($moduleName, - "between lines 70 and 72"); - }(); - }; - var LBBlack = {ctor: "LBBlack"}; - var LBlack = {ctor: "LBlack"}; - var empty = RBEmpty(LBlack); - var isEmpty = function (dict) { - return _U.eq(dict,empty); - }; - var map = F2(function (f,dict) { - return function () { - switch (dict.ctor) - {case "RBEmpty": - switch (dict._0.ctor) - {case "LBlack": - return RBEmpty(LBlack);} - break; - case "RBNode": return A5(RBNode, - dict._0, - dict._1, - A2(f,dict._1,dict._2), - A2(map,f,dict._3), - A2(map,f,dict._4));} - _U.badCase($moduleName, - "between lines 394 and 399"); - }(); - }); - var showNColor = function (c) { - return function () { - switch (c.ctor) - {case "BBlack": return "BBlack"; - case "Black": return "Black"; - case "NBlack": return "NBlack"; - case "Red": return "Red";} - _U.badCase($moduleName, - "between lines 56 and 60"); - }(); - }; - var reportRemBug = F4(function (msg, - c, - lgot, - rgot) { - return $Native$Debug.crash($String.concat(_L.fromArray(["Internal red-black tree invariant violated, expected " - ,msg - ," and got " - ,showNColor(c) - ,"/" - ,lgot - ,"/" - ,rgot - ,"\nPlease report this bug to "]))); - }); - var NBlack = {ctor: "NBlack"}; - var BBlack = {ctor: "BBlack"}; - var Black = {ctor: "Black"}; - var ensureBlackRoot = function (dict) { - return function () { - switch (dict.ctor) - {case "RBEmpty": - switch (dict._0.ctor) - {case "LBlack": return dict;} - break; - case "RBNode": - switch (dict._0.ctor) - {case "Black": return dict; - case "Red": return A5(RBNode, - Black, - dict._1, - dict._2, - dict._3, - dict._4);} - break;} - _U.badCase($moduleName, - "between lines 154 and 162"); - }(); - }; - var blackish = function (t) { - return function () { - switch (t.ctor) - {case "RBEmpty": return true; - case "RBNode": - return _U.eq(t._0, - Black) || _U.eq(t._0,BBlack);} - _U.badCase($moduleName, - "between lines 339 and 341"); - }(); - }; - var blacken = function (t) { - return function () { - switch (t.ctor) - {case "RBEmpty": - return RBEmpty(LBlack); - case "RBNode": return A5(RBNode, - Black, - t._1, - t._2, - t._3, - t._4);} - _U.badCase($moduleName, - "between lines 378 and 380"); - }(); - }; - var Red = {ctor: "Red"}; - var moreBlack = function (color) { - return function () { - switch (color.ctor) - {case "BBlack": - return $Native$Debug.crash("Can\'t make a double black node more black!"); - case "Black": return BBlack; - case "NBlack": return Red; - case "Red": return Black;} - _U.badCase($moduleName, - "between lines 244 and 248"); - }(); - }; - var lessBlack = function (color) { - return function () { - switch (color.ctor) - {case "BBlack": return Black; - case "Black": return Red; - case "NBlack": - return $Native$Debug.crash("Can\'t make a negative black node less black!"); - case "Red": return NBlack;} - _U.badCase($moduleName, - "between lines 253 and 257"); - }(); - }; - var lessBlackTree = function (dict) { - return function () { - switch (dict.ctor) - {case "RBEmpty": - switch (dict._0.ctor) - {case "LBBlack": - return RBEmpty(LBlack);} - break; - case "RBNode": return A5(RBNode, - lessBlack(dict._0), - dict._1, - dict._2, - dict._3, - dict._4);} - _U.badCase($moduleName, - "between lines 262 and 264"); - }(); - }; - var redden = function (t) { - return function () { - switch (t.ctor) - {case "RBEmpty": - return $Native$Debug.crash("can\'t make a Leaf red"); - case "RBNode": return A5(RBNode, - Red, - t._1, - t._2, - t._3, - t._4);} - _U.badCase($moduleName, - "between lines 386 and 388"); - }(); - }; - var balance_node = function (t) { - return function () { - var assemble = function (col) { - return function (xk) { - return function (xv) { - return function (yk) { - return function (yv) { - return function (zk) { - return function (zv) { - return function (a) { - return function (b) { - return function (c) { - return function (d) { - return A5(RBNode, - lessBlack(col), - yk, - yv, - A5(RBNode,Black,xk,xv,a,b), - A5(RBNode,Black,zk,zv,c,d)); - }; - }; - }; - }; - }; - }; - }; - }; - }; - }; - }; - return blackish(t) ? function () { - switch (t.ctor) - {case "RBNode": - switch (t._3.ctor) - {case "RBNode": - switch (t._3._0.ctor) - {case "Red": - switch (t._3._3.ctor) - {case "RBNode": - switch (t._3._3._0.ctor) - {case "Red": - return assemble(t._0)(t._3._3._1)(t._3._3._2)(t._3._1)(t._3._2)(t._1)(t._2)(t._3._3._3)(t._3._3._4)(t._3._4)(t._4);} - break;} - switch (t._3._4.ctor) - {case "RBNode": - switch (t._3._4._0.ctor) - {case "Red": - return assemble(t._0)(t._3._1)(t._3._2)(t._3._4._1)(t._3._4._2)(t._1)(t._2)(t._3._3)(t._3._4._3)(t._3._4._4)(t._4);} - break;} - break;} - break;} - switch (t._4.ctor) - {case "RBNode": - switch (t._4._0.ctor) - {case "Red": - switch (t._4._3.ctor) - {case "RBNode": - switch (t._4._3._0.ctor) - {case "Red": - return assemble(t._0)(t._1)(t._2)(t._4._3._1)(t._4._3._2)(t._4._1)(t._4._2)(t._3)(t._4._3._3)(t._4._3._4)(t._4._4);} - break;} - switch (t._4._4.ctor) - {case "RBNode": - switch (t._4._4._0.ctor) - {case "Red": - return assemble(t._0)(t._1)(t._2)(t._4._1)(t._4._2)(t._4._4._1)(t._4._4._2)(t._3)(t._4._3)(t._4._4._3)(t._4._4._4);} - break;} - break;} - break;} - switch (t._0.ctor) - {case "BBlack": - switch (t._4.ctor) - {case "RBNode": - switch (t._4._0.ctor) - {case "NBlack": - switch (t._4._3.ctor) - {case "RBNode": - switch (t._4._3._0.ctor) - {case "Black": - return function () { - switch (t._4._4.ctor) - {case "RBNode": - switch (t._4._4._0.ctor) - {case "Black": - return A5(RBNode, - Black, - t._4._3._1, - t._4._3._2, - A5(RBNode, - Black, - t._1, - t._2, - t._3, - t._4._3._3), - A5(balance, - Black, - t._4._1, - t._4._2, - t._4._3._4, - redden(t._4._4)));} - break;} - return t; - }();} - break;} - break;} - break;} - switch (t._3.ctor) - {case "RBNode": - switch (t._3._0.ctor) - {case "NBlack": - switch (t._3._4.ctor) - {case "RBNode": - switch (t._3._4._0.ctor) - {case "Black": - return function () { - switch (t._3._3.ctor) - {case "RBNode": - switch (t._3._3._0.ctor) - {case "Black": - return A5(RBNode, - Black, - t._3._4._1, - t._3._4._2, - A5(balance, - Black, - t._3._1, - t._3._2, - redden(t._3._3), - t._3._4._3), - A5(RBNode, - Black, - t._1, - t._2, - t._3._4._4, - t._4));} - break;} - return t; - }();} - break;} - break;} - break;} - break;} - break;} - return t; - }() : t; - }(); - }; - var balance = F5(function (c, - k, - v, - l, - r) { - return balance_node(A5(RBNode, - c, - k, - v, - l, - r)); - }); - var bubble = F5(function (c, - k, - v, - l, - r) { - return isBBlack(l) || isBBlack(r) ? A5(balance, - moreBlack(c), - k, - v, - lessBlackTree(l), - lessBlackTree(r)) : A5(RBNode, - c, - k, - v, - l, - r); - }); - var remove_max = F5(function (c, - k, - v, - l, - r) { - return function () { - switch (r.ctor) - {case "RBEmpty": return A3(rem, - c, - l, - r); - case "RBNode": return A5(bubble, - c, - k, - v, - l, - A5(remove_max, - r._0, - r._1, - r._2, - r._3, - r._4));} - _U.badCase($moduleName, - "between lines 323 and 328"); - }(); - }); - var rem = F3(function (c,l,r) { - return function () { - var _v169 = {ctor: "_Tuple2" - ,_0: l - ,_1: r}; - switch (_v169.ctor) - {case "_Tuple2": - switch (_v169._0.ctor) - {case "RBEmpty": - switch (_v169._1.ctor) - {case "RBEmpty": - return function () { - switch (c.ctor) - {case "Black": - return RBEmpty(LBBlack); - case "Red": - return RBEmpty(LBlack);} - _U.badCase($moduleName, - "between lines 282 and 286"); - }(); - case "RBNode": - return function () { - var _v191 = {ctor: "_Tuple3" - ,_0: c - ,_1: _v169._0._0 - ,_2: _v169._1._0}; - switch (_v191.ctor) - {case "_Tuple3": - switch (_v191._0.ctor) - {case "Black": - switch (_v191._1.ctor) - {case "LBlack": - switch (_v191._2.ctor) - {case "Red": return A5(RBNode, - Black, - _v169._1._1, - _v169._1._2, - _v169._1._3, - _v169._1._4);} - break;} - break;} - break;} - return A4(reportRemBug, - "Black/LBlack/Red", - c, - showLColor(_v169._0._0), - showNColor(_v169._1._0)); - }();} - break; - case "RBNode": - switch (_v169._1.ctor) - {case "RBEmpty": - return function () { - var _v195 = {ctor: "_Tuple3" - ,_0: c - ,_1: _v169._0._0 - ,_2: _v169._1._0}; - switch (_v195.ctor) - {case "_Tuple3": - switch (_v195._0.ctor) - {case "Black": - switch (_v195._1.ctor) - {case "Red": - switch (_v195._2.ctor) - {case "LBlack": - return A5(RBNode, - Black, - _v169._0._1, - _v169._0._2, - _v169._0._3, - _v169._0._4);} - break;} - break;} - break;} - return A4(reportRemBug, - "Black/Red/LBlack", - c, - showNColor(_v169._0._0), - showLColor(_v169._1._0)); - }(); - case "RBNode": - return function () { - var l$ = A5(remove_max, - _v169._0._0, - _v169._0._1, - _v169._0._2, - _v169._0._3, - _v169._0._4); - var r = A5(RBNode, - _v169._1._0, - _v169._1._1, - _v169._1._2, - _v169._1._3, - _v169._1._4); - var l = A5(RBNode, - _v169._0._0, - _v169._0._1, - _v169._0._2, - _v169._0._3, - _v169._0._4); - var $ = max(l), - k = $._0, - v = $._1; - return A5(bubble,c,k,v,l$,r); - }();} - break;} - break;} - _U.badCase($moduleName, - "between lines 280 and 309"); - }(); - }); - var update = F3(function (k, - alter, - dict) { - return function () { - var up = function (dict) { - return function () { - switch (dict.ctor) - {case "RBEmpty": - switch (dict._0.ctor) - {case "LBlack": - return function () { - var _v206 = alter($Maybe.Nothing); - switch (_v206.ctor) - {case "Just": - return {ctor: "_Tuple2" - ,_0: Insert - ,_1: A5(RBNode, - Red, - k, - _v206._0, - empty, - empty)}; - case "Nothing": - return {ctor: "_Tuple2" - ,_0: Same - ,_1: empty};} - _U.badCase($moduleName, - "between lines 194 and 198"); - }();} - break; - case "RBNode": - return function () { - var _v208 = A2($Basics.compare, - k, - dict._1); - switch (_v208.ctor) - {case "EQ": return function () { - var _v209 = alter($Maybe.Just(dict._2)); - switch (_v209.ctor) - {case "Just": - return {ctor: "_Tuple2" - ,_0: Same - ,_1: A5(RBNode, - dict._0, - dict._1, - _v209._0, - dict._3, - dict._4)}; - case "Nothing": - return {ctor: "_Tuple2" - ,_0: Remove - ,_1: A3(rem, - dict._0, - dict._3, - dict._4)};} - _U.badCase($moduleName, - "between lines 201 and 206"); - }(); - case "GT": return function () { - var $ = up(dict._4), - flag = $._0, - newRight = $._1; - return function () { - switch (flag.ctor) - {case "Insert": - return {ctor: "_Tuple2" - ,_0: Insert - ,_1: A5(balance, - dict._0, - dict._1, - dict._2, - dict._3, - newRight)}; - case "Remove": - return {ctor: "_Tuple2" - ,_0: Remove - ,_1: A5(bubble, - dict._0, - dict._1, - dict._2, - dict._3, - newRight)}; - case "Same": - return {ctor: "_Tuple2" - ,_0: Same - ,_1: A5(RBNode, - dict._0, - dict._1, - dict._2, - dict._3, - newRight)};} - _U.badCase($moduleName, - "between lines 215 and 220"); - }(); - }(); - case "LT": return function () { - var $ = up(dict._3), - flag = $._0, - newLeft = $._1; - return function () { - switch (flag.ctor) - {case "Insert": - return {ctor: "_Tuple2" - ,_0: Insert - ,_1: A5(balance, - dict._0, - dict._1, - dict._2, - newLeft, - dict._4)}; - case "Remove": - return {ctor: "_Tuple2" - ,_0: Remove - ,_1: A5(bubble, - dict._0, - dict._1, - dict._2, - newLeft, - dict._4)}; - case "Same": - return {ctor: "_Tuple2" - ,_0: Same - ,_1: A5(RBNode, - dict._0, - dict._1, - dict._2, - newLeft, - dict._4)};} - _U.badCase($moduleName, - "between lines 208 and 213"); - }(); - }();} - _U.badCase($moduleName, - "between lines 199 and 220"); - }();} - _U.badCase($moduleName, - "between lines 192 and 220"); - }(); - }; - var $ = up(dict), - flag = $._0, - updatedDict = $._1; - return function () { - switch (flag.ctor) - {case "Insert": - return ensureBlackRoot(updatedDict); - case "Remove": - return blacken(updatedDict); - case "Same": - return updatedDict;} - _U.badCase($moduleName, - "between lines 222 and 225"); - }(); - }(); - }); - var insert = F3(function (key, - value, - dict) { - return A3(update, - key, - $Basics.always($Maybe.Just(value)), - dict); - }); - var singleton = F2(function (key, - value) { - return A3(insert, - key, - value, - empty); - }); - var union = F2(function (t1, - t2) { - return A3(foldl, - insert, - t2, - t1); - }); - var fromList = function (assocs) { - return A3($List.foldl, - F2(function (_v214,dict) { - return function () { - switch (_v214.ctor) - {case "_Tuple2": - return A3(insert, - _v214._0, - _v214._1, - dict);} - _U.badCase($moduleName, - "on line 466, column 38 to 59"); - }(); - }), - empty, - assocs); - }; - var filter = F2(function (predicate, - dictionary) { - return function () { - var add = F3(function (key, - value, - dict) { - return A2(predicate, - key, - value) ? A3(insert, - key, - value, - dict) : dict; - }); - return A3(foldl, - add, - empty, - dictionary); - }(); - }); - var intersect = F2(function (t1, - t2) { - return A2(filter, - F2(function (k,_v218) { - return function () { - return A2(member,k,t2); - }(); - }), - t1); - }); - var partition = F2(function (predicate, - dict) { - return function () { - var add = F3(function (key, - value, - _v220) { - return function () { - switch (_v220.ctor) - {case "_Tuple2": - return A2(predicate, - key, - value) ? {ctor: "_Tuple2" - ,_0: A3(insert, - key, - value, - _v220._0) - ,_1: _v220._1} : {ctor: "_Tuple2" - ,_0: _v220._0 - ,_1: A3(insert, - key, - value, - _v220._1)};} - _U.badCase($moduleName, - "between lines 487 and 489"); - }(); - }); - return A3(foldl, - add, - {ctor: "_Tuple2" - ,_0: empty - ,_1: empty}, - dict); - }(); - }); - var remove = F2(function (key, - dict) { - return A3(update, - key, - $Basics.always($Maybe.Nothing), - dict); - }); - var diff = F2(function (t1,t2) { - return A3(foldl, - F3(function (k,v,t) { - return A2(remove,k,t); - }), - t1, - t2); - }); - _elm.Dict.values = {_op: _op - ,empty: empty - ,singleton: singleton - ,insert: insert - ,update: update - ,isEmpty: isEmpty - ,get: get - ,remove: remove - ,member: member - ,filter: filter - ,partition: partition - ,foldl: foldl - ,foldr: foldr - ,map: map - ,union: union - ,intersect: intersect - ,diff: diff - ,keys: keys - ,values: values - ,toList: toList - ,fromList: fromList}; - return _elm.Dict.values; -}; -Elm.Effects = Elm.Effects || {}; -Elm.Effects.make = function (_elm) { - "use strict"; - _elm.Effects = _elm.Effects || {}; - if (_elm.Effects.values) - return _elm.Effects.values; - var _op = {}, - _N = Elm.Native, - _U = _N.Utils.make(_elm), - _L = _N.List.make(_elm), - $moduleName = "Effects", - $Basics = Elm.Basics.make(_elm), - $List = Elm.List.make(_elm), - $Maybe = Elm.Maybe.make(_elm), - $Native$Effects = Elm.Native.Effects.make(_elm), - $Result = Elm.Result.make(_elm), - $Signal = Elm.Signal.make(_elm), - $Task = Elm.Task.make(_elm), - $Time = Elm.Time.make(_elm); - var ignore = function (task) { - return A2($Task.map, - $Basics.always({ctor: "_Tuple0"}), - task); - }; - var requestTickSending = $Native$Effects.requestTickSending; - var toTaskHelp = F3(function (address, - effect, - _v0) { - return function () { - switch (_v0.ctor) - {case "_Tuple2": - return function () { - switch (effect.ctor) - {case "Batch": - return A3($List.foldl, - toTaskHelp(address), - _v0, - effect._0); - case "None": return _v0; - case "Task": - return function () { - var reporter = A2($Task.andThen, - effect._0, - function (answer) { - return A2($Signal.send, - address, - _L.fromArray([answer])); - }); - return {ctor: "_Tuple2" - ,_0: A2($Task.andThen, - _v0._0, - $Basics.always(ignore($Task.spawn(reporter)))) - ,_1: _v0._1}; - }(); - case "Tick": - return {ctor: "_Tuple2" - ,_0: _v0._0 - ,_1: A2($List._op["::"], - effect._0, - _v0._1)};} - _U.badCase($moduleName, - "between lines 181 and 200"); - }();} - _U.badCase($moduleName, - "between lines 181 and 200"); - }(); - }); - var toTask = F2(function (address, - effect) { - return function () { - var $ = A3(toTaskHelp, - address, - effect, - {ctor: "_Tuple2" - ,_0: $Task.succeed({ctor: "_Tuple0"}) - ,_1: _L.fromArray([])}), - combinedTask = $._0, - tickMessages = $._1; - return $List.isEmpty(tickMessages) ? combinedTask : A2($Task.andThen, - combinedTask, - $Basics.always(A2(requestTickSending, - address, - tickMessages))); - }(); - }); - var Never = function (a) { - return {ctor: "Never",_0: a}; - }; - var Batch = function (a) { - return {ctor: "Batch",_0: a}; - }; - var batch = Batch; - var None = {ctor: "None"}; - var none = None; - var Tick = function (a) { - return {ctor: "Tick",_0: a}; - }; - var tick = Tick; - var Task = function (a) { - return {ctor: "Task",_0: a}; - }; - var task = Task; - var map = F2(function (func, - effect) { - return function () { - switch (effect.ctor) - {case "Batch": - return Batch(A2($List.map, - map(func), - effect._0)); - case "None": return None; - case "Task": - return Task(A2($Task.map, - func, - effect._0)); - case "Tick": - return Tick(function ($) { - return func(effect._0($)); - });} - _U.badCase($moduleName, - "between lines 136 and 147"); - }(); - }); - _elm.Effects.values = {_op: _op - ,none: none - ,task: task - ,tick: tick - ,map: map - ,batch: batch - ,toTask: toTask}; - return _elm.Effects.values; -}; -Elm.Graphics = Elm.Graphics || {}; -Elm.Graphics.Collage = Elm.Graphics.Collage || {}; -Elm.Graphics.Collage.make = function (_elm) { - "use strict"; - _elm.Graphics = _elm.Graphics || {}; - _elm.Graphics.Collage = _elm.Graphics.Collage || {}; - if (_elm.Graphics.Collage.values) - return _elm.Graphics.Collage.values; - var _op = {}, - _N = Elm.Native, - _U = _N.Utils.make(_elm), - _L = _N.List.make(_elm), - $moduleName = "Graphics.Collage", - $Basics = Elm.Basics.make(_elm), - $Color = Elm.Color.make(_elm), - $Graphics$Element = Elm.Graphics.Element.make(_elm), - $List = Elm.List.make(_elm), - $Native$Graphics$Collage = Elm.Native.Graphics.Collage.make(_elm), - $Text = Elm.Text.make(_elm), - $Transform2D = Elm.Transform2D.make(_elm); - var ngon = F2(function (n,r) { - return function () { - var m = $Basics.toFloat(n); - var t = 2 * $Basics.pi / m; - var f = function (i) { - return {ctor: "_Tuple2" - ,_0: r * $Basics.cos(t * i) - ,_1: r * $Basics.sin(t * i)}; - }; - return A2($List.map, - f, - _L.range(0,m - 1)); - }(); - }); - var oval = F2(function (w,h) { - return function () { - var hh = h / 2; - var hw = w / 2; - var n = 50; - var t = 2 * $Basics.pi / n; - var f = function (i) { - return {ctor: "_Tuple2" - ,_0: hw * $Basics.cos(t * i) - ,_1: hh * $Basics.sin(t * i)}; - }; - return A2($List.map, - f, - _L.range(0,n - 1)); - }(); - }); - var circle = function (r) { - return A2(oval,2 * r,2 * r); - }; - var rect = F2(function (w,h) { - return function () { - var hh = h / 2; - var hw = w / 2; - return _L.fromArray([{ctor: "_Tuple2" - ,_0: 0 - hw - ,_1: 0 - hh} - ,{ctor: "_Tuple2" - ,_0: 0 - hw - ,_1: hh} - ,{ctor: "_Tuple2",_0: hw,_1: hh} - ,{ctor: "_Tuple2" - ,_0: hw - ,_1: 0 - hh}]); - }(); - }); - var square = function (n) { - return A2(rect,n,n); - }; - var polygon = function (points) { - return points; - }; - var segment = F2(function (p1, - p2) { - return _L.fromArray([p1,p2]); - }); - var path = function (ps) { - return ps; - }; - var collage = $Native$Graphics$Collage.collage; - var alpha = F2(function (a,f) { - return _U.replace([["alpha" - ,a]], - f); - }); - var rotate = F2(function (t,f) { - return _U.replace([["theta" - ,f.theta + t]], - f); - }); - var scale = F2(function (s,f) { - return _U.replace([["scale" - ,f.scale * s]], - f); - }); - var moveY = F2(function (y,f) { - return _U.replace([["y" - ,f.y + y]], - f); - }); - var moveX = F2(function (x,f) { - return _U.replace([["x" - ,f.x + x]], - f); - }); - var move = F2(function (_v0,f) { - return function () { - switch (_v0.ctor) - {case "_Tuple2": - return _U.replace([["x" - ,f.x + _v0._0] - ,["y",f.y + _v0._1]], - f);} - _U.badCase($moduleName, - "on line 226, column 3 to 37"); - }(); - }); - var form = function (f) { - return {_: {} - ,alpha: 1 - ,form: f - ,scale: 1 - ,theta: 0 - ,x: 0 - ,y: 0}; - }; - var Fill = function (a) { - return {ctor: "Fill",_0: a}; - }; - var Line = function (a) { - return {ctor: "Line",_0: a}; - }; - var FGroup = F2(function (a,b) { - return {ctor: "FGroup" - ,_0: a - ,_1: b}; - }); - var group = function (fs) { - return form(A2(FGroup, - $Transform2D.identity, - fs)); - }; - var groupTransform = F2(function (matrix, - fs) { - return form(A2(FGroup, - matrix, - fs)); - }); - var FElement = function (a) { - return {ctor: "FElement" - ,_0: a}; - }; - var toForm = function (e) { - return form(FElement(e)); - }; - var FImage = F4(function (a, - b, - c, - d) { - return {ctor: "FImage" - ,_0: a - ,_1: b - ,_2: c - ,_3: d}; - }); - var sprite = F4(function (w, - h, - pos, - src) { - return form(A4(FImage, - w, - h, - pos, - src)); - }); - var FText = function (a) { - return {ctor: "FText",_0: a}; - }; - var text = function (t) { - return form(FText(t)); - }; - var FOutlinedText = F2(function (a, - b) { - return {ctor: "FOutlinedText" - ,_0: a - ,_1: b}; - }); - var outlinedText = F2(function (ls, - t) { - return form(A2(FOutlinedText, - ls, - t)); - }); - var FShape = F2(function (a,b) { - return {ctor: "FShape" - ,_0: a - ,_1: b}; - }); - var fill = F2(function (style, - shape) { - return form(A2(FShape, - Fill(style), - shape)); - }); - var outlined = F2(function (style, - shape) { - return form(A2(FShape, - Line(style), - shape)); - }); - var FPath = F2(function (a,b) { - return {ctor: "FPath" - ,_0: a - ,_1: b}; - }); - var traced = F2(function (style, - path) { - return form(A2(FPath, - style, - path)); - }); - var LineStyle = F6(function (a, - b, - c, - d, - e, - f) { - return {_: {} - ,cap: c - ,color: a - ,dashOffset: f - ,dashing: e - ,join: d - ,width: b}; - }); - var Clipped = {ctor: "Clipped"}; - var Sharp = function (a) { - return {ctor: "Sharp",_0: a}; - }; - var Smooth = {ctor: "Smooth"}; - var Padded = {ctor: "Padded"}; - var Round = {ctor: "Round"}; - var Flat = {ctor: "Flat"}; - var defaultLine = {_: {} - ,cap: Flat - ,color: $Color.black - ,dashOffset: 0 - ,dashing: _L.fromArray([]) - ,join: Sharp(10) - ,width: 1}; - var solid = function (clr) { - return _U.replace([["color" - ,clr]], - defaultLine); - }; - var dashed = function (clr) { - return _U.replace([["color" - ,clr] - ,["dashing" - ,_L.fromArray([8,4])]], - defaultLine); - }; - var dotted = function (clr) { - return _U.replace([["color" - ,clr] - ,["dashing" - ,_L.fromArray([3,3])]], - defaultLine); - }; - var Grad = function (a) { - return {ctor: "Grad",_0: a}; - }; - var gradient = F2(function (grad, - shape) { - return A2(fill, - Grad(grad), - shape); - }); - var Texture = function (a) { - return {ctor: "Texture" - ,_0: a}; - }; - var textured = F2(function (src, - shape) { - return A2(fill, - Texture(src), - shape); - }); - var Solid = function (a) { - return {ctor: "Solid",_0: a}; - }; - var filled = F2(function (color, - shape) { - return A2(fill, - Solid(color), - shape); - }); - var Form = F6(function (a, - b, - c, - d, - e, - f) { - return {_: {} - ,alpha: e - ,form: f - ,scale: b - ,theta: a - ,x: c - ,y: d}; - }); - _elm.Graphics.Collage.values = {_op: _op - ,collage: collage - ,toForm: toForm - ,filled: filled - ,textured: textured - ,gradient: gradient - ,outlined: outlined - ,traced: traced - ,text: text - ,outlinedText: outlinedText - ,move: move - ,moveX: moveX - ,moveY: moveY - ,scale: scale - ,rotate: rotate - ,alpha: alpha - ,group: group - ,groupTransform: groupTransform - ,rect: rect - ,oval: oval - ,square: square - ,circle: circle - ,ngon: ngon - ,polygon: polygon - ,segment: segment - ,path: path - ,solid: solid - ,dashed: dashed - ,dotted: dotted - ,defaultLine: defaultLine - ,Form: Form - ,LineStyle: LineStyle - ,Flat: Flat - ,Round: Round - ,Padded: Padded - ,Smooth: Smooth - ,Sharp: Sharp - ,Clipped: Clipped}; - return _elm.Graphics.Collage.values; -}; -Elm.Graphics = Elm.Graphics || {}; -Elm.Graphics.Element = Elm.Graphics.Element || {}; -Elm.Graphics.Element.make = function (_elm) { - "use strict"; - _elm.Graphics = _elm.Graphics || {}; - _elm.Graphics.Element = _elm.Graphics.Element || {}; - if (_elm.Graphics.Element.values) - return _elm.Graphics.Element.values; - var _op = {}, - _N = Elm.Native, - _U = _N.Utils.make(_elm), - _L = _N.List.make(_elm), - $moduleName = "Graphics.Element", - $Basics = Elm.Basics.make(_elm), - $Color = Elm.Color.make(_elm), - $List = Elm.List.make(_elm), - $Maybe = Elm.Maybe.make(_elm), - $Native$Graphics$Element = Elm.Native.Graphics.Element.make(_elm), - $Text = Elm.Text.make(_elm); - var DOut = {ctor: "DOut"}; - var outward = DOut; - var DIn = {ctor: "DIn"}; - var inward = DIn; - var DRight = {ctor: "DRight"}; - var right = DRight; - var DLeft = {ctor: "DLeft"}; - var left = DLeft; - var DDown = {ctor: "DDown"}; - var down = DDown; - var DUp = {ctor: "DUp"}; - var up = DUp; - var Position = F4(function (a, - b, - c, - d) { - return {_: {} - ,horizontal: a - ,vertical: b - ,x: c - ,y: d}; - }); - var Relative = function (a) { - return {ctor: "Relative" - ,_0: a}; - }; - var relative = Relative; - var Absolute = function (a) { - return {ctor: "Absolute" - ,_0: a}; - }; - var absolute = Absolute; - var N = {ctor: "N"}; - var bottomLeftAt = F2(function (x, - y) { - return {_: {} - ,horizontal: N - ,vertical: N - ,x: x - ,y: y}; - }); - var Z = {ctor: "Z"}; - var middle = {_: {} - ,horizontal: Z - ,vertical: Z - ,x: Relative(0.5) - ,y: Relative(0.5)}; - var midLeft = _U.replace([["horizontal" - ,N] - ,["x",Absolute(0)]], - middle); - var middleAt = F2(function (x, - y) { - return {_: {} - ,horizontal: Z - ,vertical: Z - ,x: x - ,y: y}; - }); - var midLeftAt = F2(function (x, - y) { - return {_: {} - ,horizontal: N - ,vertical: Z - ,x: x - ,y: y}; - }); - var midBottomAt = F2(function (x, - y) { - return {_: {} - ,horizontal: Z - ,vertical: N - ,x: x - ,y: y}; - }); - var P = {ctor: "P"}; - var topLeft = {_: {} - ,horizontal: N - ,vertical: P - ,x: Absolute(0) - ,y: Absolute(0)}; - var bottomLeft = _U.replace([["vertical" - ,N]], - topLeft); - var topRight = _U.replace([["horizontal" - ,P]], - topLeft); - var bottomRight = _U.replace([["horizontal" - ,P]], - bottomLeft); - var midRight = _U.replace([["horizontal" - ,P]], - midLeft); - var midTop = _U.replace([["vertical" - ,P] - ,["y",Absolute(0)]], - middle); - var midBottom = _U.replace([["vertical" - ,N]], - midTop); - var topLeftAt = F2(function (x, - y) { - return {_: {} - ,horizontal: N - ,vertical: P - ,x: x - ,y: y}; - }); - var topRightAt = F2(function (x, - y) { - return {_: {} - ,horizontal: P - ,vertical: P - ,x: x - ,y: y}; - }); - var bottomRightAt = F2(function (x, - y) { - return {_: {} - ,horizontal: P - ,vertical: N - ,x: x - ,y: y}; - }); - var midRightAt = F2(function (x, - y) { - return {_: {} - ,horizontal: P - ,vertical: Z - ,x: x - ,y: y}; - }); - var midTopAt = F2(function (x, - y) { - return {_: {} - ,horizontal: Z - ,vertical: P - ,x: x - ,y: y}; - }); - var justified = $Native$Graphics$Element.block("justify"); - var centered = $Native$Graphics$Element.block("center"); - var rightAligned = $Native$Graphics$Element.block("right"); - var leftAligned = $Native$Graphics$Element.block("left"); - var show = function (value) { - return leftAligned($Text.monospace($Text.fromString($Basics.toString(value)))); - }; - var Tiled = {ctor: "Tiled"}; - var Cropped = function (a) { - return {ctor: "Cropped" - ,_0: a}; - }; - var Fitted = {ctor: "Fitted"}; - var Plain = {ctor: "Plain"}; - var Custom = {ctor: "Custom"}; - var RawHtml = {ctor: "RawHtml"}; - var Spacer = {ctor: "Spacer"}; - var Flow = F2(function (a,b) { - return {ctor: "Flow" - ,_0: a - ,_1: b}; - }); - var Container = F2(function (a, - b) { - return {ctor: "Container" - ,_0: a - ,_1: b}; - }); - var Image = F4(function (a, - b, - c, - d) { - return {ctor: "Image" - ,_0: a - ,_1: b - ,_2: c - ,_3: d}; - }); - var newElement = $Native$Graphics$Element.newElement; - var image = F3(function (w, - h, - src) { - return A3(newElement, - w, - h, - A4(Image,Plain,w,h,src)); - }); - var fittedImage = F3(function (w, - h, - src) { - return A3(newElement, - w, - h, - A4(Image,Fitted,w,h,src)); - }); - var croppedImage = F4(function (pos, - w, - h, - src) { - return A3(newElement, - w, - h, - A4(Image,Cropped(pos),w,h,src)); - }); - var tiledImage = F3(function (w, - h, - src) { - return A3(newElement, - w, - h, - A4(Image,Tiled,w,h,src)); - }); - var container = F4(function (w, - h, - pos, - e) { - return A3(newElement, - w, - h, - A2(Container,pos,e)); - }); - var spacer = F2(function (w,h) { - return A3(newElement, - w, - h, - Spacer); - }); - var link = F2(function (href, - e) { - return function () { - var p = e.props; - return {_: {} - ,element: e.element - ,props: _U.replace([["href" - ,href]], - p)}; - }(); - }); - var tag = F2(function (name,e) { - return function () { - var p = e.props; - return {_: {} - ,element: e.element - ,props: _U.replace([["tag" - ,name]], - p)}; - }(); - }); - var color = F2(function (c,e) { - return function () { - var p = e.props; - return {_: {} - ,element: e.element - ,props: _U.replace([["color" - ,$Maybe.Just(c)]], - p)}; - }(); - }); - var opacity = F2(function (o, - e) { - return function () { - var p = e.props; - return {_: {} - ,element: e.element - ,props: _U.replace([["opacity" - ,o]], - p)}; - }(); - }); - var height = F2(function (nh, - e) { - return function () { - var p = e.props; - var props = function () { - var _v0 = e.element; - switch (_v0.ctor) - {case "Image": - return _U.replace([["width" - ,$Basics.round($Basics.toFloat(_v0._1) / $Basics.toFloat(_v0._2) * $Basics.toFloat(nh))]], - p);} - return p; - }(); - return {_: {} - ,element: e.element - ,props: _U.replace([["height" - ,nh]], - p)}; - }(); - }); - var width = F2(function (nw,e) { - return function () { - var p = e.props; - var props = function () { - var _v5 = e.element; - switch (_v5.ctor) - {case "Image": - return _U.replace([["height" - ,$Basics.round($Basics.toFloat(_v5._2) / $Basics.toFloat(_v5._1) * $Basics.toFloat(nw))]], - p); - case "RawHtml": - return _U.replace([["height" - ,$Basics.snd(A2($Native$Graphics$Element.htmlHeight, - nw, - e.element))]], - p);} - return p; - }(); - return {_: {} - ,element: e.element - ,props: _U.replace([["width" - ,nw]], - props)}; - }(); - }); - var size = F3(function (w,h,e) { - return A2(height, - h, - A2(width,w,e)); - }); - var sizeOf = function (e) { - return {ctor: "_Tuple2" - ,_0: e.props.width - ,_1: e.props.height}; - }; - var heightOf = function (e) { - return e.props.height; - }; - var widthOf = function (e) { - return e.props.width; - }; - var above = F2(function (hi, - lo) { - return A3(newElement, - A2($Basics.max, - widthOf(hi), - widthOf(lo)), - heightOf(hi) + heightOf(lo), - A2(Flow, - DDown, - _L.fromArray([hi,lo]))); - }); - var below = F2(function (lo, - hi) { - return A3(newElement, - A2($Basics.max, - widthOf(hi), - widthOf(lo)), - heightOf(hi) + heightOf(lo), - A2(Flow, - DDown, - _L.fromArray([hi,lo]))); - }); - var beside = F2(function (lft, - rht) { - return A3(newElement, - widthOf(lft) + widthOf(rht), - A2($Basics.max, - heightOf(lft), - heightOf(rht)), - A2(Flow, - right, - _L.fromArray([lft,rht]))); - }); - var layers = function (es) { - return function () { - var hs = A2($List.map, - heightOf, - es); - var ws = A2($List.map, - widthOf, - es); - return A3(newElement, - A2($Maybe.withDefault, - 0, - $List.maximum(ws)), - A2($Maybe.withDefault, - 0, - $List.maximum(hs)), - A2(Flow,DOut,es)); - }(); - }; - var empty = A2(spacer,0,0); - var flow = F2(function (dir, - es) { - return function () { - var newFlow = F2(function (w, - h) { - return A3(newElement, - w, - h, - A2(Flow,dir,es)); - }); - var maxOrZero = function (list) { - return A2($Maybe.withDefault, - 0, - $List.maximum(list)); - }; - var hs = A2($List.map, - heightOf, - es); - var ws = A2($List.map, - widthOf, - es); - return _U.eq(es, - _L.fromArray([])) ? empty : function () { - switch (dir.ctor) - {case "DDown": - return A2(newFlow, - maxOrZero(ws), - $List.sum(hs)); - case "DIn": return A2(newFlow, - maxOrZero(ws), - maxOrZero(hs)); - case "DLeft": return A2(newFlow, - $List.sum(ws), - maxOrZero(hs)); - case "DOut": return A2(newFlow, - maxOrZero(ws), - maxOrZero(hs)); - case "DRight": - return A2(newFlow, - $List.sum(ws), - maxOrZero(hs)); - case "DUp": return A2(newFlow, - maxOrZero(ws), - $List.sum(hs));} - _U.badCase($moduleName, - "between lines 362 and 368"); - }(); - }(); - }); - var Properties = F9(function (a, - b, - c, - d, - e, - f, - g, - h, - i) { - return {_: {} - ,click: i - ,color: e - ,height: c - ,hover: h - ,href: f - ,id: a - ,opacity: d - ,tag: g - ,width: b}; - }); - var Element = F2(function (a, - b) { - return {_: {} - ,element: b - ,props: a}; - }); - _elm.Graphics.Element.values = {_op: _op - ,image: image - ,fittedImage: fittedImage - ,croppedImage: croppedImage - ,tiledImage: tiledImage - ,leftAligned: leftAligned - ,rightAligned: rightAligned - ,centered: centered - ,justified: justified - ,show: show - ,width: width - ,height: height - ,size: size - ,color: color - ,opacity: opacity - ,link: link - ,tag: tag - ,widthOf: widthOf - ,heightOf: heightOf - ,sizeOf: sizeOf - ,flow: flow - ,up: up - ,down: down - ,left: left - ,right: right - ,inward: inward - ,outward: outward - ,layers: layers - ,above: above - ,below: below - ,beside: beside - ,empty: empty - ,spacer: spacer - ,container: container - ,middle: middle - ,midTop: midTop - ,midBottom: midBottom - ,midLeft: midLeft - ,midRight: midRight - ,topLeft: topLeft - ,topRight: topRight - ,bottomLeft: bottomLeft - ,bottomRight: bottomRight - ,absolute: absolute - ,relative: relative - ,middleAt: middleAt - ,midTopAt: midTopAt - ,midBottomAt: midBottomAt - ,midLeftAt: midLeftAt - ,midRightAt: midRightAt - ,topLeftAt: topLeftAt - ,topRightAt: topRightAt - ,bottomLeftAt: bottomLeftAt - ,bottomRightAt: bottomRightAt - ,Element: Element - ,Position: Position}; - return _elm.Graphics.Element.values; -}; -Elm.Html = Elm.Html || {}; -Elm.Html.make = function (_elm) { - "use strict"; - _elm.Html = _elm.Html || {}; - if (_elm.Html.values) - return _elm.Html.values; - var _op = {}, - _N = Elm.Native, - _U = _N.Utils.make(_elm), - _L = _N.List.make(_elm), - $moduleName = "Html", - $Basics = Elm.Basics.make(_elm), - $Graphics$Element = Elm.Graphics.Element.make(_elm), - $List = Elm.List.make(_elm), - $Maybe = Elm.Maybe.make(_elm), - $Result = Elm.Result.make(_elm), - $Signal = Elm.Signal.make(_elm), - $VirtualDom = Elm.VirtualDom.make(_elm); - var fromElement = $VirtualDom.fromElement; - var toElement = $VirtualDom.toElement; - var text = $VirtualDom.text; - var node = $VirtualDom.node; - var body = node("body"); - var section = node("section"); - var nav = node("nav"); - var article = node("article"); - var aside = node("aside"); - var h1 = node("h1"); - var h2 = node("h2"); - var h3 = node("h3"); - var h4 = node("h4"); - var h5 = node("h5"); - var h6 = node("h6"); - var header = node("header"); - var footer = node("footer"); - var address = node("address"); - var main$ = node("main"); - var p = node("p"); - var hr = node("hr"); - var pre = node("pre"); - var blockquote = node("blockquote"); - var ol = node("ol"); - var ul = node("ul"); - var li = node("li"); - var dl = node("dl"); - var dt = node("dt"); - var dd = node("dd"); - var figure = node("figure"); - var figcaption = node("figcaption"); - var div = node("div"); - var a = node("a"); - var em = node("em"); - var strong = node("strong"); - var small = node("small"); - var s = node("s"); - var cite = node("cite"); - var q = node("q"); - var dfn = node("dfn"); - var abbr = node("abbr"); - var time = node("time"); - var code = node("code"); - var $var = node("var"); - var samp = node("samp"); - var kbd = node("kbd"); - var sub = node("sub"); - var sup = node("sup"); - var i = node("i"); - var b = node("b"); - var u = node("u"); - var mark = node("mark"); - var ruby = node("ruby"); - var rt = node("rt"); - var rp = node("rp"); - var bdi = node("bdi"); - var bdo = node("bdo"); - var span = node("span"); - var br = node("br"); - var wbr = node("wbr"); - var ins = node("ins"); - var del = node("del"); - var img = node("img"); - var iframe = node("iframe"); - var embed = node("embed"); - var object = node("object"); - var param = node("param"); - var video = node("video"); - var audio = node("audio"); - var source = node("source"); - var track = node("track"); - var canvas = node("canvas"); - var svg = node("svg"); - var math = node("math"); - var table = node("table"); - var caption = node("caption"); - var colgroup = node("colgroup"); - var col = node("col"); - var tbody = node("tbody"); - var thead = node("thead"); - var tfoot = node("tfoot"); - var tr = node("tr"); - var td = node("td"); - var th = node("th"); - var form = node("form"); - var fieldset = node("fieldset"); - var legend = node("legend"); - var label = node("label"); - var input = node("input"); - var button = node("button"); - var select = node("select"); - var datalist = node("datalist"); - var optgroup = node("optgroup"); - var option = node("option"); - var textarea = node("textarea"); - var keygen = node("keygen"); - var output = node("output"); - var progress = node("progress"); - var meter = node("meter"); - var details = node("details"); - var summary = node("summary"); - var menuitem = node("menuitem"); - var menu = node("menu"); - _elm.Html.values = {_op: _op - ,node: node - ,text: text - ,toElement: toElement - ,fromElement: fromElement - ,body: body - ,section: section - ,nav: nav - ,article: article - ,aside: aside - ,h1: h1 - ,h2: h2 - ,h3: h3 - ,h4: h4 - ,h5: h5 - ,h6: h6 - ,header: header - ,footer: footer - ,address: address - ,main$: main$ - ,p: p - ,hr: hr - ,pre: pre - ,blockquote: blockquote - ,ol: ol - ,ul: ul - ,li: li - ,dl: dl - ,dt: dt - ,dd: dd - ,figure: figure - ,figcaption: figcaption - ,div: div - ,a: a - ,em: em - ,strong: strong - ,small: small - ,s: s - ,cite: cite - ,q: q - ,dfn: dfn - ,abbr: abbr - ,time: time - ,code: code - ,$var: $var - ,samp: samp - ,kbd: kbd - ,sub: sub - ,sup: sup - ,i: i - ,b: b - ,u: u - ,mark: mark - ,ruby: ruby - ,rt: rt - ,rp: rp - ,bdi: bdi - ,bdo: bdo - ,span: span - ,br: br - ,wbr: wbr - ,ins: ins - ,del: del - ,img: img - ,iframe: iframe - ,embed: embed - ,object: object - ,param: param - ,video: video - ,audio: audio - ,source: source - ,track: track - ,canvas: canvas - ,svg: svg - ,math: math - ,table: table - ,caption: caption - ,colgroup: colgroup - ,col: col - ,tbody: tbody - ,thead: thead - ,tfoot: tfoot - ,tr: tr - ,td: td - ,th: th - ,form: form - ,fieldset: fieldset - ,legend: legend - ,label: label - ,input: input - ,button: button - ,select: select - ,datalist: datalist - ,optgroup: optgroup - ,option: option - ,textarea: textarea - ,keygen: keygen - ,output: output - ,progress: progress - ,meter: meter - ,details: details - ,summary: summary - ,menuitem: menuitem - ,menu: menu}; - return _elm.Html.values; -}; -Elm.Html = Elm.Html || {}; -Elm.Html.Attributes = Elm.Html.Attributes || {}; -Elm.Html.Attributes.make = function (_elm) { - "use strict"; - _elm.Html = _elm.Html || {}; - _elm.Html.Attributes = _elm.Html.Attributes || {}; - if (_elm.Html.Attributes.values) - return _elm.Html.Attributes.values; - var _op = {}, - _N = Elm.Native, - _U = _N.Utils.make(_elm), - _L = _N.List.make(_elm), - $moduleName = "Html.Attributes", - $Basics = Elm.Basics.make(_elm), - $Html = Elm.Html.make(_elm), - $Json$Encode = Elm.Json.Encode.make(_elm), - $List = Elm.List.make(_elm), - $Maybe = Elm.Maybe.make(_elm), - $Result = Elm.Result.make(_elm), - $Signal = Elm.Signal.make(_elm), - $String = Elm.String.make(_elm), - $VirtualDom = Elm.VirtualDom.make(_elm); - var attribute = $VirtualDom.attribute; - var property = $VirtualDom.property; - var stringProperty = F2(function (name, - string) { - return A2(property, - name, - $Json$Encode.string(string)); - }); - var $class = function (name) { - return A2(stringProperty, - "className", - name); - }; - var id = function (name) { - return A2(stringProperty, - "id", - name); - }; - var title = function (name) { - return A2(stringProperty, - "title", - name); - }; - var accesskey = function ($char) { - return A2(stringProperty, - "accesskey", - $String.fromList(_L.fromArray([$char]))); - }; - var contextmenu = function (value) { - return A2(stringProperty, - "contextmenu", - value); - }; - var dir = function (value) { - return A2(stringProperty, - "dir", - value); - }; - var draggable = function (value) { - return A2(stringProperty, - "draggable", - value); - }; - var dropzone = function (value) { - return A2(stringProperty, - "dropzone", - value); - }; - var itemprop = function (value) { - return A2(stringProperty, - "itemprop", - value); - }; - var lang = function (value) { - return A2(stringProperty, - "lang", - value); - }; - var tabindex = function (n) { - return A2(stringProperty, - "tabIndex", - $Basics.toString(n)); - }; - var charset = function (value) { - return A2(stringProperty, - "charset", - value); - }; - var content = function (value) { - return A2(stringProperty, - "content", - value); - }; - var httpEquiv = function (value) { - return A2(stringProperty, - "httpEquiv", - value); - }; - var language = function (value) { - return A2(stringProperty, - "language", - value); - }; - var src = function (value) { - return A2(stringProperty, - "src", - value); - }; - var height = function (value) { - return A2(stringProperty, - "height", - $Basics.toString(value)); - }; - var width = function (value) { - return A2(stringProperty, - "width", - $Basics.toString(value)); - }; - var alt = function (value) { - return A2(stringProperty, - "alt", - value); - }; - var preload = function (value) { - return A2(stringProperty, - "preload", - value); - }; - var poster = function (value) { - return A2(stringProperty, - "poster", - value); - }; - var kind = function (value) { - return A2(stringProperty, - "kind", - value); - }; - var srclang = function (value) { - return A2(stringProperty, - "srclang", - value); - }; - var sandbox = function (value) { - return A2(stringProperty, - "sandbox", - value); - }; - var srcdoc = function (value) { - return A2(stringProperty, - "srcdoc", - value); - }; - var type$ = function (value) { - return A2(stringProperty, - "type", - value); - }; - var value = function (value) { - return A2(stringProperty, - "value", - value); - }; - var placeholder = function (value) { - return A2(stringProperty, - "placeholder", - value); - }; - var accept = function (value) { - return A2(stringProperty, - "accept", - value); - }; - var acceptCharset = function (value) { - return A2(stringProperty, - "acceptCharset", - value); - }; - var action = function (value) { - return A2(stringProperty, - "action", - value); - }; - var autocomplete = function (bool) { - return A2(stringProperty, - "autocomplete", - bool ? "on" : "off"); - }; - var autosave = function (value) { - return A2(stringProperty, - "autosave", - value); - }; - var enctype = function (value) { - return A2(stringProperty, - "enctype", - value); - }; - var formaction = function (value) { - return A2(stringProperty, - "formaction", - value); - }; - var list = function (value) { - return A2(stringProperty, - "list", - value); - }; - var minlength = function (n) { - return A2(stringProperty, - "minLength", - $Basics.toString(n)); - }; - var maxlength = function (n) { - return A2(stringProperty, - "maxLength", - $Basics.toString(n)); - }; - var method = function (value) { - return A2(stringProperty, - "method", - value); - }; - var name = function (value) { - return A2(stringProperty, - "name", - value); - }; - var pattern = function (value) { - return A2(stringProperty, - "pattern", - value); - }; - var size = function (n) { - return A2(stringProperty, - "size", - $Basics.toString(n)); - }; - var $for = function (value) { - return A2(stringProperty, - "htmlFor", - value); - }; - var form = function (value) { - return A2(stringProperty, - "form", - value); - }; - var max = function (value) { - return A2(stringProperty, - "max", - value); - }; - var min = function (value) { - return A2(stringProperty, - "min", - value); - }; - var step = function (n) { - return A2(stringProperty, - "step", - n); - }; - var cols = function (n) { - return A2(stringProperty, - "cols", - $Basics.toString(n)); - }; - var rows = function (n) { - return A2(stringProperty, - "rows", - $Basics.toString(n)); - }; - var wrap = function (value) { - return A2(stringProperty, - "wrap", - value); - }; - var usemap = function (value) { - return A2(stringProperty, - "useMap", - value); - }; - var shape = function (value) { - return A2(stringProperty, - "shape", - value); - }; - var coords = function (value) { - return A2(stringProperty, - "coords", - value); - }; - var challenge = function (value) { - return A2(stringProperty, - "challenge", - value); - }; - var keytype = function (value) { - return A2(stringProperty, - "keytype", - value); - }; - var align = function (value) { - return A2(stringProperty, - "align", - value); - }; - var cite = function (value) { - return A2(stringProperty, - "cite", - value); - }; - var href = function (value) { - return A2(stringProperty, - "href", - value); - }; - var target = function (value) { - return A2(stringProperty, - "target", - value); - }; - var downloadAs = function (value) { - return A2(stringProperty, - "download", - value); - }; - var hreflang = function (value) { - return A2(stringProperty, - "hreflang", - value); - }; - var media = function (value) { - return A2(stringProperty, - "media", - value); - }; - var ping = function (value) { - return A2(stringProperty, - "ping", - value); - }; - var rel = function (value) { - return A2(stringProperty, - "rel", - value); - }; - var datetime = function (value) { - return A2(stringProperty, - "datetime", - value); - }; - var pubdate = function (value) { - return A2(stringProperty, - "pubdate", - value); - }; - var start = function (n) { - return A2(stringProperty, - "start", - $Basics.toString(n)); - }; - var colspan = function (n) { - return A2(stringProperty, - "colSpan", - $Basics.toString(n)); - }; - var headers = function (value) { - return A2(stringProperty, - "headers", - value); - }; - var rowspan = function (n) { - return A2(stringProperty, - "rowSpan", - $Basics.toString(n)); - }; - var scope = function (value) { - return A2(stringProperty, - "scope", - value); - }; - var manifest = function (value) { - return A2(stringProperty, - "manifest", - value); - }; - var boolProperty = F2(function (name, - bool) { - return A2(property, - name, - $Json$Encode.bool(bool)); - }); - var hidden = function (bool) { - return A2(boolProperty, - "hidden", - bool); - }; - var contenteditable = function (bool) { - return A2(boolProperty, - "contentEditable", - bool); - }; - var spellcheck = function (bool) { - return A2(boolProperty, - "spellcheck", - bool); - }; - var async = function (bool) { - return A2(boolProperty, - "async", - bool); - }; - var defer = function (bool) { - return A2(boolProperty, - "defer", - bool); - }; - var scoped = function (bool) { - return A2(boolProperty, - "scoped", - bool); - }; - var autoplay = function (bool) { - return A2(boolProperty, - "autoplay", - bool); - }; - var controls = function (bool) { - return A2(boolProperty, - "controls", - bool); - }; - var loop = function (bool) { - return A2(boolProperty, - "loop", - bool); - }; - var $default = function (bool) { - return A2(boolProperty, - "default", - bool); - }; - var seamless = function (bool) { - return A2(boolProperty, - "seamless", - bool); - }; - var checked = function (bool) { - return A2(boolProperty, - "checked", - bool); - }; - var selected = function (bool) { - return A2(boolProperty, - "selected", - bool); - }; - var autofocus = function (bool) { - return A2(boolProperty, - "autofocus", - bool); - }; - var disabled = function (bool) { - return A2(boolProperty, - "disabled", - bool); - }; - var multiple = function (bool) { - return A2(boolProperty, - "multiple", - bool); - }; - var novalidate = function (bool) { - return A2(boolProperty, - "noValidate", - bool); - }; - var readonly = function (bool) { - return A2(boolProperty, - "readOnly", - bool); - }; - var required = function (bool) { - return A2(boolProperty, - "required", - bool); - }; - var ismap = function (value) { - return A2(boolProperty, - "isMap", - value); - }; - var download = function (bool) { - return A2(boolProperty, - "download", - bool); - }; - var reversed = function (bool) { - return A2(boolProperty, - "reversed", - bool); - }; - var classList = function (list) { - return $class($String.join(" ")($List.map($Basics.fst)($List.filter($Basics.snd)(list)))); - }; - var style = function (props) { - return property("style")($Json$Encode.object($List.map(function (_v0) { - return function () { - switch (_v0.ctor) - {case "_Tuple2": - return {ctor: "_Tuple2" - ,_0: _v0._0 - ,_1: $Json$Encode.string(_v0._1)};} - _U.badCase($moduleName, - "on line 156, column 35 to 57"); - }(); - })(props))); - }; - var key = function (k) { - return A2(stringProperty, - "key", - k); - }; - _elm.Html.Attributes.values = {_op: _op - ,key: key - ,style: style - ,$class: $class - ,classList: classList - ,id: id - ,title: title - ,hidden: hidden - ,type$: type$ - ,value: value - ,checked: checked - ,placeholder: placeholder - ,selected: selected - ,accept: accept - ,acceptCharset: acceptCharset - ,action: action - ,autocomplete: autocomplete - ,autofocus: autofocus - ,autosave: autosave - ,disabled: disabled - ,enctype: enctype - ,formaction: formaction - ,list: list - ,maxlength: maxlength - ,minlength: minlength - ,method: method - ,multiple: multiple - ,name: name - ,novalidate: novalidate - ,pattern: pattern - ,readonly: readonly - ,required: required - ,size: size - ,$for: $for - ,form: form - ,max: max - ,min: min - ,step: step - ,cols: cols - ,rows: rows - ,wrap: wrap - ,href: href - ,target: target - ,download: download - ,downloadAs: downloadAs - ,hreflang: hreflang - ,media: media - ,ping: ping - ,rel: rel - ,ismap: ismap - ,usemap: usemap - ,shape: shape - ,coords: coords - ,src: src - ,height: height - ,width: width - ,alt: alt - ,autoplay: autoplay - ,controls: controls - ,loop: loop - ,preload: preload - ,poster: poster - ,$default: $default - ,kind: kind - ,srclang: srclang - ,sandbox: sandbox - ,seamless: seamless - ,srcdoc: srcdoc - ,reversed: reversed - ,start: start - ,align: align - ,colspan: colspan - ,rowspan: rowspan - ,headers: headers - ,scope: scope - ,async: async - ,charset: charset - ,content: content - ,defer: defer - ,httpEquiv: httpEquiv - ,language: language - ,scoped: scoped - ,accesskey: accesskey - ,contenteditable: contenteditable - ,contextmenu: contextmenu - ,dir: dir - ,draggable: draggable - ,dropzone: dropzone - ,itemprop: itemprop - ,lang: lang - ,spellcheck: spellcheck - ,tabindex: tabindex - ,challenge: challenge - ,keytype: keytype - ,cite: cite - ,datetime: datetime - ,pubdate: pubdate - ,manifest: manifest - ,property: property - ,attribute: attribute}; - return _elm.Html.Attributes.values; -}; -Elm.Html = Elm.Html || {}; -Elm.Html.Events = Elm.Html.Events || {}; -Elm.Html.Events.make = function (_elm) { - "use strict"; - _elm.Html = _elm.Html || {}; - _elm.Html.Events = _elm.Html.Events || {}; - if (_elm.Html.Events.values) - return _elm.Html.Events.values; - var _op = {}, - _N = Elm.Native, - _U = _N.Utils.make(_elm), - _L = _N.List.make(_elm), - $moduleName = "Html.Events", - $Basics = Elm.Basics.make(_elm), - $Html = Elm.Html.make(_elm), - $Json$Decode = Elm.Json.Decode.make(_elm), - $List = Elm.List.make(_elm), - $Maybe = Elm.Maybe.make(_elm), - $Result = Elm.Result.make(_elm), - $Signal = Elm.Signal.make(_elm), - $VirtualDom = Elm.VirtualDom.make(_elm); - var keyCode = A2($Json$Decode._op[":="], - "keyCode", - $Json$Decode.$int); - var targetChecked = A2($Json$Decode.at, - _L.fromArray(["target" - ,"checked"]), - $Json$Decode.bool); - var targetValue = A2($Json$Decode.at, - _L.fromArray(["target" - ,"value"]), - $Json$Decode.string); - var defaultOptions = $VirtualDom.defaultOptions; - var Options = F2(function (a, - b) { - return {_: {} - ,preventDefault: b - ,stopPropagation: a}; - }); - var onWithOptions = $VirtualDom.onWithOptions; - var on = $VirtualDom.on; - var messageOn = F3(function (name, - addr, - msg) { - return A3(on, - name, - $Json$Decode.value, - function (_v0) { - return function () { - return A2($Signal.message, - addr, - msg); - }(); - }); - }); - var onClick = messageOn("click"); - var onDoubleClick = messageOn("dblclick"); - var onMouseMove = messageOn("mousemove"); - var onMouseDown = messageOn("mousedown"); - var onMouseUp = messageOn("mouseup"); - var onMouseEnter = messageOn("mouseenter"); - var onMouseLeave = messageOn("mouseleave"); - var onMouseOver = messageOn("mouseover"); - var onMouseOut = messageOn("mouseout"); - var onBlur = messageOn("blur"); - var onFocus = messageOn("focus"); - var onSubmit = messageOn("submit"); - var onKey = F3(function (name, - addr, - handler) { - return A3(on, - name, - keyCode, - function (code) { - return A2($Signal.message, - addr, - handler(code)); - }); - }); - var onKeyUp = onKey("keyup"); - var onKeyDown = onKey("keydown"); - var onKeyPress = onKey("keypress"); - _elm.Html.Events.values = {_op: _op - ,onBlur: onBlur - ,onFocus: onFocus - ,onSubmit: onSubmit - ,onKeyUp: onKeyUp - ,onKeyDown: onKeyDown - ,onKeyPress: onKeyPress - ,onClick: onClick - ,onDoubleClick: onDoubleClick - ,onMouseMove: onMouseMove - ,onMouseDown: onMouseDown - ,onMouseUp: onMouseUp - ,onMouseEnter: onMouseEnter - ,onMouseLeave: onMouseLeave - ,onMouseOver: onMouseOver - ,onMouseOut: onMouseOut - ,on: on - ,onWithOptions: onWithOptions - ,defaultOptions: defaultOptions - ,targetValue: targetValue - ,targetChecked: targetChecked - ,keyCode: keyCode - ,Options: Options}; - return _elm.Html.Events.values; -}; -Elm.Http = Elm.Http || {}; -Elm.Http.make = function (_elm) { - "use strict"; - _elm.Http = _elm.Http || {}; - if (_elm.Http.values) - return _elm.Http.values; - var _op = {}, - _N = Elm.Native, - _U = _N.Utils.make(_elm), - _L = _N.List.make(_elm), - $moduleName = "Http", - $Basics = Elm.Basics.make(_elm), - $Dict = Elm.Dict.make(_elm), - $Json$Decode = Elm.Json.Decode.make(_elm), - $List = Elm.List.make(_elm), - $Maybe = Elm.Maybe.make(_elm), - $Native$Http = Elm.Native.Http.make(_elm), - $Result = Elm.Result.make(_elm), - $Signal = Elm.Signal.make(_elm), - $String = Elm.String.make(_elm), - $Task = Elm.Task.make(_elm), - $Time = Elm.Time.make(_elm); - var sendWithAbort = $Native$Http.send; - var send = F2(function (settings, - request) { - return $Basics.fst(A2(sendWithAbort, - settings, - request)); - }); - var BadResponse = F2(function (a, - b) { - return {ctor: "BadResponse" - ,_0: a - ,_1: b}; - }); - var UnexpectedPayload = function (a) { - return {ctor: "UnexpectedPayload" - ,_0: a}; - }; - var handleResponse = F2(function (handle, - response) { - return _U.cmp(200, - response.status) < 1 && _U.cmp(response.status, - 300) < 0 ? function () { - var _v0 = response.value; - switch (_v0.ctor) - {case "Text": - return handle(_v0._0);} - return $Task.fail(UnexpectedPayload("Response body is a blob, expecting a string.")); - }() : $Task.fail(A2(BadResponse, - response.status, - response.statusText)); - }); - var NetworkError = {ctor: "NetworkError"}; - var Timeout = {ctor: "Timeout"}; - var promoteError = function (rawError) { - return function () { - switch (rawError.ctor) - {case "RawNetworkError": - return NetworkError; - case "RawTimeout": - return Timeout;} - _U.badCase($moduleName, - "between lines 466 and 468"); - }(); - }; - var fromJson = F2(function (decoder, - response) { - return function () { - var decode = function (str) { - return function () { - var _v3 = A2($Json$Decode.decodeString, - decoder, - str); - switch (_v3.ctor) - {case "Err": - return $Task.fail(UnexpectedPayload(_v3._0)); - case "Ok": - return $Task.succeed(_v3._0);} - _U.badCase($moduleName, - "between lines 439 and 442"); - }(); - }; - return A2($Task.andThen, - A2($Task.mapError, - promoteError, - response), - handleResponse(decode)); - }(); - }); - var RawNetworkError = {ctor: "RawNetworkError"}; - var RawTimeout = {ctor: "RawTimeout"}; - var Blob = function (a) { - return {ctor: "Blob",_0: a}; - }; - var Text = function (a) { - return {ctor: "Text",_0: a}; - }; - var Response = F5(function (a, - b, - c, - d, - e) { - return {_: {} - ,headers: c - ,status: a - ,statusText: b - ,url: d - ,value: e}; - }); - var defaultSettings = {_: {} - ,desiredResponseType: $Maybe.Nothing - ,onProgress: $Maybe.Nothing - ,onStart: $Maybe.Nothing - ,timeout: 0 - ,withCredentials: false}; - var post = F3(function (decoder, - url, - body) { - return function () { - var request = {_: {} - ,body: body - ,headers: _L.fromArray([]) - ,url: url - ,verb: "POST"}; - return A2(fromJson, - decoder, - A2(send, - defaultSettings, - request)); - }(); - }); - var Settings = F5(function (a, - b, - c, - d, - e) { - return {_: {} - ,desiredResponseType: d - ,onProgress: c - ,onStart: b - ,timeout: a - ,withCredentials: e}; - }); - var multipart = $Native$Http.multipart; - var FileData = F3(function (a, - b, - c) { - return {ctor: "FileData" - ,_0: a - ,_1: b - ,_2: c}; - }); - var BlobData = F3(function (a, - b, - c) { - return {ctor: "BlobData" - ,_0: a - ,_1: b - ,_2: c}; - }); - var blobData = BlobData; - var StringData = F2(function (a, - b) { - return {ctor: "StringData" - ,_0: a - ,_1: b}; - }); - var stringData = StringData; - var BodyBlob = function (a) { - return {ctor: "BodyBlob" - ,_0: a}; - }; - var BodyFormData = {ctor: "BodyFormData"}; - var ArrayBuffer = {ctor: "ArrayBuffer"}; - var BodyString = function (a) { - return {ctor: "BodyString" - ,_0: a}; - }; - var string = BodyString; - var Empty = {ctor: "Empty"}; - var empty = Empty; - var getString = function (url) { - return function () { - var request = {_: {} - ,body: empty - ,headers: _L.fromArray([]) - ,url: url - ,verb: "GET"}; - return A2($Task.andThen, - A2($Task.mapError, - promoteError, - A2(send, - defaultSettings, - request)), - handleResponse($Task.succeed)); - }(); - }; - var getWithAbort = F2(function (decoder, - url) { - return function () { - var request = {_: {} - ,body: empty - ,headers: _L.fromArray([]) - ,url: url - ,verb: "GET"}; - var $ = A2(sendWithAbort, - defaultSettings, - request), - sendTask = $._0, - abortTask = $._1; - return {ctor: "_Tuple2" - ,_0: A2(fromJson, - decoder, - sendTask) - ,_1: abortTask}; - }(); - }); - var get = F2(function (decoder, - url) { - return $Basics.fst(A2(getWithAbort, - decoder, - url)); - }); - var Request = F4(function (a, - b, - c, - d) { - return {_: {} - ,body: d - ,headers: b - ,url: c - ,verb: a}; - }); - var uriDecode = $Native$Http.uriDecode; - var uriEncode = $Native$Http.uriEncode; - var queryEscape = function (string) { - return A2($String.join, - "+", - A2($String.split, - "%20", - uriEncode(string))); - }; - var queryPair = function (_v6) { - return function () { - switch (_v6.ctor) - {case "_Tuple2": - return A2($Basics._op["++"], - queryEscape(_v6._0), - A2($Basics._op["++"], - "=", - queryEscape(_v6._1)));} - _U.badCase($moduleName, - "on line 68, column 3 to 46"); - }(); - }; - var url = F2(function (baseUrl, - args) { - return function () { - switch (args.ctor) - {case "[]": return baseUrl;} - return A2($Basics._op["++"], - baseUrl, - A2($Basics._op["++"], - "?", - A2($String.join, - "&", - A2($List.map,queryPair,args)))); - }(); - }); - var TODO_implement_file_in_another_library = {ctor: "TODO_implement_file_in_another_library"}; - var TODO_implement_blob_in_another_library = {ctor: "TODO_implement_blob_in_another_library"}; - _elm.Http.values = {_op: _op - ,getString: getString - ,get: get - ,post: post - ,send: send - ,getWithAbort: getWithAbort - ,sendWithAbort: sendWithAbort - ,url: url - ,uriEncode: uriEncode - ,uriDecode: uriDecode - ,empty: empty - ,string: string - ,multipart: multipart - ,stringData: stringData - ,defaultSettings: defaultSettings - ,fromJson: fromJson - ,Request: Request - ,Settings: Settings - ,Response: Response - ,Text: Text - ,Blob: Blob - ,Timeout: Timeout - ,NetworkError: NetworkError - ,UnexpectedPayload: UnexpectedPayload - ,BadResponse: BadResponse - ,RawTimeout: RawTimeout - ,RawNetworkError: RawNetworkError}; - return _elm.Http.values; -}; -Elm.Json = Elm.Json || {}; -Elm.Json.Decode = Elm.Json.Decode || {}; -Elm.Json.Decode.make = function (_elm) { - "use strict"; - _elm.Json = _elm.Json || {}; - _elm.Json.Decode = _elm.Json.Decode || {}; - if (_elm.Json.Decode.values) - return _elm.Json.Decode.values; - var _op = {}, - _N = Elm.Native, - _U = _N.Utils.make(_elm), - _L = _N.List.make(_elm), - $moduleName = "Json.Decode", - $Array = Elm.Array.make(_elm), - $Dict = Elm.Dict.make(_elm), - $Json$Encode = Elm.Json.Encode.make(_elm), - $List = Elm.List.make(_elm), - $Maybe = Elm.Maybe.make(_elm), - $Native$Json = Elm.Native.Json.make(_elm), - $Result = Elm.Result.make(_elm); - var tuple8 = $Native$Json.decodeTuple8; - var tuple7 = $Native$Json.decodeTuple7; - var tuple6 = $Native$Json.decodeTuple6; - var tuple5 = $Native$Json.decodeTuple5; - var tuple4 = $Native$Json.decodeTuple4; - var tuple3 = $Native$Json.decodeTuple3; - var tuple2 = $Native$Json.decodeTuple2; - var tuple1 = $Native$Json.decodeTuple1; - var succeed = $Native$Json.succeed; - var fail = $Native$Json.fail; - var andThen = $Native$Json.andThen; - var customDecoder = $Native$Json.customDecoder; - var decodeValue = $Native$Json.runDecoderValue; - var value = $Native$Json.decodeValue; - var maybe = $Native$Json.decodeMaybe; - var $null = $Native$Json.decodeNull; - var array = $Native$Json.decodeArray; - var list = $Native$Json.decodeList; - var bool = $Native$Json.decodeBool; - var $int = $Native$Json.decodeInt; - var $float = $Native$Json.decodeFloat; - var string = $Native$Json.decodeString; - var oneOf = $Native$Json.oneOf; - var keyValuePairs = $Native$Json.decodeKeyValuePairs; - var object8 = $Native$Json.decodeObject8; - var object7 = $Native$Json.decodeObject7; - var object6 = $Native$Json.decodeObject6; - var object5 = $Native$Json.decodeObject5; - var object4 = $Native$Json.decodeObject4; - var object3 = $Native$Json.decodeObject3; - var object2 = $Native$Json.decodeObject2; - var object1 = $Native$Json.decodeObject1; - _op[":="] = $Native$Json.decodeField; - var at = F2(function (fields, - decoder) { - return A3($List.foldr, - F2(function (x,y) { - return A2(_op[":="],x,y); - }), - decoder, - fields); - }); - var decodeString = $Native$Json.runDecoderString; - var map = $Native$Json.decodeObject1; - var dict = function (decoder) { - return A2(map, - $Dict.fromList, - keyValuePairs(decoder)); - }; - var Decoder = {ctor: "Decoder"}; - _elm.Json.Decode.values = {_op: _op - ,decodeString: decodeString - ,decodeValue: decodeValue - ,string: string - ,$int: $int - ,$float: $float - ,bool: bool - ,$null: $null - ,list: list - ,array: array - ,tuple1: tuple1 - ,tuple2: tuple2 - ,tuple3: tuple3 - ,tuple4: tuple4 - ,tuple5: tuple5 - ,tuple6: tuple6 - ,tuple7: tuple7 - ,tuple8: tuple8 - ,at: at - ,object1: object1 - ,object2: object2 - ,object3: object3 - ,object4: object4 - ,object5: object5 - ,object6: object6 - ,object7: object7 - ,object8: object8 - ,keyValuePairs: keyValuePairs - ,dict: dict - ,maybe: maybe - ,oneOf: oneOf - ,map: map - ,fail: fail - ,succeed: succeed - ,andThen: andThen - ,value: value - ,customDecoder: customDecoder - ,Decoder: Decoder}; - return _elm.Json.Decode.values; -}; -Elm.Json = Elm.Json || {}; -Elm.Json.Encode = Elm.Json.Encode || {}; -Elm.Json.Encode.make = function (_elm) { - "use strict"; - _elm.Json = _elm.Json || {}; - _elm.Json.Encode = _elm.Json.Encode || {}; - if (_elm.Json.Encode.values) - return _elm.Json.Encode.values; - var _op = {}, - _N = Elm.Native, - _U = _N.Utils.make(_elm), - _L = _N.List.make(_elm), - $moduleName = "Json.Encode", - $Array = Elm.Array.make(_elm), - $Native$Json = Elm.Native.Json.make(_elm); - var list = $Native$Json.encodeList; - var array = $Native$Json.encodeArray; - var object = $Native$Json.encodeObject; - var $null = $Native$Json.encodeNull; - var bool = $Native$Json.identity; - var $float = $Native$Json.identity; - var $int = $Native$Json.identity; - var string = $Native$Json.identity; - var encode = $Native$Json.encode; - var Value = {ctor: "Value"}; - _elm.Json.Encode.values = {_op: _op - ,encode: encode - ,string: string - ,$int: $int - ,$float: $float - ,bool: bool - ,$null: $null - ,list: list - ,array: array - ,object: object - ,Value: Value}; - return _elm.Json.Encode.values; -}; -Elm.List = Elm.List || {}; -Elm.List.make = function (_elm) { - "use strict"; - _elm.List = _elm.List || {}; - if (_elm.List.values) - return _elm.List.values; - var _op = {}, - _N = Elm.Native, - _U = _N.Utils.make(_elm), - _L = _N.List.make(_elm), - $moduleName = "List", - $Basics = Elm.Basics.make(_elm), - $Maybe = Elm.Maybe.make(_elm), - $Native$List = Elm.Native.List.make(_elm); - var sortWith = $Native$List.sortWith; - var sortBy = $Native$List.sortBy; - var sort = function (xs) { - return A2(sortBy, - $Basics.identity, - xs); - }; - var repeat = $Native$List.repeat; - var drop = $Native$List.drop; - var take = $Native$List.take; - var map5 = $Native$List.map5; - var map4 = $Native$List.map4; - var map3 = $Native$List.map3; - var map2 = $Native$List.map2; - var any = $Native$List.any; - var all = F2(function (pred, - xs) { - return $Basics.not(A2(any, - function ($) { - return $Basics.not(pred($)); - }, - xs)); - }); - var foldr = $Native$List.foldr; - var foldl = $Native$List.foldl; - var length = function (xs) { - return A3(foldl, - F2(function (_v0,i) { - return function () { - return i + 1; - }(); - }), - 0, - xs); - }; - var sum = function (numbers) { - return A3(foldl, - F2(function (x,y) { - return x + y; - }), - 0, - numbers); - }; - var product = function (numbers) { - return A3(foldl, - F2(function (x,y) { - return x * y; - }), - 1, - numbers); - }; - var maximum = function (list) { - return function () { - switch (list.ctor) - {case "::": - return $Maybe.Just(A3(foldl, - $Basics.max, - list._0, - list._1));} - return $Maybe.Nothing; - }(); - }; - var minimum = function (list) { - return function () { - switch (list.ctor) - {case "::": - return $Maybe.Just(A3(foldl, - $Basics.min, - list._0, - list._1));} - return $Maybe.Nothing; - }(); - }; - var indexedMap = F2(function (f, - xs) { - return A3(map2, - f, - _L.range(0,length(xs) - 1), - xs); - }); - var member = F2(function (x, - xs) { - return A2(any, - function (a) { - return _U.eq(a,x); - }, - xs); - }); - var isEmpty = function (xs) { - return function () { - switch (xs.ctor) - {case "[]": return true;} - return false; - }(); - }; - var tail = function (list) { - return function () { - switch (list.ctor) - {case "::": - return $Maybe.Just(list._1); - case "[]": - return $Maybe.Nothing;} - _U.badCase($moduleName, - "between lines 87 and 89"); - }(); - }; - var head = function (list) { - return function () { - switch (list.ctor) - {case "::": - return $Maybe.Just(list._0); - case "[]": - return $Maybe.Nothing;} - _U.badCase($moduleName, - "between lines 75 and 77"); - }(); - }; - _op["::"] = $Native$List.cons; - var map = F2(function (f,xs) { - return A3(foldr, - F2(function (x,acc) { - return A2(_op["::"], - f(x), - acc); - }), - _L.fromArray([]), - xs); - }); - var filter = F2(function (pred, - xs) { - return function () { - var conditionalCons = F2(function (x, - xs$) { - return pred(x) ? A2(_op["::"], - x, - xs$) : xs$; - }); - return A3(foldr, - conditionalCons, - _L.fromArray([]), - xs); - }(); - }); - var maybeCons = F3(function (f, - mx, - xs) { - return function () { - var _v15 = f(mx); - switch (_v15.ctor) - {case "Just": - return A2(_op["::"],_v15._0,xs); - case "Nothing": return xs;} - _U.badCase($moduleName, - "between lines 179 and 181"); - }(); - }); - var filterMap = F2(function (f, - xs) { - return A3(foldr, - maybeCons(f), - _L.fromArray([]), - xs); - }); - var reverse = function (list) { - return A3(foldl, - F2(function (x,y) { - return A2(_op["::"],x,y); - }), - _L.fromArray([]), - list); - }; - var scanl = F3(function (f, - b, - xs) { - return function () { - var scan1 = F2(function (x, - accAcc) { - return function () { - switch (accAcc.ctor) - {case "::": return A2(_op["::"], - A2(f,x,accAcc._0), - accAcc); - case "[]": - return _L.fromArray([]);} - _U.badCase($moduleName, - "between lines 148 and 151"); - }(); - }); - return reverse(A3(foldl, - scan1, - _L.fromArray([b]), - xs)); - }(); - }); - var append = F2(function (xs, - ys) { - return function () { - switch (ys.ctor) - {case "[]": return xs;} - return A3(foldr, - F2(function (x,y) { - return A2(_op["::"],x,y); - }), - ys, - xs); - }(); - }); - var concat = function (lists) { - return A3(foldr, - append, - _L.fromArray([]), - lists); - }; - var concatMap = F2(function (f, - list) { - return concat(A2(map, - f, - list)); - }); - var partition = F2(function (pred, - list) { - return function () { - var step = F2(function (x, - _v21) { - return function () { - switch (_v21.ctor) - {case "_Tuple2": - return pred(x) ? {ctor: "_Tuple2" - ,_0: A2(_op["::"],x,_v21._0) - ,_1: _v21._1} : {ctor: "_Tuple2" - ,_0: _v21._0 - ,_1: A2(_op["::"], - x, - _v21._1)};} - _U.badCase($moduleName, - "between lines 301 and 303"); - }(); - }); - return A3(foldr, - step, - {ctor: "_Tuple2" - ,_0: _L.fromArray([]) - ,_1: _L.fromArray([])}, - list); - }(); - }); - var unzip = function (pairs) { - return function () { - var step = F2(function (_v25, - _v26) { - return function () { - switch (_v26.ctor) - {case "_Tuple2": - return function () { - switch (_v25.ctor) - {case "_Tuple2": - return {ctor: "_Tuple2" - ,_0: A2(_op["::"], - _v25._0, - _v26._0) - ,_1: A2(_op["::"], - _v25._1, - _v26._1)};} - _U.badCase($moduleName, - "on line 339, column 12 to 28"); - }();} - _U.badCase($moduleName, - "on line 339, column 12 to 28"); - }(); - }); - return A3(foldr, - step, - {ctor: "_Tuple2" - ,_0: _L.fromArray([]) - ,_1: _L.fromArray([])}, - pairs); - }(); - }; - var intersperse = F2(function (sep, - xs) { - return function () { - switch (xs.ctor) - {case "::": return function () { - var step = F2(function (x, - rest) { - return A2(_op["::"], - sep, - A2(_op["::"],x,rest)); - }); - var spersed = A3(foldr, - step, - _L.fromArray([]), - xs._1); - return A2(_op["::"], - xs._0, - spersed); - }(); - case "[]": - return _L.fromArray([]);} - _U.badCase($moduleName, - "between lines 350 and 356"); - }(); - }); - _elm.List.values = {_op: _op - ,isEmpty: isEmpty - ,length: length - ,reverse: reverse - ,member: member - ,head: head - ,tail: tail - ,filter: filter - ,take: take - ,drop: drop - ,repeat: repeat - ,append: append - ,concat: concat - ,intersperse: intersperse - ,partition: partition - ,unzip: unzip - ,map: map - ,map2: map2 - ,map3: map3 - ,map4: map4 - ,map5: map5 - ,filterMap: filterMap - ,concatMap: concatMap - ,indexedMap: indexedMap - ,foldr: foldr - ,foldl: foldl - ,sum: sum - ,product: product - ,maximum: maximum - ,minimum: minimum - ,all: all - ,any: any - ,scanl: scanl - ,sort: sort - ,sortBy: sortBy - ,sortWith: sortWith}; - return _elm.List.values; -}; -Elm.Main = Elm.Main || {}; -Elm.Main.make = function (_elm) { - "use strict"; - _elm.Main = _elm.Main || {}; - if (_elm.Main.values) - return _elm.Main.values; - var _op = {}, - _N = Elm.Native, - _U = _N.Utils.make(_elm), - _L = _N.List.make(_elm), - $moduleName = "Main", - $Array = Elm.Array.make(_elm), - $Basics = Elm.Basics.make(_elm), - $Effects = Elm.Effects.make(_elm), - $Html = Elm.Html.make(_elm), - $Html$Attributes = Elm.Html.Attributes.make(_elm), - $Html$Events = Elm.Html.Events.make(_elm), - $Http = Elm.Http.make(_elm), - $Json$Decode = Elm.Json.Decode.make(_elm), - $List = Elm.List.make(_elm), - $Maybe = Elm.Maybe.make(_elm), - $Result = Elm.Result.make(_elm), - $Signal = Elm.Signal.make(_elm), - $StartApp = Elm.StartApp.make(_elm), - $Task = Elm.Task.make(_elm); - var aLast = function (arr) { - return A2($Array.get, - $Array.length(arr) - 1, - arr); - }; - var aFirst = $Array.get(0); - _op[">>="] = F2(function (_v0, - f) { - return function () { - switch (_v0.ctor) - {case "_Tuple2": - return function () { - var $ = f(_v0._0), - model$ = $._0, - effects$ = $._1; - return {ctor: "_Tuple2" - ,_0: model$ - ,_1: $Effects.batch(_L.fromArray([_v0._1 - ,effects$]))}; - }();} - _U.badCase($moduleName, - "between lines 622 and 624"); - }(); - }); - var bindAll = F2(function (modelEffects, - fs) { - return A3($List.foldl, - $Basics.flip(F2(function (x,y) { - return A2(_op[">>="],x,y); - })), - modelEffects, - fs); - }); - var pure = function (model) { - return {ctor: "_Tuple2" - ,_0: model - ,_1: $Effects.none}; - }; - var andThenAndThen = F2(function (mmValue, - f) { - return A2($Maybe.andThen, - mmValue, - A2($Basics.flip, - $Maybe.andThen, - f)); - }); - var mMap2 = F3(function (func, - ma, - mb) { - return function () { - var _v4 = {ctor: "_Tuple2" - ,_0: ma - ,_1: mb}; - switch (_v4.ctor) - {case "_Tuple2": - switch (_v4._0.ctor) - {case "Just": - switch (_v4._1.ctor) - {case "Just": - return $Maybe.Just(A2(func, - _v4._0._0, - _v4._1._0));} - break;} - break;} - return $Maybe.Nothing; - }(); - }); - var any = F2(function (pred, - array) { - return _U.cmp($Array.length(A2($Array.filter, - pred, - array)), - 0) > 0; - }); - var notNothing = function (maybe) { - return function () { - switch (maybe.ctor) - {case "Just": return true; - case "Nothing": return false;} - _U.badCase($moduleName, - "between lines 581 and 583"); - }(); - }; - var isNothing = function ($) { - return $Basics.not(notNothing($)); - }; - var inBounds = F2(function (pos, - slots) { - return _U.cmp(pos, - 0) > -1 && _U.cmp(pos, - $Array.length(slots)) < 0; - }); - var viewPlanetMonitor = function (mWorld) { - return A2($Html.h1, - _L.fromArray([$Html$Attributes.$class("css-planet-monitor")]), - _L.fromArray([$Html.text(A2($Basics._op["++"], - "Obi-Wan currently ", - function () { - switch (mWorld.ctor) - {case "Just": - return A2($Basics._op["++"], - "on ", - mWorld._0.name); - case "Nothing": - return "in transit";} - _U.badCase($moduleName, - "between lines 461 and 463"); - }()))])); - }; - var onWorld = F2(function (mJedi, - mWorld) { - return function () { - var _v13 = A3(mMap2, - F2(function (v0,v1) { - return {ctor: "_Tuple2" - ,_0: v0 - ,_1: v1}; - }), - mWorld, - mJedi); - switch (_v13.ctor) - {case "Just": - switch (_v13._0.ctor) - {case "_Tuple2": - return _U.eq(_v13._0._1.homeworld.id, - _v13._0._0.id);} - break; - case "Nothing": return false;} - _U.badCase($moduleName, - "between lines 437 and 440"); - }(); - }); - var viewJedi = F2(function (mWorld, - mJedi) { - return A2($Html.li, - _L.fromArray([$Html$Attributes.$class("css-slot") - ,$Html$Attributes.style(A2(onWorld, - mJedi, - mWorld) ? _L.fromArray([{ctor: "_Tuple2" - ,_0: "color" - ,_1: "red"}]) : _L.fromArray([]))]), - function () { - switch (mJedi.ctor) - {case "Just": - return _L.fromArray([A2($Html.h3, - _L.fromArray([]), - _L.fromArray([$Html.text(mJedi._0.name)])) - ,A2($Html.h6, - _L.fromArray([]), - _L.fromArray([$Html.text(mJedi._0.homeworld.name)]))]); - case "Nothing": - return _L.fromArray([]);} - _U.badCase($moduleName, - "between lines 485 and 491"); - }()); - }); - var canScroll = F3(function (upOrDown, - scrollSpeed, - jediSlots) { - return function () { - var $ = function () { - switch (upOrDown.ctor) - {case "Down": - return {ctor: "_Tuple4" - ,_0: aLast - ,_1: function (_) { - return _.apprentice; - } - ,_2: scrollSpeed - ,_3: $Array.length(jediSlots)}; - case "Up": - return {ctor: "_Tuple4" - ,_0: aFirst - ,_1: function (_) { - return _.master; - } - ,_2: 0 - ,_3: 0 - scrollSpeed};} - _U.badCase($moduleName, - "between lines 410 and 422"); - }(), - getFirstOrLast = $._0, - apprenticeOrMaster = $._1, - scrollStart = $._2, - scrollEnd = $._3; - var jediInView = any(notNothing)(A2($Array.slice, - scrollStart, - scrollEnd)(jediSlots)); - var loadedJedis = A2($Array.filter, - notNothing, - jediSlots); - var next = A2(andThenAndThen, - getFirstOrLast(loadedJedis), - apprenticeOrMaster); - return notNothing(next) && jediInView; - }(); - }); - var haveJediAt = F2(function (pos, - _v20) { - return function () { - return !_U.eq(A2($Array.get, - pos, - _v20.jediSlots), - $Maybe.Just($Maybe.Nothing)); - }(); - }); - var needJediAt = F2(function (pos, - model) { - return A2(inBounds, - pos, - model.jediSlots) && $Basics.not(A2(haveJediAt, - pos, - model)); - }); - var removeRequest = F2(function (request, - requests) { - return A2($List.filter, - function (r) { - return !_U.eq(r,request); - }, - requests); - }); - var adjustPos = F3(function (pos, - oldScrollPos, - newScrollPos) { - return function () { - var offset = oldScrollPos - newScrollPos; - return pos + offset; - }(); - }); - var abortAndSaveAllRequests = function (model) { - return {ctor: "_Tuple2" - ,_0: _U.replace([["jediRequests" - ,_L.fromArray([])] - ,["requestsToResume" - ,A2($List.append, - model.requestsToResume, - model.jediRequests)]], - model) - ,_1: $Effects.batch(A2($List.map, - function (_) { - return _.abort; - }, - model.jediRequests))}; - }; - var abortRequests = function (model) { - return function () { - var $ = A2($List.partition, - function (request) { - return A2(inBounds, - A3(adjustPos, - request.insertPos, - request.scrollPos, - model.scrollPos), - model.jediSlots); - }, - model.jediRequests), - newRequests = $._0, - requestsToAbort = $._1; - var aborts = A2($List.map, - function (_) { - return _.abort; - }, - requestsToAbort); - return {ctor: "_Tuple2" - ,_0: _U.replace([["jediRequests" - ,newRequests]], - model) - ,_1: $Effects.batch(aborts)}; - }(); - }; - var NoAction = {ctor: "NoAction"}; - var Scroll = F2(function (a,b) { - return {ctor: "Scroll" - ,_0: a - ,_1: b}; - }); - var viewScrollButton = F5(function (address, - scrollDisabled, - jediSlots, - scrollSpeed, - dir) { - return function () { - var clickHandler = A2($Html$Events.onClick, - address, - A2(Scroll,dir,scrollSpeed)); - var enabled = $Basics.not(scrollDisabled) && A3(canScroll, - dir, - scrollSpeed, - jediSlots); - var className = function () { - switch (dir.ctor) - {case "Down": - return "css-button-down"; - case "Up": - return "css-button-up";} - _U.badCase($moduleName, - "between lines 507 and 513"); - }(); - var classes = $Html$Attributes.classList(_L.fromArray([{ctor: "_Tuple2" - ,_0: className - ,_1: true} - ,{ctor: "_Tuple2" - ,_0: "css-button-disabled" - ,_1: $Basics.not(enabled)}])); - return A2($Html.button, - enabled ? _L.fromArray([classes - ,clickHandler]) : _L.fromArray([classes]), - _L.fromArray([])); - }(); - }); - var SetJedi = F2(function (a, - b) { - return {ctor: "SetJedi" - ,_0: a - ,_1: b}; - }); - var SetWorld = function (a) { - return {ctor: "SetWorld" - ,_0: a}; - }; - var initModel = F2(function (nbSlots, - scrollSpeed) { - return {_: {} - ,jediRequests: _L.fromArray([]) - ,jediSlots: A2($Array.repeat, - nbSlots, - $Maybe.Nothing) - ,nextRequestId: 0 - ,requestsToResume: _L.fromArray([]) - ,scrollPos: 0 - ,scrollSpeed: scrollSpeed - ,world: $Maybe.Nothing}; - }); - var mkJediUrl = function (id) { - return {_: {} - ,id: id - ,url: A2($Basics._op["++"], - "http://localhost:3000/dark-jedis/", - $Basics.toString(id))}; - }; - var darthSidious = mkJediUrl(3616); - var Down = {ctor: "Down"}; - var Up = {ctor: "Up"}; - var viewScrollButtons = F2(function (address, - model) { - return function () { - var scrollDisabled = A2(any, - A2($Basics.flip, - onWorld, - model.world), - model.jediSlots); - return A2($Html.div, - _L.fromArray([$Html$Attributes.$class("css-scroll-buttons")]), - A2($List.map, - A4(viewScrollButton, - address, - scrollDisabled, - model.jediSlots, - model.scrollSpeed), - _L.fromArray([Up,Down]))); - }(); - }); - var viewJediList = F2(function (address, - model) { - return A2($Html.div, - _L.fromArray([$Html$Attributes.$class("css-scrollable-list")]), - _L.fromArray([A2($Html.ul, - _L.fromArray([$Html$Attributes.$class("css-slots")]), - A2($List.map, - viewJedi(model.world), - $Array.toList(model.jediSlots))) - ,A2(viewScrollButtons, - address, - model)])); - }); - var view = F2(function (address, - model) { - return A2($Html.div, - _L.fromArray([$Html$Attributes.$class("css-root")]), - _L.fromArray([viewPlanetMonitor(model.world) - ,A2(viewJediList, - address, - model)])); - }); - var JediRequest = F5(function (a, - b, - c, - d, - e) { - return {_: {} - ,abort: e - ,id: a - ,insertPos: c - ,jediUrl: b - ,scrollPos: d}; - }); - var JediUrl = F2(function (a, - b) { - return {_: {},id: a,url: b}; - }); - var decodeJediUrl = A2($Json$Decode.andThen, - A2($Json$Decode._op[":="], - "id", - $Json$Decode.oneOf(_L.fromArray([A2($Json$Decode.map, - $Maybe.Just, - $Json$Decode.$int) - ,$Json$Decode.$null($Maybe.Nothing)]))), - function (mId) { - return function () { - switch (mId.ctor) - {case "Just": - return A2($Json$Decode.object1, - function (url) { - return $Maybe.Just(A2(JediUrl, - mId._0, - url)); - }, - A2($Json$Decode._op[":="], - "url", - $Json$Decode.string)); - case "Nothing": - return $Json$Decode.succeed($Maybe.Nothing);} - _U.badCase($moduleName, - "between lines 560 and 566"); - }(); - }); - var Jedi = F5(function (a, - b, - c, - d, - e) { - return {_: {} - ,apprentice: e - ,homeworld: c - ,id: a - ,master: d - ,name: b}; - }); - var World = F2(function (a,b) { - return {_: {},id: a,name: b}; - }); - var decodeWorld = A3($Json$Decode.object2, - World, - A2($Json$Decode._op[":="], - "id", - $Json$Decode.$int), - A2($Json$Decode._op[":="], - "name", - $Json$Decode.string)); - var decodeJedi = A6($Json$Decode.object5, - Jedi, - A2($Json$Decode._op[":="], - "id", - $Json$Decode.$int), - A2($Json$Decode._op[":="], - "name", - $Json$Decode.string), - A2($Json$Decode._op[":="], - "homeworld", - decodeWorld), - A2($Json$Decode._op[":="], - "master", - decodeJediUrl), - A2($Json$Decode._op[":="], - "apprentice", - decodeJediUrl)); - var fetchJedi = F4(function (sleepMillis, - insertPos, - jediUrl, - model) { - return function () { - var $ = A2($Http.getWithAbort, - decodeJedi, - jediUrl.url), - sendTask = $._0, - abortTask = $._1; - var abortEffect = $Effects.task($Task.map(function (_v25) { - return function () { - return NoAction; - }(); - })($Task.toMaybe(abortTask))); - var request = {_: {} - ,abort: abortEffect - ,id: model.nextRequestId - ,insertPos: insertPos - ,jediUrl: jediUrl - ,scrollPos: model.scrollPos}; - var sendEffect = $Effects.task($Task.map(SetJedi(request))($Task.toResult(A2($Task.andThen, - $Task.sleep(sleepMillis), - function (_v27) { - return function () { - return sendTask; - }(); - })))); - return {ctor: "_Tuple2" - ,_0: _U.replace([["jediRequests" - ,A2($List._op["::"], - request, - model.jediRequests)] - ,["nextRequestId" - ,model.nextRequestId + 1]], - model) - ,_1: sendEffect}; - }(); - }); - var init = F3(function (nbSlots, - scrollSpeed, - jediUrl) { - return A4(fetchJedi, - 0, - nbSlots / 2 | 0, - jediUrl, - A2(initModel, - nbSlots, - scrollSpeed)); - }); - var retryRequest = F3(function (sleepMillis, - request, - model) { - return function () { - var model$ = _U.replace([["jediRequests" - ,A2(removeRequest, - request, - model.jediRequests)]], - model); - var newInsertPos = A3(adjustPos, - request.insertPos, - request.scrollPos, - model$.scrollPos); - return A4(fetchJedi, - sleepMillis, - newInsertPos, - request.jediUrl, - model$); - }(); - }); - var resumeAllRequests = function (model) { - return function () { - var model$ = _U.replace([["requestsToResume" - ,_L.fromArray([])]], - model); - return A2(bindAll, - pure(model$), - A2($List.map, - retryRequest(0), - model.requestsToResume)); - }(); - }; - var setWorld = F2(function (mWorld, - model) { - return function () { - var model$ = _U.replace([["world" - ,mWorld]], - model); - return A2(any, - A2($Basics.flip,onWorld,mWorld), - model$.jediSlots) ? abortAndSaveAllRequests(model$) : resumeAllRequests(model$); - }(); - }); - var maybeFetchJedi = F4(function (pos, - nextPos, - getNextUrl, - model) { - return function () { - var mNext = A2(needJediAt, - nextPos, - model) ? A2(andThenAndThen, - A2($Array.get, - pos, - model.jediSlots), - getNextUrl) : $Maybe.Nothing; - return function () { - switch (mNext.ctor) - {case "Just": - return A4(fetchJedi, - 0, - nextPos, - mNext._0, - model); - case "Nothing": - return pure(model);} - _U.badCase($moduleName, - "between lines 369 and 373"); - }(); - }(); - }); - var maybeFetchJedisAround = F2(function (pos, - model) { - return A2(_op[">>="], - A2(_op[">>="], - pure(model), - A3(maybeFetchJedi, - pos, - pos - 1, - function (_) { - return _.master; - })), - A3(maybeFetchJedi, - pos, - pos + 1, - function (_) { - return _.apprentice; - })); - }); - var setJedi = F3(function (request, - newJediResult, - model) { - return function () { - var maybeRetry = function () { - switch (newJediResult.ctor) - {case "Err": - return A2(retryRequest, - 1000, - request); - case "Ok": return pure;} - _U.badCase($moduleName, - "between lines 211 and 217"); - }(); - var adjustedPos = A3(adjustPos, - request.insertPos, - request.scrollPos, - model.scrollPos); - var newMJedi = $Result.toMaybe(newJediResult); - var newJediSlots = A2(inBounds, - adjustedPos, - model.jediSlots) ? A3($Array.set, - adjustedPos, - newMJedi, - model.jediSlots) : model.jediSlots; - var model$ = _U.replace([["jediRequests" - ,A2(removeRequest, - request, - model.jediRequests)] - ,["jediSlots",newJediSlots]], - model); - var maybeAbortAll = A2(onWorld, - newMJedi, - model.world) ? abortAndSaveAllRequests : pure; - return A2(_op[">>="], - A2(_op[">>="], - A2(maybeFetchJedisAround, - adjustedPos, - model$), - maybeRetry), - maybeAbortAll); - }(); - }); - var doScroll = F3(function (model, - dir, - scrollSpeed) { - return $Basics.not(A3(canScroll, - dir, - scrollSpeed, - model.jediSlots)) ? pure(model) : function () { - var emptySlots = A2($Array.repeat, - scrollSpeed, - $Maybe.Nothing); - var slotsLength = $Array.length(model.jediSlots); - var $ = function () { - switch (dir.ctor) - {case "Down": - return {ctor: "_Tuple3" - ,_0: A2($Array.append, - A3($Array.slice, - scrollSpeed, - slotsLength, - model.jediSlots), - emptySlots) - ,_1: model.scrollPos + scrollSpeed - ,_2: slotsLength - scrollSpeed - 1}; - case "Up": - return {ctor: "_Tuple3" - ,_0: A2($Array.append, - emptySlots, - A3($Array.slice, - 0, - slotsLength - scrollSpeed, - model.jediSlots)) - ,_1: model.scrollPos - scrollSpeed - ,_2: scrollSpeed};} - _U.badCase($moduleName, - "between lines 286 and 298"); - }(), - newJedis = $._0, - newScrollPos = $._1, - endJediPos = $._2; - return A2(_op[">>="], - A2(_op[">>="], - pure(_U.replace([["jediSlots" - ,newJedis] - ,["scrollPos",newScrollPos]], - model)), - abortRequests), - maybeFetchJedisAround(endJediPos)); - }(); - }); - var update = F2(function (action, - model) { - return function () { - switch (action.ctor) - {case "NoAction": - return pure(model); - case "Scroll": - return A3(doScroll, - model, - action._0, - action._1); - case "SetJedi": - return A3(setJedi, - action._0, - action._1, - model); - case "SetWorld": - return A2(setWorld, - action._0, - model);} - _U.badCase($moduleName, - "between lines 156 and 167"); - }(); - }); - var Model = F7(function (a, - b, - c, - d, - e, - f, - g) { - return {_: {} - ,jediRequests: e - ,jediSlots: b - ,nextRequestId: g - ,requestsToResume: f - ,scrollPos: c - ,scrollSpeed: d - ,world: a}; - }); - var currentWorld = Elm.Native.Port.make(_elm).inboundSignal("currentWorld", - "Maybe.Maybe Main.World", - function (v) { - return v === null ? Elm.Maybe.make(_elm).Nothing : Elm.Maybe.make(_elm).Just(typeof v === "object" && "id" in v && "name" in v ? {_: {} - ,id: typeof v.id === "number" ? v.id : _U.badPort("a number", - v.id) - ,name: typeof v.name === "string" || typeof v.name === "object" && v.name instanceof String ? v.name : _U.badPort("a string", - v.name)} : _U.badPort("an object with fields `id`, `name`", - v)); - }); - var app = $StartApp.start({_: {} - ,init: A3(init,5,2,darthSidious) - ,inputs: _L.fromArray([A2($Signal.map, - SetWorld, - currentWorld)]) - ,update: update - ,view: view}); - var main = app.html; - var tasks = Elm.Native.Task.make(_elm).performSignal("tasks", - app.tasks); - _elm.Main.values = {_op: _op - ,app: app - ,main: main - ,Model: Model - ,World: World - ,Jedi: Jedi - ,JediUrl: JediUrl - ,JediRequest: JediRequest - ,Up: Up - ,Down: Down - ,mkJediUrl: mkJediUrl - ,darthSidious: darthSidious - ,init: init - ,initModel: initModel - ,SetWorld: SetWorld - ,SetJedi: SetJedi - ,Scroll: Scroll - ,NoAction: NoAction - ,update: update - ,setWorld: setWorld - ,setJedi: setJedi - ,abortRequests: abortRequests - ,abortAndSaveAllRequests: abortAndSaveAllRequests - ,resumeAllRequests: resumeAllRequests - ,doScroll: doScroll - ,fetchJedi: fetchJedi - ,retryRequest: retryRequest - ,maybeFetchJedisAround: maybeFetchJedisAround - ,maybeFetchJedi: maybeFetchJedi - ,adjustPos: adjustPos - ,removeRequest: removeRequest - ,haveJediAt: haveJediAt - ,needJediAt: needJediAt - ,canScroll: canScroll - ,onWorld: onWorld - ,view: view - ,viewPlanetMonitor: viewPlanetMonitor - ,viewJediList: viewJediList - ,viewJedi: viewJedi - ,viewScrollButtons: viewScrollButtons - ,viewScrollButton: viewScrollButton - ,decodeJedi: decodeJedi - ,decodeWorld: decodeWorld - ,decodeJediUrl: decodeJediUrl - ,inBounds: inBounds - ,notNothing: notNothing - ,isNothing: isNothing - ,any: any - ,mMap2: mMap2 - ,andThenAndThen: andThenAndThen - ,pure: pure - ,bindAll: bindAll - ,aFirst: aFirst - ,aLast: aLast}; - return _elm.Main.values; -}; -Elm.Maybe = Elm.Maybe || {}; -Elm.Maybe.make = function (_elm) { - "use strict"; - _elm.Maybe = _elm.Maybe || {}; - if (_elm.Maybe.values) - return _elm.Maybe.values; - var _op = {}, - _N = Elm.Native, - _U = _N.Utils.make(_elm), - _L = _N.List.make(_elm), - $moduleName = "Maybe"; - var withDefault = F2(function ($default, - maybe) { - return function () { - switch (maybe.ctor) - {case "Just": return maybe._0; - case "Nothing": - return $default;} - _U.badCase($moduleName, - "between lines 45 and 47"); - }(); - }); - var Nothing = {ctor: "Nothing"}; - var oneOf = function (maybes) { - return function () { - switch (maybes.ctor) - {case "::": return function () { - switch (maybes._0.ctor) - {case "Just": return maybes._0; - case "Nothing": - return oneOf(maybes._1);} - _U.badCase($moduleName, - "between lines 64 and 66"); - }(); - case "[]": return Nothing;} - _U.badCase($moduleName, - "between lines 59 and 66"); - }(); - }; - var andThen = F2(function (maybeValue, - callback) { - return function () { - switch (maybeValue.ctor) - {case "Just": - return callback(maybeValue._0); - case "Nothing": return Nothing;} - _U.badCase($moduleName, - "between lines 110 and 112"); - }(); - }); - var Just = function (a) { - return {ctor: "Just",_0: a}; - }; - var map = F2(function (f, - maybe) { - return function () { - switch (maybe.ctor) - {case "Just": - return Just(f(maybe._0)); - case "Nothing": return Nothing;} - _U.badCase($moduleName, - "between lines 76 and 78"); - }(); - }); - _elm.Maybe.values = {_op: _op - ,andThen: andThen - ,map: map - ,withDefault: withDefault - ,oneOf: oneOf - ,Just: Just - ,Nothing: Nothing}; - return _elm.Maybe.values; -}; Elm.Native.Array = {}; Elm.Native.Array.make = function(localRuntime) { @@ -5507,9187 +8,11342 @@ Elm.Native.Array.make = function(localRuntime) { { return localRuntime.Native.Array.values; } - if ('values' in Elm.Native.Array) + if ('values' in Elm.Native.Array) + { + return localRuntime.Native.Array.values = Elm.Native.Array.values; + } + + var List = Elm.Native.List.make(localRuntime); + + // A RRB-Tree has two distinct data types. + // Leaf -> "height" is always 0 + // "table" is an array of elements + // Node -> "height" is always greater than 0 + // "table" is an array of child nodes + // "lengths" is an array of accumulated lengths of the child nodes + + // M is the maximal table size. 32 seems fast. E is the allowed increase + // of search steps when concatting to find an index. Lower values will + // decrease balancing, but will increase search steps. + var M = 32; + var E = 2; + + // An empty array. + var empty = { + ctor: '_Array', + height: 0, + table: [] + }; + + + function get(i, array) + { + if (i < 0 || i >= length(array)) + { + throw new Error( + 'Index ' + i + ' is out of range. Check the length of ' + + 'your array first or use getMaybe or getWithDefault.'); + } + return unsafeGet(i, array); + } + + + function unsafeGet(i, array) + { + for (var x = array.height; x > 0; x--) + { + var slot = i >> (x * 5); + while (array.lengths[slot] <= i) + { + slot++; + } + if (slot > 0) + { + i -= array.lengths[slot - 1]; + } + array = array.table[slot]; + } + return array.table[i]; + } + + + // Sets the value at the index i. Only the nodes leading to i will get + // copied and updated. + function set(i, item, array) + { + if (i < 0 || length(array) <= i) + { + return array; + } + return unsafeSet(i, item, array); + } + + + function unsafeSet(i, item, array) + { + array = nodeCopy(array); + + if (array.height === 0) + { + array.table[i] = item; + } + else + { + var slot = getSlot(i, array); + if (slot > 0) + { + i -= array.lengths[slot - 1]; + } + array.table[slot] = unsafeSet(i, item, array.table[slot]); + } + return array; + } + + + function initialize(len, f) + { + if (len <= 0) + { + return empty; + } + var h = Math.floor( Math.log(len) / Math.log(M) ); + return initialize_(f, h, 0, len); + } + + function initialize_(f, h, from, to) + { + if (h === 0) + { + var table = new Array((to - from) % (M + 1)); + for (var i = 0; i < table.length; i++) + { + table[i] = f(from + i); + } + return { + ctor: '_Array', + height: 0, + table: table + }; + } + + var step = Math.pow(M, h); + var table = new Array(Math.ceil((to - from) / step)); + var lengths = new Array(table.length); + for (var i = 0; i < table.length; i++) + { + table[i] = initialize_(f, h - 1, from + (i * step), Math.min(from + ((i + 1) * step), to)); + lengths[i] = length(table[i]) + (i > 0 ? lengths[i-1] : 0); + } + return { + ctor: '_Array', + height: h, + table: table, + lengths: lengths + }; + } + + function fromList(list) { - return localRuntime.Native.Array.values = Elm.Native.Array.values; - } + if (list === List.Nil) + { + return empty; + } - var List = Elm.Native.List.make(localRuntime); + // Allocate M sized blocks (table) and write list elements to it. + var table = new Array(M); + var nodes = []; + var i = 0; - // A RRB-Tree has two distinct data types. - // Leaf -> "height" is always 0 - // "table" is an array of elements - // Node -> "height" is always greater than 0 - // "table" is an array of child nodes - // "lengths" is an array of accumulated lengths of the child nodes + while (list.ctor !== '[]') + { + table[i] = list._0; + list = list._1; + i++; - // M is the maximal table size. 32 seems fast. E is the allowed increase - // of search steps when concatting to find an index. Lower values will - // decrease balancing, but will increase search steps. - var M = 32; - var E = 2; + // table is full, so we can push a leaf containing it into the + // next node. + if (i === M) + { + var leaf = { + ctor: '_Array', + height: 0, + table: table + }; + fromListPush(leaf, nodes); + table = new Array(M); + i = 0; + } + } - // An empty array. - var empty = { - ctor: "_Array", - height: 0, - table: new Array() - }; + // Maybe there is something left on the table. + if (i > 0) + { + var leaf = { + ctor: '_Array', + height: 0, + table: table.splice(0, i) + }; + fromListPush(leaf, nodes); + } + // Go through all of the nodes and eventually push them into higher nodes. + for (var h = 0; h < nodes.length - 1; h++) + { + if (nodes[h].table.length > 0) + { + fromListPush(nodes[h], nodes); + } + } - function get(i, array) + var head = nodes[nodes.length - 1]; + if (head.height > 0 && head.table.length === 1) + { + return head.table[0]; + } + else + { + return head; + } + } + + // Push a node into a higher node as a child. + function fromListPush(toPush, nodes) { - if (i < 0 || i >= length(array)) + var h = toPush.height; + + // Maybe the node on this height does not exist. + if (nodes.length === h) { - throw new Error( - "Index " + i + " is out of range. Check the length of " + - "your array first or use getMaybe or getWithDefault."); + var node = { + ctor: '_Array', + height: h + 1, + table: [], + lengths: [] + }; + nodes.push(node); + } + + nodes[h].table.push(toPush); + var len = length(toPush); + if (nodes[h].lengths.length > 0) + { + len += nodes[h].lengths[nodes[h].lengths.length - 1]; + } + nodes[h].lengths.push(len); + + if (nodes[h].table.length === M) + { + fromListPush(nodes[h], nodes); + nodes[h] = { + ctor: '_Array', + height: h + 1, + table: [], + lengths: [] + }; } - return unsafeGet(i, array); } + // Pushes an item via push_ to the bottom right of a tree. + function push(item, a) + { + var pushed = push_(item, a); + if (pushed !== null) + { + return pushed; + } + + var newTree = create(item, a.height); + return siblise(a, newTree); + } - function unsafeGet(i, array) + // Recursively tries to push an item to the bottom-right most + // tree possible. If there is no space left for the item, + // null will be returned. + function push_(item, a) { - for (var x = array.height; x > 0; x--) + // Handle resursion stop at leaf level. + if (a.height === 0) { - var slot = i >> (x * 5); - while (array.lengths[slot] <= i) + if (a.table.length < M) { - slot++; + var newA = { + ctor: '_Array', + height: 0, + table: a.table.slice() + }; + newA.table.push(item); + return newA; } - if (slot > 0) + else { - i -= array.lengths[slot - 1]; + return null; } - array = array.table[slot]; } - return array.table[i]; + + // Recursively push + var pushed = push_(item, botRight(a)); + + // There was space in the bottom right tree, so the slot will + // be updated. + if (pushed !== null) + { + var newA = nodeCopy(a); + newA.table[newA.table.length - 1] = pushed; + newA.lengths[newA.lengths.length - 1]++; + return newA; + } + + // When there was no space left, check if there is space left + // for a new slot with a tree which contains only the item + // at the bottom. + if (a.table.length < M) + { + var newSlot = create(item, a.height - 1); + var newA = nodeCopy(a); + newA.table.push(newSlot); + newA.lengths.push(newA.lengths[newA.lengths.length - 1] + length(newSlot)); + return newA; + } + else + { + return null; + } } + // Converts an array into a list of elements. + function toList(a) + { + return toList_(List.Nil, a); + } - // Sets the value at the index i. Only the nodes leading to i will get - // copied and updated. - function set(i, item, array) + function toList_(list, a) { - if (i < 0 || length(array) <= i) + for (var i = a.table.length - 1; i >= 0; i--) { - return array; + list = + a.height === 0 + ? List.Cons(a.table[i], list) + : toList_(list, a.table[i]); } - return unsafeSet(i, item, array); + return list; } + // Maps a function over the elements of an array. + function map(f, a) + { + var newA = { + ctor: '_Array', + height: a.height, + table: new Array(a.table.length) + }; + if (a.height > 0) + { + newA.lengths = a.lengths; + } + for (var i = 0; i < a.table.length; i++) + { + newA.table[i] = + a.height === 0 + ? f(a.table[i]) + : map(f, a.table[i]); + } + return newA; + } - function unsafeSet(i, item, array) + // Maps a function over the elements with their index as first argument. + function indexedMap(f, a) { - array = nodeCopy(array); + return indexedMap_(f, a, 0); + } + + function indexedMap_(f, a, from) + { + var newA = { + ctor: '_Array', + height: a.height, + table: new Array(a.table.length) + }; + if (a.height > 0) + { + newA.lengths = a.lengths; + } + for (var i = 0; i < a.table.length; i++) + { + newA.table[i] = + a.height === 0 + ? A2(f, from + i, a.table[i]) + : indexedMap_(f, a.table[i], i == 0 ? from : from + a.lengths[i - 1]); + } + return newA; + } - if (array.height == 0) + function foldl(f, b, a) + { + if (a.height === 0) { - array.table[i] = item; + for (var i = 0; i < a.table.length; i++) + { + b = A2(f, a.table[i], b); + } + } + else + { + for (var i = 0; i < a.table.length; i++) + { + b = foldl(f, b, a.table[i]); + } + } + return b; + } + + function foldr(f, b, a) + { + if (a.height === 0) + { + for (var i = a.table.length; i--; ) + { + b = A2(f, a.table[i], b); + } } else { - var slot = getSlot(i, array); - if (slot > 0) + for (var i = a.table.length; i--; ) { - i -= array.lengths[slot - 1]; + b = foldr(f, b, a.table[i]); } - array.table[slot] = unsafeSet(i, item, array.table[slot]); } - return array; + return b; } - - function initialize(len, f) + // TODO: currently, it slices the right, then the left. This can be + // optimized. + function slice(from, to, a) { - if (len == 0) + if (from < 0) { - return empty; + from += length(a); } - var h = Math.floor( Math.log(len) / Math.log(M) ); - return initialize_(f, h, 0, len); + if (to < 0) + { + to += length(a); + } + return sliceLeft(from, sliceRight(to, a)); } - function initialize_(f, h, from, to) + function sliceRight(to, a) { - if (h == 0) + if (to === length(a)) { - var table = new Array((to - from) % (M + 1)); - for (var i = 0; i < table.length; i++) - { - table[i] = f(from + i); - } - return { - ctor: "_Array", - height: 0, - table: table - }; + return a; } - var step = Math.pow(M, h); - var table = new Array(Math.ceil((to - from) / step)); - var lengths = new Array(table.length); - for (var i = 0; i < table.length; i++) + // Handle leaf level. + if (a.height === 0) { - table[i] = initialize_(f, h - 1, from + (i * step), Math.min(from + ((i + 1) * step), to)); - lengths[i] = length(table[i]) + (i > 0 ? lengths[i-1] : 0); + var newA = { ctor:'_Array', height:0 }; + newA.table = a.table.slice(0, to); + return newA; } - return { - ctor: "_Array", - height: h, - table: table, - lengths: lengths - }; - } - function fromList(list) - { - if (list == List.Nil) + // Slice the right recursively. + var right = getSlot(to, a); + var sliced = sliceRight(to - (right > 0 ? a.lengths[right - 1] : 0), a.table[right]); + + // Maybe the a node is not even needed, as sliced contains the whole slice. + if (right === 0) { - return empty; + return sliced; } - // Allocate M sized blocks (table) and write list elements to it. - var table = new Array(M); - var nodes = new Array(); - var i = 0; - - while (list.ctor !== '[]') + // Create new node. + var newA = { + ctor: '_Array', + height: a.height, + table: a.table.slice(0, right), + lengths: a.lengths.slice(0, right) + }; + if (sliced.table.length > 0) { - table[i] = list._0; - list = list._1; - i++; - - // table is full, so we can push a leaf containing it into the - // next node. - if (i == M) - { - var leaf = { - ctor: "_Array", - height: 0, - table: table - }; - fromListPush(leaf, nodes); - table = new Array(M); - i = 0; - } + newA.table[right] = sliced; + newA.lengths[right] = length(sliced) + (right > 0 ? newA.lengths[right - 1] : 0); } + return newA; + } - // Maybe there is something left on the table. - if (i > 0) + function sliceLeft(from, a) + { + if (from === 0) { - var leaf = { - ctor: "_Array", - height: 0, - table: table.splice(0,i) - }; - fromListPush(leaf, nodes); + return a; } - // Go through all of the nodes and eventually push them into higher nodes. - for (var h = 0; h < nodes.length - 1; h++) + // Handle leaf level. + if (a.height === 0) { - if (nodes[h].table.length > 0) - { - fromListPush(nodes[h], nodes); - } + var newA = { ctor:'_Array', height:0 }; + newA.table = a.table.slice(from, a.table.length + 1); + return newA; } - var head = nodes[nodes.length - 1]; - if (head.height > 0 && head.table.length == 1) + // Slice the left recursively. + var left = getSlot(from, a); + var sliced = sliceLeft(from - (left > 0 ? a.lengths[left - 1] : 0), a.table[left]); + + // Maybe the a node is not even needed, as sliced contains the whole slice. + if (left === a.table.length - 1) { - return head.table[0]; + return sliced; } - else + + // Create new node. + var newA = { + ctor: '_Array', + height: a.height, + table: a.table.slice(left, a.table.length + 1), + lengths: new Array(a.table.length - left) + }; + newA.table[0] = sliced; + var len = 0; + for (var i = 0; i < newA.table.length; i++) { - return head; + len += length(newA.table[i]); + newA.lengths[i] = len; } + + return newA; } - // Push a node into a higher node as a child. - function fromListPush(toPush, nodes) + // Appends two trees. + function append(a,b) { - var h = toPush.height; - - // Maybe the node on this height does not exist. - if (nodes.length == h) + if (a.table.length === 0) { - var node = { - ctor: "_Array", - height: h + 1, - table: new Array(), - lengths: new Array() - }; - nodes.push(node); + return b; } - - nodes[h].table.push(toPush); - var len = length(toPush); - if (nodes[h].lengths.length > 0) + if (b.table.length === 0) { - len += nodes[h].lengths[nodes[h].lengths.length - 1]; + return a; } - nodes[h].lengths.push(len); - if (nodes[h].table.length == M) + var c = append_(a, b); + + // Check if both nodes can be crunshed together. + if (c[0].table.length + c[1].table.length <= M) { - fromListPush(nodes[h], nodes); - nodes[h] = { - ctor: "_Array", - height: h + 1, - table: new Array(), - lengths: new Array() - }; + if (c[0].table.length === 0) + { + return c[1]; + } + if (c[1].table.length === 0) + { + return c[0]; + } + + // Adjust .table and .lengths + c[0].table = c[0].table.concat(c[1].table); + if (c[0].height > 0) + { + var len = length(c[0]); + for (var i = 0; i < c[1].lengths.length; i++) + { + c[1].lengths[i] += len; + } + c[0].lengths = c[0].lengths.concat(c[1].lengths); + } + + return c[0]; } - } - // Pushes an item via push_ to the bottom right of a tree. - function push(item, a) - { - var pushed = push_(item, a); - if (pushed !== null) + if (c[0].height > 0) { - return pushed; + var toRemove = calcToRemove(a, b); + if (toRemove > E) + { + c = shuffle(c[0], c[1], toRemove); + } } - var newTree = create(item, a.height); - return siblise(a, newTree); + return siblise(c[0], c[1]); } - // Recursively tries to push an item to the bottom-right most - // tree possible. If there is no space left for the item, - // null will be returned. - function push_(item, a) + // Returns an array of two nodes; right and left. One node _may_ be empty. + function append_(a, b) { - // Handle resursion stop at leaf level. - if (a.height == 0) + if (a.height === 0 && b.height === 0) { - if (a.table.length < M) + return [a, b]; + } + + if (a.height !== 1 || b.height !== 1) + { + if (a.height === b.height) { - var newA = { - ctor: "_Array", - height: 0, - table: a.table.slice() - }; - newA.table.push(item); - return newA; + a = nodeCopy(a); + b = nodeCopy(b); + var appended = append_(botRight(a), botLeft(b)); + + insertRight(a, appended[1]); + insertLeft(b, appended[0]); } - else + else if (a.height > b.height) { - return null; - } - } + a = nodeCopy(a); + var appended = append_(botRight(a), b); - // Recursively push - var pushed = push_(item, botRight(a)); + insertRight(a, appended[0]); + b = parentise(appended[1], appended[1].height + 1); + } + else + { + b = nodeCopy(b); + var appended = append_(a, botLeft(b)); - // There was space in the bottom right tree, so the slot will - // be updated. - if (pushed != null) - { - var newA = nodeCopy(a); - newA.table[newA.table.length - 1] = pushed; - newA.lengths[newA.lengths.length - 1]++; - return newA; + var left = appended[0].table.length === 0 ? 0 : 1; + var right = left === 0 ? 1 : 0; + insertLeft(b, appended[left]); + a = parentise(appended[right], appended[right].height + 1); + } } - // When there was no space left, check if there is space left - // for a new slot with a tree which contains only the item - // at the bottom. - if (a.table.length < M) + // Check if balancing is needed and return based on that. + if (a.table.length === 0 || b.table.length === 0) { - var newSlot = create(item, a.height - 1); - var newA = nodeCopy(a); - newA.table.push(newSlot); - newA.lengths.push(newA.lengths[newA.lengths.length - 1] + length(newSlot)); - return newA; + return [a, b]; } - else + + var toRemove = calcToRemove(a, b); + if (toRemove <= E) { - return null; + return [a, b]; } + return shuffle(a, b, toRemove); } - // Converts an array into a list of elements. - function toList(a) + // Helperfunctions for append_. Replaces a child node at the side of the parent. + function insertRight(parent, node) { - return toList_(List.Nil, a); + var index = parent.table.length - 1; + parent.table[index] = node; + parent.lengths[index] = length(node); + parent.lengths[index] += index > 0 ? parent.lengths[index - 1] : 0; } - function toList_(list, a) + function insertLeft(parent, node) { - for (var i = a.table.length - 1; i >= 0; i--) + if (node.table.length > 0) { - list = - a.height == 0 - ? List.Cons(a.table[i], list) - : toList_(list, a.table[i]); + parent.table[0] = node; + parent.lengths[0] = length(node); + + var len = length(parent.table[0]); + for (var i = 1; i < parent.lengths.length; i++) + { + len += length(parent.table[i]); + parent.lengths[i] = len; + } + } + else + { + parent.table.shift(); + for (var i = 1; i < parent.lengths.length; i++) + { + parent.lengths[i] = parent.lengths[i] - parent.lengths[0]; + } + parent.lengths.shift(); } - return list; } - // Maps a function over the elements of an array. - function map(f, a) + // Returns the extra search steps for E. Refer to the paper. + function calcToRemove(a, b) { - var newA = { - ctor: "_Array", - height: a.height, - table: new Array(a.table.length) - }; - if (a.height > 0) + var subLengths = 0; + for (var i = 0; i < a.table.length; i++) { - newA.lengths = a.lengths; + subLengths += a.table[i].table.length; } - for (var i = 0; i < a.table.length; i++) + for (var i = 0; i < b.table.length; i++) { - newA.table[i] = - a.height == 0 - ? f(a.table[i]) - : map(f, a.table[i]); + subLengths += b.table[i].table.length; } - return newA; - } - // Maps a function over the elements with their index as first argument. - function indexedMap(f, a) - { - return indexedMap_(f, a, 0); + var toRemove = a.table.length + b.table.length; + return toRemove - (Math.floor((subLengths - 1) / M) + 1); } - function indexedMap_(f, a, from) + // get2, set2 and saveSlot are helpers for accessing elements over two arrays. + function get2(a, b, index) { - var newA = { - ctor: "_Array", - height: a.height, - table: new Array(a.table.length) - }; - if (a.height > 0) - { - newA.lengths = a.lengths; - } - for (var i = 0; i < a.table.length; i++) - { - newA.table[i] = - a.height == 0 - ? A2(f, from + i, a.table[i]) - : indexedMap_(f, a.table[i], i == 0 ? 0 : a.lengths[i - 1]); - } - return newA; + return index < a.length + ? a[index] + : b[index - a.length]; } - function foldl(f, b, a) + function set2(a, b, index, value) { - if (a.height == 0) + if (index < a.length) { - for (var i = 0; i < a.table.length; i++) - { - b = A2(f, a.table[i], b); - } + a[index] = value; } else { - for (var i = 0; i < a.table.length; i++) - { - b = foldl(f, b, a.table[i]); - } + b[index - a.length] = value; } - return b; } - function foldr(f, b, a) + function saveSlot(a, b, index, slot) { - if (a.height == 0) - { - for (var i = a.table.length; i--; ) - { - b = A2(f, a.table[i], b); - } - } - else - { - for (var i = a.table.length; i--; ) - { - b = foldr(f, b, a.table[i]); - } - } - return b; + set2(a.table, b.table, index, slot); + + var l = (index === 0 || index === a.lengths.length) + ? 0 + : get2(a.lengths, a.lengths, index - 1); + + set2(a.lengths, b.lengths, index, l + length(slot)); } - // TODO: currently, it slices the right, then the left. This can be - // optimized. - function slice(from, to, a) + // Creates a node or leaf with a given length at their arrays for perfomance. + // Is only used by shuffle. + function createNode(h, length) { - if (from < 0) + if (length < 0) { - from += length(a); + length = 0; } - if (to < 0) + var a = { + ctor: '_Array', + height: h, + table: new Array(length) + }; + if (h > 0) { - to += length(a); + a.lengths = new Array(length); } - return sliceLeft(from, sliceRight(to, a)); + return a; } - function sliceRight(to, a) + // Returns an array of two balanced nodes. + function shuffle(a, b, toRemove) { - if (to == length(a)) - { - return a; - } + var newA = createNode(a.height, Math.min(M, a.table.length + b.table.length - toRemove)); + var newB = createNode(a.height, newA.table.length - (a.table.length + b.table.length - toRemove)); - // Handle leaf level. - if (a.height == 0) + // Skip the slots with size M. More precise: copy the slot references + // to the new node + var read = 0; + while (get2(a.table, b.table, read).table.length % M === 0) { - var newA = { ctor:"_Array", height:0 }; - newA.table = a.table.slice(0, to); - return newA; + set2(newA.table, newB.table, read, get2(a.table, b.table, read)); + set2(newA.lengths, newB.lengths, read, get2(a.lengths, b.lengths, read)); + read++; } - // Slice the right recursively. - var right = getSlot(to, a); - var sliced = sliceRight(to - (right > 0 ? a.lengths[right - 1] : 0), a.table[right]); + // Pulling items from left to right, caching in a slot before writing + // it into the new nodes. + var write = read; + var slot = new createNode(a.height - 1, 0); + var from = 0; - // Maybe the a node is not even needed, as sliced contains the whole slice. - if (right == 0) + // If the current slot is still containing data, then there will be at + // least one more write, so we do not break this loop yet. + while (read - write - (slot.table.length > 0 ? 1 : 0) < toRemove) { - return sliced; - } + // Find out the max possible items for copying. + var source = get2(a.table, b.table, read); + var to = Math.min(M - slot.table.length, source.table.length); - // Create new node. - var newA = { - ctor: "_Array", - height: a.height, - table: a.table.slice(0, right), - lengths: a.lengths.slice(0, right) - }; - if (sliced.table.length > 0) - { - newA.table[right] = sliced; - newA.lengths[right] = length(sliced) + (right > 0 ? newA.lengths[right - 1] : 0); + // Copy and adjust size table. + slot.table = slot.table.concat(source.table.slice(from, to)); + if (slot.height > 0) + { + var len = slot.lengths.length; + for (var i = len; i < len + to - from; i++) + { + slot.lengths[i] = length(slot.table[i]); + slot.lengths[i] += (i > 0 ? slot.lengths[i - 1] : 0); + } + } + + from += to; + + // Only proceed to next slots[i] if the current one was + // fully copied. + if (source.table.length <= to) + { + read++; from = 0; + } + + // Only create a new slot if the current one is filled up. + if (slot.table.length === M) + { + saveSlot(newA, newB, write, slot); + slot = createNode(a.height - 1, 0); + write++; + } } - return newA; - } - function sliceLeft(from, a) - { - if (from == 0) + // Cleanup after the loop. Copy the last slot into the new nodes. + if (slot.table.length > 0) { - return a; + saveSlot(newA, newB, write, slot); + write++; } - // Handle leaf level. - if (a.height == 0) + // Shift the untouched slots to the left + while (read < a.table.length + b.table.length ) { - var newA = { ctor:"_Array", height:0 }; - newA.table = a.table.slice(from, a.table.length + 1); - return newA; + saveSlot(newA, newB, write, get2(a.table, b.table, read)); + read++; + write++; } - // Slice the left recursively. - var left = getSlot(from, a); - var sliced = sliceLeft(from - (left > 0 ? a.lengths[left - 1] : 0), a.table[left]); + return [newA, newB]; + } - // Maybe the a node is not even needed, as sliced contains the whole slice. - if (left == a.table.length - 1) - { - return sliced; - } + // Navigation functions + function botRight(a) + { + return a.table[a.table.length - 1]; + } + function botLeft(a) + { + return a.table[0]; + } - // Create new node. + // Copies a node for updating. Note that you should not use this if + // only updating only one of "table" or "lengths" for performance reasons. + function nodeCopy(a) + { var newA = { - ctor: "_Array", + ctor: '_Array', height: a.height, - table: a.table.slice(left, a.table.length + 1), - lengths: new Array(a.table.length - left) + table: a.table.slice() }; - newA.table[0] = sliced; - var len = 0; - for (var i = 0; i < newA.table.length; i++) + if (a.height > 0) { - len += length(newA.table[i]); - newA.lengths[i] = len; + newA.lengths = a.lengths.slice(); } - return newA; } - // Appends two trees. - function append(a,b) + // Returns how many items are in the tree. + function length(array) { - if (a.table.length === 0) + if (array.height === 0) { - return b; + return array.table.length; } - if (b.table.length === 0) + else { - return a; + return array.lengths[array.lengths.length - 1]; } + } - var c = append_(a, b); - - // Check if both nodes can be crunshed together. - if (c[0].table.length + c[1].table.length <= M) + // Calculates in which slot of "table" the item probably is, then + // find the exact slot via forward searching in "lengths". Returns the index. + function getSlot(i, a) + { + var slot = i >> (5 * a.height); + while (a.lengths[slot] <= i) { - if (c[0].table.length === 0) - { - return c[1]; - } - if (c[1].table.length === 0) - { - return c[0]; - } - - // Adjust .table and .lengths - c[0].table = c[0].table.concat(c[1].table); - if (c[0].height > 0) - { - var len = length(c[0]); - for (var i = 0; i < c[1].lengths.length; i++) - { - c[1].lengths[i] += len; - } - c[0].lengths = c[0].lengths.concat(c[1].lengths); - } - - return c[0]; + slot++; } + return slot; + } - if (c[0].height > 0) + // Recursively creates a tree with a given height containing + // only the given item. + function create(item, h) + { + if (h === 0) { - var toRemove = calcToRemove(a, b); - if (toRemove > E) - { - c = shuffle(c[0], c[1], toRemove); - } + return { + ctor: '_Array', + height: 0, + table: [item] + }; } - - return siblise(c[0], c[1]); + return { + ctor: '_Array', + height: h, + table: [create(item, h - 1)], + lengths: [1] + }; } - // Returns an array of two nodes; right and left. One node _may_ be empty. - function append_(a, b) + // Recursively creates a tree that contains the given tree. + function parentise(tree, h) { - if (a.height === 0 && b.height === 0) + if (h === tree.height) { - return [a, b]; + return tree; } - if (a.height !== 1 || b.height !== 1) - { - if (a.height === b.height) - { - a = nodeCopy(a); - b = nodeCopy(b); - var appended = append_(botRight(a), botLeft(b)); + return { + ctor: '_Array', + height: h, + table: [parentise(tree, h - 1)], + lengths: [length(tree)] + }; + } - insertRight(a, appended[1]); - insertLeft(b, appended[0]); - } - else if (a.height > b.height) - { - a = nodeCopy(a); - var appended = append_(botRight(a), b); + // Emphasizes blood brotherhood beneath two trees. + function siblise(a, b) + { + return { + ctor: '_Array', + height: a.height + 1, + table: [a, b], + lengths: [length(a), length(a) + length(b)] + }; + } - insertRight(a, appended[0]); - b = parentise(appended[1], appended[1].height + 1); + function toJSArray(a) + { + var jsArray = new Array(length(a)); + toJSArray_(jsArray, 0, a); + return jsArray; + } + + function toJSArray_(jsArray, i, a) + { + for (var t = 0; t < a.table.length; t++) + { + if (a.height === 0) + { + jsArray[i + t] = a.table[t]; } else { - b = nodeCopy(b); - var appended = append_(a, botLeft(b)); - - var left = appended[0].table.length === 0 ? 0 : 1; - var right = left === 0 ? 1 : 0; - insertLeft(b, appended[left]); - a = parentise(appended[right], appended[right].height + 1); + var inc = t === 0 ? 0 : a.lengths[t - 1]; + toJSArray_(jsArray, i + inc, a.table[t]); } } + } - // Check if balancing is needed and return based on that. - if (a.table.length === 0 || b.table.length === 0) + function fromJSArray(jsArray) + { + if (jsArray.length === 0) { - return [a,b]; + return empty; } + var h = Math.floor(Math.log(jsArray.length) / Math.log(M)); + return fromJSArray_(jsArray, h, 0, jsArray.length); + } - var toRemove = calcToRemove(a, b); - if (toRemove <= E) + function fromJSArray_(jsArray, h, from, to) + { + if (h === 0) { - return [a,b]; + return { + ctor: '_Array', + height: 0, + table: jsArray.slice(from, to) + }; } - return shuffle(a, b, toRemove); + + var step = Math.pow(M, h); + var table = new Array(Math.ceil((to - from) / step)); + var lengths = new Array(table.length); + for (var i = 0; i < table.length; i++) + { + table[i] = fromJSArray_(jsArray, h - 1, from + (i * step), Math.min(from + ((i + 1) * step), to)); + lengths[i] = length(table[i]) + (i > 0 ? lengths[i - 1] : 0); + } + return { + ctor: '_Array', + height: h, + table: table, + lengths: lengths + }; } - // Helperfunctions for append_. Replaces a child node at the side of the parent. - function insertRight(parent, node) + Elm.Native.Array.values = { + empty: empty, + fromList: fromList, + toList: toList, + initialize: F2(initialize), + append: F2(append), + push: F2(push), + slice: F3(slice), + get: F2(get), + set: F3(set), + map: F2(map), + indexedMap: F2(indexedMap), + foldl: F3(foldl), + foldr: F3(foldr), + length: length, + + toJSArray: toJSArray, + fromJSArray: fromJSArray + }; + + return localRuntime.Native.Array.values = Elm.Native.Array.values; +}; + +Elm.Native.Basics = {}; +Elm.Native.Basics.make = function(localRuntime) { + localRuntime.Native = localRuntime.Native || {}; + localRuntime.Native.Basics = localRuntime.Native.Basics || {}; + if (localRuntime.Native.Basics.values) { - var index = parent.table.length - 1; - parent.table[index] = node; - parent.lengths[index] = length(node) - parent.lengths[index] += index > 0 ? parent.lengths[index - 1] : 0; + return localRuntime.Native.Basics.values; } - function insertLeft(parent, node) - { - if (node.table.length > 0) - { - parent.table[0] = node; - parent.lengths[0] = length(node); + var Utils = Elm.Native.Utils.make(localRuntime); - var len = length(parent.table[0]); - for (var i = 1; i < parent.lengths.length; i++) - { - len += length(parent.table[i]); - parent.lengths[i] = len; - } - } - else + function div(a, b) + { + return (a / b) | 0; + } + function rem(a, b) + { + return a % b; + } + function mod(a, b) + { + if (b === 0) { - parent.table.shift(); - for (var i = 1; i < parent.lengths.length; i++) - { - parent.lengths[i] = parent.lengths[i] - parent.lengths[0]; - } - parent.lengths.shift(); + throw new Error('Cannot perform mod 0. Division by zero error.'); } + var r = a % b; + var m = a === 0 ? 0 : (b > 0 ? (a >= 0 ? r : r + b) : -mod(-a, -b)); + + return m === b ? 0 : m; + } + function logBase(base, n) + { + return Math.log(n) / Math.log(base); + } + function negate(n) + { + return -n; + } + function abs(n) + { + return n < 0 ? -n : n; } - // Returns the extra search steps for E. Refer to the paper. - function calcToRemove(a, b) + function min(a, b) { - var subLengths = 0; - for (var i = 0; i < a.table.length; i++) - { - subLengths += a.table[i].table.length; - } - for (var i = 0; i < b.table.length; i++) - { - subLengths += b.table[i].table.length; - } - - var toRemove = a.table.length + b.table.length - return toRemove - (Math.floor((subLengths - 1) / M) + 1); + return Utils.cmp(a, b) < 0 ? a : b; } - - // get2, set2 and saveSlot are helpers for accessing elements over two arrays. - function get2(a, b, index) + function max(a, b) { - return index < a.length - ? a[index] - : b[index - a.length]; + return Utils.cmp(a, b) > 0 ? a : b; } - - function set2(a, b, index, value) + function clamp(lo, hi, n) { - if (index < a.length) - { - a[index] = value; - } - else - { - b[index - a.length] = value; - } + return Utils.cmp(n, lo) < 0 ? lo : Utils.cmp(n, hi) > 0 ? hi : n; } - function saveSlot(a, b, index, slot) + function xor(a, b) { - set2(a.table, b.table, index, slot); - - var l = (index == 0 || index == a.lengths.length) - ? 0 - : get2(a.lengths, a.lengths, index - 1); - - set2(a.lengths, b.lengths, index, l + length(slot)); + return a !== b; } - - // Creates a node or leaf with a given length at their arrays for perfomance. - // Is only used by shuffle. - function createNode(h, length) + function not(b) { - if (length < 0) - { - length = 0; - } - var a = { - ctor: "_Array", - height: h, - table: new Array(length) - }; - if (h > 0) - { - a.lengths = new Array(length); - } - return a; + return !b; } - - // Returns an array of two balanced nodes. - function shuffle(a, b, toRemove) + function isInfinite(n) { - var newA = createNode(a.height, Math.min(M, a.table.length + b.table.length - toRemove)); - var newB = createNode(a.height, newA.table.length - (a.table.length + b.table.length - toRemove)); - - // Skip the slots with size M. More precise: copy the slot references - // to the new node - var read = 0; - while (get2(a.table, b.table, read).table.length % M == 0) - { - set2(newA.table, newB.table, read, get2(a.table, b.table, read)); - set2(newA.lengths, newB.lengths, read, get2(a.lengths, b.lengths, read)); - read++; - } + return n === Infinity || n === -Infinity; + } - // Pulling items from left to right, caching in a slot before writing - // it into the new nodes. - var write = read; - var slot = new createNode(a.height - 1, 0); - var from = 0; + function truncate(n) + { + return n | 0; + } - // If the current slot is still containing data, then there will be at - // least one more write, so we do not break this loop yet. - while (read - write - (slot.table.length > 0 ? 1 : 0) < toRemove) - { - // Find out the max possible items for copying. - var source = get2(a.table, b.table, read); - var to = Math.min(M - slot.table.length, source.table.length) + function degrees(d) + { + return d * Math.PI / 180; + } + function turns(t) + { + return 2 * Math.PI * t; + } + function fromPolar(point) + { + var r = point._0; + var t = point._1; + return Utils.Tuple2(r * Math.cos(t), r * Math.sin(t)); + } + function toPolar(point) + { + var x = point._0; + var y = point._1; + return Utils.Tuple2(Math.sqrt(x * x + y * y), Math.atan2(y, x)); + } - // Copy and adjust size table. - slot.table = slot.table.concat(source.table.slice(from, to)); - if (slot.height > 0) - { - var len = slot.lengths.length; - for (var i = len; i < len + to - from; i++) - { - slot.lengths[i] = length(slot.table[i]); - slot.lengths[i] += (i > 0 ? slot.lengths[i - 1] : 0); - } - } + return localRuntime.Native.Basics.values = { + div: F2(div), + rem: F2(rem), + mod: F2(mod), - from += to; + pi: Math.PI, + e: Math.E, + cos: Math.cos, + sin: Math.sin, + tan: Math.tan, + acos: Math.acos, + asin: Math.asin, + atan: Math.atan, + atan2: F2(Math.atan2), - // Only proceed to next slots[i] if the current one was - // fully copied. - if (source.table.length <= to) - { - read++; from = 0; - } + degrees: degrees, + turns: turns, + fromPolar: fromPolar, + toPolar: toPolar, - // Only create a new slot if the current one is filled up. - if (slot.table.length == M) - { - saveSlot(newA, newB, write, slot); - slot = createNode(a.height - 1,0); - write++; - } - } + sqrt: Math.sqrt, + logBase: F2(logBase), + negate: negate, + abs: abs, + min: F2(min), + max: F2(max), + clamp: F3(clamp), + compare: Utils.compare, - // Cleanup after the loop. Copy the last slot into the new nodes. - if (slot.table.length > 0) - { - saveSlot(newA, newB, write, slot); - write++; - } + xor: F2(xor), + not: not, - // Shift the untouched slots to the left - while (read < a.table.length + b.table.length ) - { - saveSlot(newA, newB, write, get2(a.table, b.table, read)); - read++; - write++; - } + truncate: truncate, + ceiling: Math.ceil, + floor: Math.floor, + round: Math.round, + toFloat: function(x) { return x; }, + isNaN: isNaN, + isInfinite: isInfinite + }; +}; - return [newA, newB]; - } +Elm.Native.Port = {}; - // Navigation functions - function botRight(a) - { - return a.table[a.table.length - 1]; - } - function botLeft(a) +Elm.Native.Port.make = function(localRuntime) { + localRuntime.Native = localRuntime.Native || {}; + localRuntime.Native.Port = localRuntime.Native.Port || {}; + if (localRuntime.Native.Port.values) { - return a.table[0]; + return localRuntime.Native.Port.values; } - // Copies a node for updating. Note that you should not use this if - // only updating only one of "table" or "lengths" for performance reasons. - function nodeCopy(a) - { - var newA = { - ctor: "_Array", - height: a.height, - table: a.table.slice() - }; - if (a.height > 0) - { - newA.lengths = a.lengths.slice(); - } - return newA; - } + var NS; - // Returns how many items are in the tree. - function length(array) - { - if (array.height == 0) - { - return array.table.length; - } - else - { - return array.lengths[array.lengths.length - 1]; - } - } + // INBOUND - // Calculates in which slot of "table" the item probably is, then - // find the exact slot via forward searching in "lengths". Returns the index. - function getSlot(i, a) + function inbound(name, type, converter) { - var slot = i >> (5 * a.height); - while (a.lengths[slot] <= i) + if (!localRuntime.argsTracker[name]) { - slot++; + throw new Error( + 'Port Error:\n' + + 'No argument was given for the port named \'' + name + '\' with type:\n\n' + + ' ' + type.split('\n').join('\n ') + '\n\n' + + 'You need to provide an initial value!\n\n' + + 'Find out more about ports here ' + ); } - return slot; + var arg = localRuntime.argsTracker[name]; + arg.used = true; + + return jsToElm(name, type, converter, arg.value); } - // Recursively creates a tree with a given height containing - // only the given item. - function create(item, h) + + function inboundSignal(name, type, converter) { - if (h == 0) + var initialValue = inbound(name, type, converter); + + if (!NS) { - return { - ctor: "_Array", - height: 0, - table: [item] - }; - } - return { - ctor: "_Array", - height: h, - table: [create(item, h - 1)], - lengths: [1] - }; - } + NS = Elm.Native.Signal.make(localRuntime); + } + var signal = NS.input('inbound-port-' + name, initialValue); - // Recursively creates a tree that contains the given tree. - function parentise(tree, h) - { - if (h == tree.height) + function send(jsValue) { - return tree; + var elmValue = jsToElm(name, type, converter, jsValue); + setTimeout(function() { + localRuntime.notify(signal.id, elmValue); + }, 0); } - return { - ctor: "_Array", - height: h, - table: [parentise(tree, h - 1)], - lengths: [length(tree)] - }; + localRuntime.ports[name] = { send: send }; + + return signal; } - // Emphasizes blood brotherhood beneath two trees. - function siblise(a, b) + + function jsToElm(name, type, converter, value) { - return { - ctor: "_Array", - height: a.height + 1, - table: [a, b], - lengths: [length(a), length(a) + length(b)] - }; + try + { + return converter(value); + } + catch(e) + { + throw new Error( + 'Port Error:\n' + + 'Regarding the port named \'' + name + '\' with type:\n\n' + + ' ' + type.split('\n').join('\n ') + '\n\n' + + 'You just sent the value:\n\n' + + ' ' + JSON.stringify(value) + '\n\n' + + 'but it cannot be converted to the necessary type.\n' + + e.message + ); + } } - function toJSArray(a) + + // OUTBOUND + + function outbound(name, converter, elmValue) { - var jsArray = new Array(length(a)); - toJSArray_(jsArray, 0, a); - return jsArray; + localRuntime.ports[name] = converter(elmValue); } - function toJSArray_(jsArray, i, a) + + function outboundSignal(name, converter, signal) { - for (var t = 0; t < a.table.length; t++) + var subscribers = []; + + function subscribe(handler) { - if (a.height == 0) - { - jsArray[i + t] = a.table[t]; - } - else - { - var inc = t == 0 ? 0 : a.lengths[t - 1]; - toJSArray_(jsArray, i + inc, a.table[t]); - } + subscribers.push(handler); } - } - - function fromJSArray(jsArray) - { - if (jsArray.length == 0) + function unsubscribe(handler) { - return empty; + subscribers.pop(subscribers.indexOf(handler)); } - var h = Math.floor(Math.log(jsArray.length) / Math.log(M)); - return fromJSArray_(jsArray, h, 0, jsArray.length); - } - function fromJSArray_(jsArray, h, from, to) - { - if (h == 0) + function notify(elmValue) { - return { - ctor: "_Array", - height: 0, - table: jsArray.slice(from, to) - }; + var jsValue = converter(elmValue); + var len = subscribers.length; + for (var i = 0; i < len; ++i) + { + subscribers[i](jsValue); + } } - var step = Math.pow(M, h); - var table = new Array(Math.ceil((to - from) / step)); - var lengths = new Array(table.length); - for (var i = 0; i < table.length; i++) + if (!NS) { - table[i] = fromJSArray_(jsArray, h - 1, from + (i * step), Math.min(from + ((i + 1) * step), to)); - lengths[i] = length(table[i]) + (i > 0 ? lengths[i-1] : 0); + NS = Elm.Native.Signal.make(localRuntime); } - return { - ctor: "_Array", - height: h, - table: table, - lengths: lengths + NS.output('outbound-port-' + name, notify, signal); + + localRuntime.ports[name] = { + subscribe: subscribe, + unsubscribe: unsubscribe }; + + return signal; } - Elm.Native.Array.values = { - empty: empty, - fromList: fromList, - toList: toList, - initialize: F2(initialize), - append: F2(append), - push: F2(push), - slice: F3(slice), - get: F2(get), - set: F3(set), - map: F2(map), - indexedMap: F2(indexedMap), - foldl: F3(foldl), - foldr: F3(foldr), - length: length, - toJSArray:toJSArray, - fromJSArray:fromJSArray + return localRuntime.Native.Port.values = { + inbound: inbound, + outbound: outbound, + inboundSignal: inboundSignal, + outboundSignal: outboundSignal }; +}; - return localRuntime.Native.Array.values = Elm.Native.Array.values; +if (!Elm.fullscreen) { + (function() { + 'use strict'; -} + var Display = { + FULLSCREEN: 0, + COMPONENT: 1, + NONE: 2 + }; -Elm.Native.Basics = {}; -Elm.Native.Basics.make = function(localRuntime) { + Elm.fullscreen = function(module, args) + { + var container = document.createElement('div'); + document.body.appendChild(container); + return init(Display.FULLSCREEN, container, module, args || {}); + }; - localRuntime.Native = localRuntime.Native || {}; - localRuntime.Native.Basics = localRuntime.Native.Basics || {}; - if (localRuntime.Native.Basics.values) - { - return localRuntime.Native.Basics.values; - } + Elm.embed = function(module, container, args) + { + var tag = container.tagName; + if (tag !== 'DIV') + { + throw new Error('Elm.node must be given a DIV, not a ' + tag + '.'); + } + return init(Display.COMPONENT, container, module, args || {}); + }; - var Utils = Elm.Native.Utils.make(localRuntime); + Elm.worker = function(module, args) + { + return init(Display.NONE, {}, module, args || {}); + }; - function div(a, b) - { - return (a/b)|0; - } - function rem(a, b) - { - return a % b; - } - function mod(a, b) - { - if (b === 0) + function init(display, container, module, args, moduleToReplace) { - throw new Error("Cannot perform mod 0. Division by zero error."); - } - var r = a % b; - var m = a === 0 ? 0 : (b > 0 ? (a >= 0 ? r : r+b) : -mod(-a,-b)); + // defining state needed for an instance of the Elm RTS + var inputs = []; - return m === b ? 0 : m; - } - function logBase(base, n) - { - return Math.log(n) / Math.log(base); - } - function negate(n) - { - return -n; - } - function abs(n) - { - return n < 0 ? -n : n; - } + /* OFFSET + * Elm's time traveling debugger lets you pause time. This means + * "now" may be shifted a bit into the past. By wrapping Date.now() + * we can manage this. + */ + var timer = { + programStart: Date.now(), + now: function() + { + return Date.now(); + } + }; - function min(a, b) - { - return Utils.cmp(a,b) < 0 ? a : b; - } - function max(a, b) - { - return Utils.cmp(a,b) > 0 ? a : b; - } - function clamp(lo, hi, n) - { - return Utils.cmp(n,lo) < 0 ? lo : Utils.cmp(n,hi) > 0 ? hi : n; - } + var updateInProgress = false; + function notify(id, v) + { + if (updateInProgress) + { + throw new Error( + 'The notify function has been called synchronously!\n' + + 'This can lead to frames being dropped.\n' + + 'Definitely report this to \n'); + } + updateInProgress = true; + var timestep = timer.now(); + for (var i = inputs.length; i--; ) + { + inputs[i].notify(timestep, id, v); + } + updateInProgress = false; + } + function setTimeout(func, delay) + { + return window.setTimeout(func, delay); + } - function xor(a, b) - { - return a !== b; - } - function not(b) - { - return !b; - } - function isInfinite(n) - { - return n === Infinity || n === -Infinity - } + var listeners = []; + function addListener(relevantInputs, domNode, eventName, func) + { + domNode.addEventListener(eventName, func); + var listener = { + relevantInputs: relevantInputs, + domNode: domNode, + eventName: eventName, + func: func + }; + listeners.push(listener); + } - function truncate(n) - { - return n|0; - } + var argsTracker = {}; + for (var name in args) + { + argsTracker[name] = { + value: args[name], + used: false + }; + } - function degrees(d) - { - return d * Math.PI / 180; - } - function turns(t) - { - return 2 * Math.PI * t; - } - function fromPolar(point) - { - var r = point._0; - var t = point._1; - return Utils.Tuple2(r * Math.cos(t), r * Math.sin(t)); - } - function toPolar(point) - { - var x = point._0; - var y = point._1; - return Utils.Tuple2(Math.sqrt(x * x + y * y), Math.atan2(y,x)); - } + // create the actual RTS. Any impure modules will attach themselves to this + // object. This permits many Elm programs to be embedded per document. + var elm = { + notify: notify, + setTimeout: setTimeout, + node: container, + addListener: addListener, + inputs: inputs, + timer: timer, + argsTracker: argsTracker, + ports: {}, - return localRuntime.Native.Basics.values = { - div: F2(div), - rem: F2(rem), - mod: F2(mod), + isFullscreen: function() { return display === Display.FULLSCREEN; }, + isEmbed: function() { return display === Display.COMPONENT; }, + isWorker: function() { return display === Display.NONE; } + }; - pi: Math.PI, - e: Math.E, - cos: Math.cos, - sin: Math.sin, - tan: Math.tan, - acos: Math.acos, - asin: Math.asin, - atan: Math.atan, - atan2: F2(Math.atan2), + function swap(newModule) + { + removeListeners(listeners); + var div = document.createElement('div'); + var newElm = init(display, div, newModule, args, elm); + inputs = []; - degrees: degrees, - turns: turns, - fromPolar: fromPolar, - toPolar: toPolar, + return newElm; + } - sqrt: Math.sqrt, - logBase: F2(logBase), - negate: negate, - abs: abs, - min: F2(min), - max: F2(max), - clamp: F3(clamp), - compare: Utils.compare, + function dispose() + { + removeListeners(listeners); + inputs = []; + } - xor: F2(xor), - not: not, + var Module = {}; + try + { + Module = module.make(elm); + checkInputs(elm); + } + catch (error) + { + if (typeof container.appendChild === "function") + { + container.appendChild(errorNode(error.message)); + } + else + { + console.error(error.message); + } + throw error; + } - truncate: truncate, - ceiling: Math.ceil, - floor: Math.floor, - round: Math.round, - toFloat: function(x) { return x; }, - isNaN: isNaN, - isInfinite: isInfinite - }; -}; + if (display !== Display.NONE) + { + var graphicsNode = initGraphics(elm, Module); + } -Elm.Native.Char = {}; -Elm.Native.Char.make = function(localRuntime) { - localRuntime.Native = localRuntime.Native || {}; - localRuntime.Native.Char = localRuntime.Native.Char || {}; - if (localRuntime.Native.Char.values) - { - return localRuntime.Native.Char.values; - } + var rootNode = { kids: inputs }; + trimDeadNodes(rootNode); + inputs = rootNode.kids; + filterListeners(inputs, listeners); - var Utils = Elm.Native.Utils.make(localRuntime); + addReceivers(elm.ports); - return localRuntime.Native.Char.values = { - fromCode : function(c) { return Utils.chr(String.fromCharCode(c)); }, - toCode : function(c) { return c.charCodeAt(0); }, - toUpper : function(c) { return Utils.chr(c.toUpperCase()); }, - toLower : function(c) { return Utils.chr(c.toLowerCase()); }, - toLocaleUpper : function(c) { return Utils.chr(c.toLocaleUpperCase()); }, - toLocaleLower : function(c) { return Utils.chr(c.toLocaleLowerCase()); }, - }; -}; + if (typeof moduleToReplace !== 'undefined') + { + hotSwap(moduleToReplace, elm); -Elm.Native.Color = {}; -Elm.Native.Color.make = function(localRuntime) { - localRuntime.Native = localRuntime.Native || {}; - localRuntime.Native.Color = localRuntime.Native.Color || {}; - if (localRuntime.Native.Color.values) - { - return localRuntime.Native.Color.values; - } + // rerender scene if graphics are enabled. + if (typeof graphicsNode !== 'undefined') + { + graphicsNode.notify(0, true, 0); + } + } - function toCss(c) - { - var format = ''; - var colors = ''; - if (c.ctor === 'RGBA') - { - format = 'rgb'; - colors = c._0 + ', ' + c._1 + ', ' + c._2; - } - else - { - format = 'hsl'; - colors = (c._0 * 180 / Math.PI) + ', ' + - (c._1 * 100) + '%, ' + - (c._2 * 100) + '%'; + return { + swap: swap, + ports: elm.ports, + dispose: dispose + }; } - if (c._3 === 1) + + function checkInputs(elm) { - return format + '(' + colors + ')'; + var argsTracker = elm.argsTracker; + for (var name in argsTracker) + { + if (!argsTracker[name].used) + { + throw new Error( + "Port Error:\nYou provided an argument named '" + name + + "' but there is no corresponding port!\n\n" + + "Maybe add a port '" + name + "' to your Elm module?\n" + + "Maybe remove the '" + name + "' argument from your initialization code in JS?" + ); + } + } } - else + + function errorNode(message) { - return format + 'a(' + colors + ', ' + c._3 + ')'; - } - } + var code = document.createElement('code'); - return localRuntime.Native.Color.values = { - toCss: toCss - }; + var lines = message.split('\n'); + code.appendChild(document.createTextNode(lines[0])); + code.appendChild(document.createElement('br')); + code.appendChild(document.createElement('br')); + for (var i = 1; i < lines.length; ++i) + { + code.appendChild(document.createTextNode('\u00A0 \u00A0 ' + lines[i].replace(/ /g, '\u00A0 '))); + code.appendChild(document.createElement('br')); + } + code.appendChild(document.createElement('br')); + code.appendChild(document.createTextNode('Open the developer console for more details.')); + return code; + } -}; -Elm.Native.Debug = {}; -Elm.Native.Debug.make = function(localRuntime) { - localRuntime.Native = localRuntime.Native || {}; - localRuntime.Native.Debug = localRuntime.Native.Debug || {}; - if (localRuntime.Native.Debug.values) - { - return localRuntime.Native.Debug.values; - } + //// FILTER SIGNALS //// - var toString = Elm.Native.Show.make(localRuntime).toString; + // TODO: move this code into the signal module and create a function + // Signal.initializeGraph that actually instantiates everything. - function log(tag, value) - { - var msg = tag + ': ' + toString(value); - var process = process || {}; - if (process.stdout) - { - process.stdout.write(msg); - } - else + function filterListeners(inputs, listeners) { - console.log(msg); + loop: + for (var i = listeners.length; i--; ) + { + var listener = listeners[i]; + for (var j = inputs.length; j--; ) + { + if (listener.relevantInputs.indexOf(inputs[j].id) >= 0) + { + continue loop; + } + } + listener.domNode.removeEventListener(listener.eventName, listener.func); + } } - return value; - } - - function crash(message) - { - throw new Error(message); - } - function tracePath(tag, form) - { - if (localRuntime.debug) + function removeListeners(listeners) { - return localRuntime.debug.trace(tag, form); + for (var i = listeners.length; i--; ) + { + var listener = listeners[i]; + listener.domNode.removeEventListener(listener.eventName, listener.func); + } } - return form; - } - function watch(tag, value) - { - if (localRuntime.debug) + // add receivers for built-in ports if they are defined + function addReceivers(ports) { - localRuntime.debug.watch(tag, value); + if ('title' in ports) + { + if (typeof ports.title === 'string') + { + document.title = ports.title; + } + else + { + ports.title.subscribe(function(v) { document.title = v; }); + } + } + if ('redirect' in ports) + { + ports.redirect.subscribe(function(v) { + if (v.length > 0) + { + window.location = v; + } + }); + } } - return value; - } - function watchSummary(tag, summarize, value) - { - if (localRuntime.debug) + + // returns a boolean representing whether the node is alive or not. + function trimDeadNodes(node) { - localRuntime.debug.watch(tag, summarize(value)); - } - return value; - } + if (node.isOutput) + { + return true; + } - return localRuntime.Native.Debug.values = { - crash: crash, - tracePath: F2(tracePath), - log: F2(log), - watch: F2(watch), - watchSummary:F3(watchSummary), - }; -}; + var liveKids = []; + for (var i = node.kids.length; i--; ) + { + var kid = node.kids[i]; + if (trimDeadNodes(kid)) + { + liveKids.push(kid); + } + } + node.kids = liveKids; -Elm.Native.Effects = {}; -Elm.Native.Effects.make = function(localRuntime) { + return liveKids.length > 0; + } - localRuntime.Native = localRuntime.Native || {}; - localRuntime.Native.Effects = localRuntime.Native.Effects || {}; - if (localRuntime.Native.Effects.values) - { - return localRuntime.Native.Effects.values; - } - var Task = Elm.Native.Task.make(localRuntime); - var Utils = Elm.Native.Utils.make(localRuntime); - var Signal = Elm.Signal.make(localRuntime); - var List = Elm.Native.List.make(localRuntime); + //// RENDERING //// + + function initGraphics(elm, Module) + { + if (!('main' in Module)) + { + throw new Error("'main' is missing! What do I display?!"); + } + var signalGraph = Module.main; - // polyfill so things will work even if rAF is not available for some reason - var _requestAnimationFrame = - typeof requestAnimationFrame !== 'undefined' - ? requestAnimationFrame - : function(cb) { setTimeout(cb, 1000 / 60); } - ; + // make sure the signal graph is actually a signal & extract the visual model + if (!('notify' in signalGraph)) + { + signalGraph = Elm.Signal.make(elm).constant(signalGraph); + } + var initialScene = signalGraph.value; + // Figure out what the render functions should be + var render; + var update; + if (initialScene.ctor === 'Element_elm_builtin') + { + var Element = Elm.Native.Graphics.Element.make(elm); + render = Element.render; + update = Element.updateAndReplace; + } + else + { + var VirtualDom = Elm.Native.VirtualDom.make(elm); + render = VirtualDom.render; + update = VirtualDom.updateAndReplace; + } - // batchedSending and sendCallback implement a small state machine in order - // to schedule only one send(time) call per animation frame. - // - // Invariants: - // 1. In the NO_REQUEST state, there is never a scheduled sendCallback. - // 2. In the PENDING_REQUEST and EXTRA_REQUEST states, there is always exactly - // one scheduled sendCallback. - var NO_REQUEST = 0; - var PENDING_REQUEST = 1; - var EXTRA_REQUEST = 2; - var state = NO_REQUEST; - var messageArray = []; + // Add the initialScene to the DOM + var container = elm.node; + var node = render(initialScene); + while (container.firstChild) + { + container.removeChild(container.firstChild); + } + container.appendChild(node); + var _requestAnimationFrame = + typeof requestAnimationFrame !== 'undefined' + ? requestAnimationFrame + : function(cb) { setTimeout(cb, 1000 / 60); } + ; - function batchedSending(address, tickMessages) - { - // insert ticks into the messageArray - var foundAddress = false; + // domUpdate is called whenever the main Signal changes. + // + // domUpdate and drawCallback implement a small state machine in order + // to schedule only 1 draw per animation frame. This enforces that + // once draw has been called, it will not be called again until the + // next frame. + // + // drawCallback is scheduled whenever + // 1. The state transitions from PENDING_REQUEST to EXTRA_REQUEST, or + // 2. The state transitions from NO_REQUEST to PENDING_REQUEST + // + // Invariants: + // 1. In the NO_REQUEST state, there is never a scheduled drawCallback. + // 2. In the PENDING_REQUEST and EXTRA_REQUEST states, there is always exactly 1 + // scheduled drawCallback. + var NO_REQUEST = 0; + var PENDING_REQUEST = 1; + var EXTRA_REQUEST = 2; + var state = NO_REQUEST; + var savedScene = initialScene; + var scheduledScene = initialScene; - for (var i = messageArray.length; i--; ) - { - if (messageArray[i].address === address) + function domUpdate(newScene) { - foundAddress = true; - messageArray[i].tickMessages = A3(List.foldl, List.cons, messageArray[i].tickMessages, tickMessages); - break; + scheduledScene = newScene; + + switch (state) + { + case NO_REQUEST: + _requestAnimationFrame(drawCallback); + state = PENDING_REQUEST; + return; + case PENDING_REQUEST: + state = PENDING_REQUEST; + return; + case EXTRA_REQUEST: + state = PENDING_REQUEST; + return; + } } - } - if (!foundAddress) - { - messageArray.push({ address: address, tickMessages: tickMessages }); - } + function drawCallback() + { + switch (state) + { + case NO_REQUEST: + // This state should not be possible. How can there be no + // request, yet somehow we are actively fulfilling a + // request? + throw new Error( + 'Unexpected draw callback.\n' + + 'Please report this to .' + ); - // do the appropriate state transition - switch (state) - { - case NO_REQUEST: - _requestAnimationFrame(sendCallback); - state = PENDING_REQUEST; - break; - case PENDING_REQUEST: - state = PENDING_REQUEST; - break; - case EXTRA_REQUEST: - state = PENDING_REQUEST; - break; - } - } + case PENDING_REQUEST: + // At this point, we do not *know* that another frame is + // needed, but we make an extra request to rAF just in + // case. It's possible to drop a frame if rAF is called + // too late, so we just do it preemptively. + _requestAnimationFrame(drawCallback); + state = EXTRA_REQUEST; + // There's also stuff we definitely need to draw. + draw(); + return; - function sendCallback(time) - { - switch (state) - { - case NO_REQUEST: - // This state should not be possible. How can there be no - // request, yet somehow we are actively fulfilling a - // request? - throw new Error( - 'Unexpected send callback.\n' + - 'Please report this to .' - ); + case EXTRA_REQUEST: + // Turns out the extra request was not needed, so we will + // stop calling rAF. No reason to call it all the time if + // no one needs it. + state = NO_REQUEST; + return; + } + } - case PENDING_REQUEST: - // At this point, we do not *know* that another frame is - // needed, but we make an extra request to rAF just in - // case. It's possible to drop a frame if rAF is called - // too late, so we just do it preemptively. - _requestAnimationFrame(sendCallback); - state = EXTRA_REQUEST; + function draw() + { + update(elm.node.firstChild, savedScene, scheduledScene); + if (elm.Native.Window) + { + elm.Native.Window.values.resizeIfNeeded(); + } + savedScene = scheduledScene; + } - // There's also stuff we definitely need to send. - send(time); - return; + var renderer = Elm.Native.Signal.make(elm).output('main', domUpdate, signalGraph); - case EXTRA_REQUEST: - // Turns out the extra request was not needed, so we will - // stop calling rAF. No reason to call it all the time if - // no one needs it. - state = NO_REQUEST; - return; + // must check for resize after 'renderer' is created so + // that changes show up. + if (elm.Native.Window) + { + elm.Native.Window.values.resizeIfNeeded(); + } + + return renderer; } - } + //// HOT SWAPPING //// - function send(time) - { - for (var i = messageArray.length; i--; ) + // Returns boolean indicating if the swap was successful. + // Requires that the two signal graphs have exactly the same + // structure. + function hotSwap(from, to) { - var messages = A3( - List.foldl, - F2( function(toAction, list) { return List.Cons(toAction(time), list); } ), - List.Nil, - messageArray[i].tickMessages - ); - Task.perform( A2(Signal.send, messageArray[i].address, messages) ); + function similar(nodeOld, nodeNew) + { + if (nodeOld.id !== nodeNew.id) + { + return false; + } + if (nodeOld.isOutput) + { + return nodeNew.isOutput; + } + return nodeOld.kids.length === nodeNew.kids.length; + } + function swap(nodeOld, nodeNew) + { + nodeNew.value = nodeOld.value; + return true; + } + var canSwap = depthFirstTraversals(similar, from.inputs, to.inputs); + if (canSwap) + { + depthFirstTraversals(swap, from.inputs, to.inputs); + } + from.node.parentNode.replaceChild(to.node, from.node); + + return canSwap; } - messageArray = []; - } + // Returns false if the node operation f ever fails. + function depthFirstTraversals(f, queueOld, queueNew) + { + if (queueOld.length !== queueNew.length) + { + return false; + } + queueOld = queueOld.slice(0); + queueNew = queueNew.slice(0); + + var seen = []; + while (queueOld.length > 0 && queueNew.length > 0) + { + var nodeOld = queueOld.pop(); + var nodeNew = queueNew.pop(); + if (seen.indexOf(nodeOld.id) < 0) + { + if (!f(nodeOld, nodeNew)) + { + return false; + } + queueOld = queueOld.concat(nodeOld.kids || []); + queueNew = queueNew.concat(nodeNew.kids || []); + seen.push(nodeOld.id); + } + } + return true; + } + }()); - function requestTickSending(address, tickMessages) + function F2(fun) { - return Task.asyncFunction(function(callback) { - batchedSending(address, tickMessages); - callback(Task.succeed(Utils.Tuple0)); - }); + function wrapper(a) { return function(b) { return fun(a,b); }; } + wrapper.arity = 2; + wrapper.func = fun; + return wrapper; } - - return localRuntime.Native.Effects.values = { - requestTickSending: F2(requestTickSending) - }; - -}; - - -// setup -Elm.Native = Elm.Native || {}; -Elm.Native.Graphics = Elm.Native.Graphics || {}; -Elm.Native.Graphics.Collage = Elm.Native.Graphics.Collage || {}; - -// definition -Elm.Native.Graphics.Collage.make = function(localRuntime) { - 'use strict'; - - // attempt to short-circuit - localRuntime.Native = localRuntime.Native || {}; - localRuntime.Native.Graphics = localRuntime.Native.Graphics || {}; - localRuntime.Native.Graphics.Collage = localRuntime.Native.Graphics.Collage || {}; - if ('values' in localRuntime.Native.Graphics.Collage) + function F3(fun) { - return localRuntime.Native.Graphics.Collage.values; + function wrapper(a) { + return function(b) { return function(c) { return fun(a, b, c); }; }; + } + wrapper.arity = 3; + wrapper.func = fun; + return wrapper; } - // okay, we cannot short-ciruit, so now we define everything - var Color = Elm.Native.Color.make(localRuntime); - var List = Elm.Native.List.make(localRuntime); - var NativeElement = Elm.Native.Graphics.Element.make(localRuntime); - var Transform = Elm.Transform2D.make(localRuntime); - var Utils = Elm.Native.Utils.make(localRuntime); - - function setStrokeStyle(ctx, style) + function F4(fun) { - ctx.lineWidth = style.width; - - var cap = style.cap.ctor; - ctx.lineCap = cap === 'Flat' - ? 'butt' - : cap === 'Round' - ? 'round' - : 'square'; - - var join = style.join.ctor; - ctx.lineJoin = join === 'Smooth' - ? 'round' - : join === 'Sharp' - ? 'miter' - : 'bevel'; - - ctx.miterLimit = style.join._0 || 10; - ctx.strokeStyle = Color.toCss(style.color); + function wrapper(a) { return function(b) { return function(c) { + return function(d) { return fun(a, b, c, d); }; }; }; + } + wrapper.arity = 4; + wrapper.func = fun; + return wrapper; } - function setFillStyle(ctx, style) + function F5(fun) { - var sty = style.ctor; - ctx.fillStyle = sty === 'Solid' - ? Color.toCss(style._0) - : sty === 'Texture' - ? texture(redo, ctx, style._0) - : gradient(ctx, style._0); + function wrapper(a) { return function(b) { return function(c) { + return function(d) { return function(e) { return fun(a, b, c, d, e); }; }; }; }; + } + wrapper.arity = 5; + wrapper.func = fun; + return wrapper; } - function trace(ctx, path) + function F6(fun) { - var points = List.toArray(path); - var i = points.length - 1; - if (i <= 0) - { - return; - } - ctx.moveTo(points[i]._0, points[i]._1); - while (i--) - { - ctx.lineTo(points[i]._0, points[i]._1); - } - if (path.closed) - { - i = points.length - 1; - ctx.lineTo(points[i]._0, points[i]._1); + function wrapper(a) { return function(b) { return function(c) { + return function(d) { return function(e) { return function(f) { + return fun(a, b, c, d, e, f); }; }; }; }; }; } + wrapper.arity = 6; + wrapper.func = fun; + return wrapper; } - function line(ctx,style,path) + function F7(fun) { - (style.dashing.ctor === '[]') - ? trace(ctx, path) - : customLineHelp(ctx, style, path); - ctx.scale(1,-1); - ctx.stroke(); + function wrapper(a) { return function(b) { return function(c) { + return function(d) { return function(e) { return function(f) { + return function(g) { return fun(a, b, c, d, e, f, g); }; }; }; }; }; }; + } + wrapper.arity = 7; + wrapper.func = fun; + return wrapper; } - function customLineHelp(ctx, style, path) + function F8(fun) { - var points = List.toArray(path); - if (path.closed) - { - points.push(points[0]); - } - var pattern = List.toArray(style.dashing); - var i = points.length - 1; - if (i <= 0) - { - return; + function wrapper(a) { return function(b) { return function(c) { + return function(d) { return function(e) { return function(f) { + return function(g) { return function(h) { + return fun(a, b, c, d, e, f, g, h); }; }; }; }; }; }; }; } - var x0 = points[i]._0, y0 = points[i]._1; - var x1=0, y1=0, dx=0, dy=0, remaining=0, nx=0, ny=0; - var pindex = 0, plen = pattern.length; - var draw = true, segmentLength = pattern[0]; - ctx.moveTo(x0,y0); - while (i--) - { - x1 = points[i]._0; - y1 = points[i]._1; - dx = x1 - x0; - dy = y1 - y0; - remaining = Math.sqrt(dx * dx + dy * dy); - while (segmentLength <= remaining) - { - x0 += dx * segmentLength / remaining; - y0 += dy * segmentLength / remaining; - ctx[draw ? 'lineTo' : 'moveTo'](x0, y0); - // update starting position - dx = x1 - x0; - dy = y1 - y0; - remaining = Math.sqrt(dx * dx + dy * dy); - // update pattern - draw = !draw; - pindex = (pindex + 1) % plen; - segmentLength = pattern[pindex]; - } - if (remaining > 0) - { - ctx[draw ? 'lineTo' : 'moveTo'](x1, y1); - segmentLength -= remaining; - } - x0 = x1; - y0 = y1; + wrapper.arity = 8; + wrapper.func = fun; + return wrapper; + } + + function F9(fun) + { + function wrapper(a) { return function(b) { return function(c) { + return function(d) { return function(e) { return function(f) { + return function(g) { return function(h) { return function(i) { + return fun(a, b, c, d, e, f, g, h, i); }; }; }; }; }; }; }; }; } + wrapper.arity = 9; + wrapper.func = fun; + return wrapper; } - function drawLine(ctx, style, path) + function A2(fun, a, b) { - setStrokeStyle(ctx, style); - return line(ctx, style, path); + return fun.arity === 2 + ? fun.func(a, b) + : fun(a)(b); } - - function texture(redo, ctx, src) + function A3(fun, a, b, c) { - var img = new Image(); - img.src = src; - img.onload = redo; - return ctx.createPattern(img, 'repeat'); + return fun.arity === 3 + ? fun.func(a, b, c) + : fun(a)(b)(c); } - - function gradient(ctx, grad) + function A4(fun, a, b, c, d) { - var g; - var stops = []; - if (grad.ctor === 'Linear') - { - var p0 = grad._0, p1 = grad._1; - g = ctx.createLinearGradient(p0._0, -p0._1, p1._0, -p1._1); - stops = List.toArray(grad._2); - } - else - { - var p0 = grad._0, p2 = grad._2; - g = ctx.createRadialGradient(p0._0, -p0._1, grad._1, p2._0, -p2._1, grad._3); - stops = List.toArray(grad._4); - } - var len = stops.length; - for (var i = 0; i < len; ++i) - { - var stop = stops[i]; - g.addColorStop(stop._0, Color.toCss(stop._1)); - } - return g; + return fun.arity === 4 + ? fun.func(a, b, c, d) + : fun(a)(b)(c)(d); } - - function drawShape(redo, ctx, style, path) + function A5(fun, a, b, c, d, e) { - trace(ctx, path); - setFillStyle(ctx, style); - ctx.scale(1,-1); - ctx.fill(); + return fun.arity === 5 + ? fun.func(a, b, c, d, e) + : fun(a)(b)(c)(d)(e); } - - - // TEXT RENDERING - - function fillText(redo, ctx, text) + function A6(fun, a, b, c, d, e, f) { - drawText(ctx, text, ctx.fillText); + return fun.arity === 6 + ? fun.func(a, b, c, d, e, f) + : fun(a)(b)(c)(d)(e)(f); } - - function strokeText(redo, ctx, style, text) + function A7(fun, a, b, c, d, e, f, g) { - setStrokeStyle(ctx, style); - // Use native canvas API for dashes only for text for now - // Degrades to non-dashed on IE 9 + 10 - if (style.dashing.ctor !== '[]' && ctx.setLineDash) - { - var pattern = List.toArray(style.dashing); - ctx.setLineDash(pattern); - } - drawText(ctx, text, ctx.strokeText); + return fun.arity === 7 + ? fun.func(a, b, c, d, e, f, g) + : fun(a)(b)(c)(d)(e)(f)(g); + } + function A8(fun, a, b, c, d, e, f, g, h) + { + return fun.arity === 8 + ? fun.func(a, b, c, d, e, f, g, h) + : fun(a)(b)(c)(d)(e)(f)(g)(h); + } + function A9(fun, a, b, c, d, e, f, g, h, i) + { + return fun.arity === 9 + ? fun.func(a, b, c, d, e, f, g, h, i) + : fun(a)(b)(c)(d)(e)(f)(g)(h)(i); } +} - function drawText(ctx, text, canvasDrawFn) +Elm.Native = Elm.Native || {}; +Elm.Native.Utils = {}; +Elm.Native.Utils.make = function(localRuntime) { + localRuntime.Native = localRuntime.Native || {}; + localRuntime.Native.Utils = localRuntime.Native.Utils || {}; + if (localRuntime.Native.Utils.values) { - var textChunks = chunkText(defaultContext, text); + return localRuntime.Native.Utils.values; + } - var totalWidth = 0; - var maxHeight = 0; - var numChunks = textChunks.length; - ctx.scale(1,-1); + // COMPARISONS - for (var i = numChunks; i--; ) + function eq(l, r) + { + var stack = [{'x': l, 'y': r}]; + while (stack.length > 0) { - var chunk = textChunks[i]; - ctx.font = chunk.font; - var metrics = ctx.measureText(chunk.text); - chunk.width = metrics.width; - totalWidth += chunk.width; - if (chunk.height > maxHeight) + var front = stack.pop(); + var x = front.x; + var y = front.y; + if (x === y) { - maxHeight = chunk.height; + continue; + } + if (typeof x === 'object') + { + var c = 0; + for (var i in x) + { + ++c; + if (i in y) + { + if (i !== 'ctor') + { + stack.push({ 'x': x[i], 'y': y[i] }); + } + } + else + { + return false; + } + } + if ('ctor' in x) + { + stack.push({'x': x.ctor, 'y': y.ctor}); + } + if (c !== Object.keys(y).length) + { + return false; + } + } + else if (typeof x === 'function') + { + throw new Error('Equality error: general function equality is ' + + 'undecidable, and therefore, unsupported'); + } + else + { + return false; } } - - var x = -totalWidth / 2.0; - for (var i = 0; i < numChunks; ++i) - { - var chunk = textChunks[i]; - ctx.font = chunk.font; - ctx.fillStyle = chunk.color; - canvasDrawFn.call(ctx, chunk.text, x, maxHeight / 2); - x += chunk.width; - } + return true; } - function toFont(props) + // code in Generate/JavaScript.hs depends on the particular + // integer values assigned to LT, EQ, and GT + var LT = -1, EQ = 0, GT = 1, ord = ['LT', 'EQ', 'GT']; + + function compare(x, y) { - return [ - props['font-style'], - props['font-variant'], - props['font-weight'], - props['font-size'], - props['font-family'] - ].join(' '); + return { + ctor: ord[cmp(x, y) + 1] + }; } - - // Convert the object returned by the text module - // into something we can use for styling canvas text - function chunkText(context, text) - { - var tag = text.ctor; - if (tag === 'Text:Append') + function cmp(x, y) { + var ord; + if (typeof x !== 'object') { - var leftChunks = chunkText(context, text._0); - var rightChunks = chunkText(context, text._1); - return leftChunks.concat(rightChunks); + return x === y ? EQ : x < y ? LT : GT; } - if (tag === 'Text:Text') + else if (x.isChar) { - return [{ - text: text._0, - color: context.color, - height: context['font-size'].slice(0,-2) | 0, - font: toFont(context) - }]; + var a = x.toString(); + var b = y.toString(); + return a === b + ? EQ + : a < b + ? LT + : GT; } - if (tag === 'Text:Meta') + else if (x.ctor === '::' || x.ctor === '[]') { - var newContext = freshContext(text._0, context); - return chunkText(newContext, text._1); + while (true) + { + if (x.ctor === '[]' && y.ctor === '[]') + { + return EQ; + } + if (x.ctor !== y.ctor) + { + return x.ctor === '[]' ? LT : GT; + } + ord = cmp(x._0, y._0); + if (ord !== EQ) + { + return ord; + } + x = x._1; + y = y._1; + } + } + else if (x.ctor.slice(0, 6) === '_Tuple') + { + var n = x.ctor.slice(6) - 0; + var err = 'cannot compare tuples with more than 6 elements.'; + if (n === 0) return EQ; + if (n >= 1) { ord = cmp(x._0, y._0); if (ord !== EQ) return ord; + if (n >= 2) { ord = cmp(x._1, y._1); if (ord !== EQ) return ord; + if (n >= 3) { ord = cmp(x._2, y._2); if (ord !== EQ) return ord; + if (n >= 4) { ord = cmp(x._3, y._3); if (ord !== EQ) return ord; + if (n >= 5) { ord = cmp(x._4, y._4); if (ord !== EQ) return ord; + if (n >= 6) { ord = cmp(x._5, y._5); if (ord !== EQ) return ord; + if (n >= 7) throw new Error('Comparison error: ' + err); } } } } } } + return EQ; + } + else + { + throw new Error('Comparison error: comparison is only defined on ints, ' + + 'floats, times, chars, strings, lists of comparable values, ' + + 'and tuples of comparable values.'); } } - function freshContext(props, ctx) - { - return { - 'font-style': props['font-style'] || ctx['font-style'], - 'font-variant': props['font-variant'] || ctx['font-variant'], - 'font-weight': props['font-weight'] || ctx['font-weight'], - 'font-size': props['font-size'] || ctx['font-size'], - 'font-family': props['font-family'] || ctx['font-family'], - 'color': props['color'] || ctx['color'] - }; - } - var defaultContext = { - 'font-style': 'normal', - 'font-variant': 'normal', - 'font-weight': 'normal', - 'font-size': '12px', - 'font-family': 'sans-serif', - 'color': 'black' + // TUPLES + + var Tuple0 = { + ctor: '_Tuple0' }; + function Tuple2(x, y) + { + return { + ctor: '_Tuple2', + _0: x, + _1: y + }; + } - // IMAGES - function drawImage(redo, ctx, form) + // LITERALS + + function chr(c) { - var img = new Image(); - img.onload = redo; - img.src = form._3; - var w = form._0, - h = form._1, - pos = form._2, - srcX = pos._0, - srcY = pos._1, - srcW = w, - srcH = h, - destX = -w/2, - destY = -h/2, - destW = w, - destH = h; + var x = new String(c); + x.isChar = true; + return x; + } - ctx.scale(1,-1); - ctx.drawImage(img, srcX, srcY, srcW, srcH, destX, destY, destW, destH); + function txt(str) + { + var t = new String(str); + t.text = true; + return t; } - function renderForm(redo, ctx, form) + + // GUID + + var count = 0; + function guid(_) { - ctx.save(); + return count++; + } - var x = form.x, - y = form.y, - theta = form.theta, - scale = form.scale; - if (x !== 0 || y !== 0) - { - ctx.translate(x, y); - } - if (theta !== 0) + // RECORDS + + function update(oldRecord, updatedFields) + { + var newRecord = {}; + for (var key in oldRecord) { - ctx.rotate(theta); + var value = (key in updatedFields) ? updatedFields[key] : oldRecord[key]; + newRecord[key] = value; } - if (scale !== 1) + return newRecord; + } + + + // MOUSE COORDINATES + + function getXY(e) + { + var posx = 0; + var posy = 0; + if (e.pageX || e.pageY) { - ctx.scale(scale,scale); + posx = e.pageX; + posy = e.pageY; } - if (form.alpha !== 1) + else if (e.clientX || e.clientY) { - ctx.globalAlpha = ctx.globalAlpha * form.alpha; + posx = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft; + posy = e.clientY + document.body.scrollTop + document.documentElement.scrollTop; } - ctx.beginPath(); - var f = form.form; - switch (f.ctor) + if (localRuntime.isEmbed()) { - case 'FPath': - drawLine(ctx, f._0, f._1); - break; - - case 'FImage': - drawImage(redo, ctx, f); - break; - - case 'FShape': - if (f._0.ctor === 'Line') - { - f._1.closed = true; - drawLine(ctx, f._0._0, f._1); - } - else - { - drawShape(redo, ctx, f._0._0, f._1); - } - break; - - case 'FText': - fillText(redo, ctx, f._0); - break; - - case 'FOutlinedText': - strokeText(redo, ctx, f._0, f._1); - break; + var rect = localRuntime.node.getBoundingClientRect(); + var relx = rect.left + document.body.scrollLeft + document.documentElement.scrollLeft; + var rely = rect.top + document.body.scrollTop + document.documentElement.scrollTop; + // TODO: figure out if there is a way to avoid rounding here + posx = posx - Math.round(relx) - localRuntime.node.clientLeft; + posy = posy - Math.round(rely) - localRuntime.node.clientTop; } - ctx.restore(); + return Tuple2(posx, posy); } - function formToMatrix(form) - { - var scale = form.scale; - var matrix = A6( Transform.matrix, scale, 0, 0, scale, form.x, form.y ); - var theta = form.theta - if (theta !== 0) - { - matrix = A2( Transform.multiply, matrix, Transform.rotation(theta) ); - } + //// LIST STUFF //// - return matrix; - } + var Nil = { ctor: '[]' }; - function str(n) + function Cons(hd, tl) { - if (n < 0.00001 && n > -0.00001) - { - return 0; - } - return n; + return { + ctor: '::', + _0: hd, + _1: tl + }; } - function makeTransform(w, h, form, matrices) + function list(arr) { - var props = form.form._0.props; - var m = A6( Transform.matrix, 1, 0, 0, -1, - (w - props.width ) / 2, - (h - props.height) / 2 ); - var len = matrices.length; - for (var i = 0; i < len; ++i) + var out = Nil; + for (var i = arr.length; i--; ) { - m = A2( Transform.multiply, m, matrices[i] ); + out = Cons(arr[i], out); } - m = A2( Transform.multiply, m, formToMatrix(form) ); - - return 'matrix(' + - str( m[0]) + ', ' + str( m[3]) + ', ' + - str(-m[1]) + ', ' + str(-m[4]) + ', ' + - str( m[2]) + ', ' + str( m[5]) + ')'; + return out; } - function stepperHelp(list) + function range(lo, hi) { - var arr = List.toArray(list); - var i = 0; - function peekNext() - { - return i < arr.length ? arr[i].form.ctor : ''; - } - // assumes that there is a next element - function next() + var list = Nil; + if (lo <= hi) { - var out = arr[i]; - ++i; - return out; + do + { + list = Cons(hi, list); + } + while (hi-- > lo); } - return { - peekNext: peekNext, - next: next - }; + return list; } - function formStepper(forms) + function append(xs, ys) { - var ps = [stepperHelp(forms)]; - var matrices = []; - var alphas = []; - function peekNext() + // append Strings + if (typeof xs === 'string') { - var len = ps.length; - var formType = ''; - for (var i = 0; i < len; ++i ) - { - if (formType = ps[i].peekNext()) return formType; - } - return ''; + return xs + ys; } - // assumes that there is a next element - function next(ctx) - { - while (!ps[0].peekNext()) - { - ps.shift(); - matrices.pop(); - alphas.shift(); - if (ctx) - { - ctx.restore(); - } - } - var out = ps[0].next(); - var f = out.form; - if (f.ctor === 'FGroup') - { - ps.unshift(stepperHelp(f._1)); - var m = A2(Transform.multiply, f._0, formToMatrix(out)); - ctx.save(); - ctx.transform(m[0], m[3], m[1], m[4], m[2], m[5]); - matrices.push(m); - var alpha = (alphas[0] || 1) * out.alpha; - alphas.unshift(alpha); - ctx.globalAlpha = alpha; - } - return out; + // append Text + if (xs.ctor.slice(0, 5) === 'Text:') + { + return { + ctor: 'Text:Append', + _0: xs, + _1: ys + }; } - function transforms() + + + // append Lists + if (xs.ctor === '[]') { - return matrices; + return ys; } - function alpha() + var root = Cons(xs._0, Nil); + var curr = root; + xs = xs._1; + while (xs.ctor !== '[]') { - return alphas[0] || 1; + curr._1 = Cons(xs._0, Nil); + xs = xs._1; + curr = curr._1; } - return { - peekNext: peekNext, - next: next, - transforms: transforms, - alpha: alpha + curr._1 = ys; + return root; + } + + + // CRASHES + + function crash(moduleName, region) + { + return function(message) { + throw new Error( + 'Ran into a `Debug.crash` in module `' + moduleName + '` ' + regionToString(region) + '\n' + + 'The message provided by the code author is:\n\n ' + + message + ); + }; + } + + function crashCase(moduleName, region, value) + { + return function(message) { + throw new Error( + 'Ran into a `Debug.crash` in module `' + moduleName + '`\n\n' + + 'This was caused by the `case` expression ' + regionToString(region) + '.\n' + + 'One of the branches ended with a crash and the following value got through:\n\n ' + toString(value) + '\n\n' + + 'The message provided by the code author is:\n\n ' + + message + ); }; } - function makeCanvas(w,h) + function regionToString(region) + { + if (region.start.line == region.end.line) + { + return 'on line ' + region.start.line; + } + return 'between lines ' + region.start.line + ' and ' + region.end.line; + } + + + // BAD PORTS + + function badPort(expected, received) { - var canvas = NativeElement.createNode('canvas'); - canvas.style.width = w + 'px'; - canvas.style.height = h + 'px'; - canvas.style.display = "block"; - canvas.style.position = "absolute"; - var ratio = window.devicePixelRatio || 1; - canvas.width = w * ratio; - canvas.height = h * ratio; - return canvas; + throw new Error( + 'Runtime error when sending values through a port.\n\n' + + 'Expecting ' + expected + ' but was given ' + formatValue(received) + ); } - function render(model) + function formatValue(value) { - var div = NativeElement.createNode('div'); - div.style.overflow = 'hidden'; - div.style.position = 'relative'; - update(div, model, model); - return div; + // Explicity format undefined values as "undefined" + // because JSON.stringify(undefined) unhelpfully returns "" + return (value === undefined) ? "undefined" : JSON.stringify(value); } - function nodeStepper(w,h,div) - { - var kids = div.childNodes; - var i = 0; - var ratio = window.devicePixelRatio || 1; - function transform(transforms, ctx) + // TO STRING + + var _Array; + var Dict; + var List; + + var toString = function(v) + { + var type = typeof v; + if (type === 'function') { - ctx.translate( w / 2 * ratio, h / 2 * ratio ); - ctx.scale( ratio, -ratio ); - var len = transforms.length; - for (var i = 0; i < len; ++i) - { - var m = transforms[i]; - ctx.save(); - ctx.transform(m[0], m[3], m[1], m[4], m[2], m[5]); - } - return ctx; + var name = v.func ? v.func.name : v.name; + return ''; } - function nextContext(transforms) + else if (type === 'boolean') { - while (i < kids.length) + return v ? 'True' : 'False'; + } + else if (type === 'number') + { + return v + ''; + } + else if ((v instanceof String) && v.isChar) + { + return '\'' + addSlashes(v, true) + '\''; + } + else if (type === 'string') + { + return '"' + addSlashes(v, false) + '"'; + } + else if (type === 'object' && 'ctor' in v) + { + if (v.ctor.substring(0, 6) === '_Tuple') { - var node = kids[i]; - if (node.getContext) + var output = []; + for (var k in v) { - node.width = w * ratio; - node.height = h * ratio; - node.style.width = w + 'px'; - node.style.height = h + 'px'; - ++i; - return transform(transforms, node.getContext('2d')); + if (k === 'ctor') continue; + output.push(toString(v[k])); } - div.removeChild(node); + return '(' + output.join(',') + ')'; } - var canvas = makeCanvas(w,h); - div.appendChild(canvas); - // we have added a new node, so we must step our position - ++i; - return transform(transforms, canvas.getContext('2d')); - } - function addElement(matrices, alpha, form) - { - var kid = kids[i]; - var elem = form.form._0; - - var node = (!kid || kid.getContext) - ? NativeElement.render(elem) - : NativeElement.update(kid, kid.oldElement, elem); - - node.style.position = 'absolute'; - node.style.opacity = alpha * form.alpha * elem.props.opacity; - NativeElement.addTransform(node.style, makeTransform(w, h, form, matrices)); - node.oldElement = elem; - ++i; - if (!kid) + else if (v.ctor === '_Array') { - div.appendChild(node); + if (!_Array) + { + _Array = Elm.Array.make(localRuntime); + } + var list = _Array.toList(v); + return 'Array.fromList ' + toString(list); + } + else if (v.ctor === '::') + { + var output = '[' + toString(v._0); + v = v._1; + while (v.ctor === '::') + { + output += ',' + toString(v._0); + v = v._1; + } + return output + ']'; + } + else if (v.ctor === '[]') + { + return '[]'; + } + else if (v.ctor === 'RBNode_elm_builtin' || v.ctor === 'RBEmpty_elm_builtin' || v.ctor === 'Set_elm_builtin') + { + if (!Dict) + { + Dict = Elm.Dict.make(localRuntime); + } + var list; + var name; + if (v.ctor === 'Set_elm_builtin') + { + if (!List) + { + List = Elm.List.make(localRuntime); + } + name = 'Set'; + list = A2(List.map, function(x) {return x._0; }, Dict.toList(v._0)); + } + else + { + name = 'Dict'; + list = Dict.toList(v); + } + return name + '.fromList ' + toString(list); + } + else if (v.ctor.slice(0, 5) === 'Text:') + { + return ''; + } + else if (v.ctor === 'Element_elm_builtin') + { + return '' + } + else if (v.ctor === 'Form_elm_builtin') + { + return '
' } else { - div.insertBefore(node, kid); + var output = ''; + for (var i in v) + { + if (i === 'ctor') continue; + var str = toString(v[i]); + var parenless = str[0] === '{' || str[0] === '<' || str.indexOf(' ') < 0; + output += ' ' + (parenless ? str : '(' + str + ')'); + } + return v.ctor + output; } } - function clearRest() + else if (type === 'object' && 'notify' in v && 'id' in v) { - while (i < kids.length) - { - div.removeChild(kids[i]); - } + return ''; } - return { - nextContext: nextContext, - addElement: addElement, - clearRest: clearRest - }; - } - - - function update(div, _, model) - { - var w = model.w; - var h = model.h; - - var forms = formStepper(model.forms); - var nodes = nodeStepper(w,h,div); - var ctx = null; - var formType = ''; - - while (formType = forms.peekNext()) + else if (type === 'object') { - // make sure we have context if we need it - if (ctx === null && formType !== 'FElement') - { - ctx = nodes.nextContext(forms.transforms()); - ctx.globalAlpha = forms.alpha(); - } - - var form = forms.next(ctx); - // if it is FGroup, all updates are made within formStepper when next is called. - if (formType === 'FElement') + var output = []; + for (var k in v) { - // update or insert an element, get a new context - nodes.addElement(forms.transforms(), forms.alpha(), form); - ctx = null; + output.push(k + ' = ' + toString(v[k])); } - else if (formType !== 'FGroup') + if (output.length === 0) { - renderForm(function() { update(div, model, model); }, ctx, form); + return '{}'; } + return '{ ' + output.join(', ') + ' }'; } - nodes.clearRest(); - return div; - } - + return ''; + }; - function collage(w,h,forms) + function addSlashes(str, isChar) { - return A3(NativeElement.newElement, w, h, { - ctor: 'Custom', - type: 'Collage', - render: render, - update: update, - model: {w:w, h:h, forms:forms} - }); + var s = str.replace(/\\/g, '\\\\') + .replace(/\n/g, '\\n') + .replace(/\t/g, '\\t') + .replace(/\r/g, '\\r') + .replace(/\v/g, '\\v') + .replace(/\0/g, '\\0'); + if (isChar) + { + return s.replace(/\'/g, '\\\''); + } + else + { + return s.replace(/\"/g, '\\"'); + } } - return localRuntime.Native.Graphics.Collage.values = { - collage: F3(collage) + + return localRuntime.Native.Utils.values = { + eq: eq, + cmp: cmp, + compare: F2(compare), + Tuple0: Tuple0, + Tuple2: Tuple2, + chr: chr, + txt: txt, + update: update, + guid: guid, + getXY: getXY, + + Nil: Nil, + Cons: Cons, + list: list, + range: range, + append: F2(append), + + crash: crash, + crashCase: crashCase, + badPort: badPort, + + toString: toString }; +}; +Elm.Basics = Elm.Basics || {}; +Elm.Basics.make = function (_elm) { + "use strict"; + _elm.Basics = _elm.Basics || {}; + if (_elm.Basics.values) return _elm.Basics.values; + var _U = Elm.Native.Utils.make(_elm),$Native$Basics = Elm.Native.Basics.make(_elm),$Native$Utils = Elm.Native.Utils.make(_elm); + var _op = {}; + var uncurry = F2(function (f,_p0) { var _p1 = _p0;return A2(f,_p1._0,_p1._1);}); + var curry = F3(function (f,a,b) { return f({ctor: "_Tuple2",_0: a,_1: b});}); + var flip = F3(function (f,b,a) { return A2(f,a,b);}); + var snd = function (_p2) { var _p3 = _p2;return _p3._1;}; + var fst = function (_p4) { var _p5 = _p4;return _p5._0;}; + var always = F2(function (a,_p6) { return a;}); + var identity = function (x) { return x;}; + _op["<|"] = F2(function (f,x) { return f(x);}); + _op["|>"] = F2(function (x,f) { return f(x);}); + _op[">>"] = F3(function (f,g,x) { return g(f(x));}); + _op["<<"] = F3(function (g,f,x) { return g(f(x));}); + _op["++"] = $Native$Utils.append; + var toString = $Native$Utils.toString; + var isInfinite = $Native$Basics.isInfinite; + var isNaN = $Native$Basics.isNaN; + var toFloat = $Native$Basics.toFloat; + var ceiling = $Native$Basics.ceiling; + var floor = $Native$Basics.floor; + var truncate = $Native$Basics.truncate; + var round = $Native$Basics.round; + var not = $Native$Basics.not; + var xor = $Native$Basics.xor; + _op["||"] = $Native$Basics.or; + _op["&&"] = $Native$Basics.and; + var max = $Native$Basics.max; + var min = $Native$Basics.min; + var GT = {ctor: "GT"}; + var EQ = {ctor: "EQ"}; + var LT = {ctor: "LT"}; + var compare = $Native$Basics.compare; + _op[">="] = $Native$Basics.ge; + _op["<="] = $Native$Basics.le; + _op[">"] = $Native$Basics.gt; + _op["<"] = $Native$Basics.lt; + _op["/="] = $Native$Basics.neq; + _op["=="] = $Native$Basics.eq; + var e = $Native$Basics.e; + var pi = $Native$Basics.pi; + var clamp = $Native$Basics.clamp; + var logBase = $Native$Basics.logBase; + var abs = $Native$Basics.abs; + var negate = $Native$Basics.negate; + var sqrt = $Native$Basics.sqrt; + var atan2 = $Native$Basics.atan2; + var atan = $Native$Basics.atan; + var asin = $Native$Basics.asin; + var acos = $Native$Basics.acos; + var tan = $Native$Basics.tan; + var sin = $Native$Basics.sin; + var cos = $Native$Basics.cos; + _op["^"] = $Native$Basics.exp; + _op["%"] = $Native$Basics.mod; + var rem = $Native$Basics.rem; + _op["//"] = $Native$Basics.div; + _op["/"] = $Native$Basics.floatDiv; + _op["*"] = $Native$Basics.mul; + _op["-"] = $Native$Basics.sub; + _op["+"] = $Native$Basics.add; + var toPolar = $Native$Basics.toPolar; + var fromPolar = $Native$Basics.fromPolar; + var turns = $Native$Basics.turns; + var degrees = $Native$Basics.degrees; + var radians = function (t) { return t;}; + return _elm.Basics.values = {_op: _op + ,max: max + ,min: min + ,compare: compare + ,not: not + ,xor: xor + ,rem: rem + ,negate: negate + ,abs: abs + ,sqrt: sqrt + ,clamp: clamp + ,logBase: logBase + ,e: e + ,pi: pi + ,cos: cos + ,sin: sin + ,tan: tan + ,acos: acos + ,asin: asin + ,atan: atan + ,atan2: atan2 + ,round: round + ,floor: floor + ,ceiling: ceiling + ,truncate: truncate + ,toFloat: toFloat + ,degrees: degrees + ,radians: radians + ,turns: turns + ,toPolar: toPolar + ,fromPolar: fromPolar + ,isNaN: isNaN + ,isInfinite: isInfinite + ,toString: toString + ,fst: fst + ,snd: snd + ,identity: identity + ,always: always + ,flip: flip + ,curry: curry + ,uncurry: uncurry + ,LT: LT + ,EQ: EQ + ,GT: GT}; }; - - -// setup -Elm.Native = Elm.Native || {}; -Elm.Native.Graphics = Elm.Native.Graphics || {}; -Elm.Native.Graphics.Element = Elm.Native.Graphics.Element || {}; - -// definition -Elm.Native.Graphics.Element.make = function(localRuntime) { - 'use strict'; - - // attempt to short-circuit +Elm.Maybe = Elm.Maybe || {}; +Elm.Maybe.make = function (_elm) { + "use strict"; + _elm.Maybe = _elm.Maybe || {}; + if (_elm.Maybe.values) return _elm.Maybe.values; + var _U = Elm.Native.Utils.make(_elm); + var _op = {}; + var withDefault = F2(function ($default,maybe) { var _p0 = maybe;if (_p0.ctor === "Just") { return _p0._0;} else { return $default;}}); + var Nothing = {ctor: "Nothing"}; + var oneOf = function (maybes) { + oneOf: while (true) { + var _p1 = maybes; + if (_p1.ctor === "[]") { + return Nothing; + } else { + var _p3 = _p1._0; + var _p2 = _p3; + if (_p2.ctor === "Nothing") { + var _v3 = _p1._1; + maybes = _v3; + continue oneOf; + } else { + return _p3; + } + } + } + }; + var andThen = F2(function (maybeValue,callback) { + var _p4 = maybeValue; + if (_p4.ctor === "Just") { + return callback(_p4._0); + } else { + return Nothing; + } + }); + var Just = function (a) { return {ctor: "Just",_0: a};}; + var map = F2(function (f,maybe) { var _p5 = maybe;if (_p5.ctor === "Just") { return Just(f(_p5._0));} else { return Nothing;}}); + var map2 = F3(function (func,ma,mb) { + var _p6 = {ctor: "_Tuple2",_0: ma,_1: mb}; + if (_p6.ctor === "_Tuple2" && _p6._0.ctor === "Just" && _p6._1.ctor === "Just") { + return Just(A2(func,_p6._0._0,_p6._1._0)); + } else { + return Nothing; + } + }); + var map3 = F4(function (func,ma,mb,mc) { + var _p7 = {ctor: "_Tuple3",_0: ma,_1: mb,_2: mc}; + if (_p7.ctor === "_Tuple3" && _p7._0.ctor === "Just" && _p7._1.ctor === "Just" && _p7._2.ctor === "Just") { + return Just(A3(func,_p7._0._0,_p7._1._0,_p7._2._0)); + } else { + return Nothing; + } + }); + var map4 = F5(function (func,ma,mb,mc,md) { + var _p8 = {ctor: "_Tuple4",_0: ma,_1: mb,_2: mc,_3: md}; + if (_p8.ctor === "_Tuple4" && _p8._0.ctor === "Just" && _p8._1.ctor === "Just" && _p8._2.ctor === "Just" && _p8._3.ctor === "Just") { + return Just(A4(func,_p8._0._0,_p8._1._0,_p8._2._0,_p8._3._0)); + } else { + return Nothing; + } + }); + var map5 = F6(function (func,ma,mb,mc,md,me) { + var _p9 = {ctor: "_Tuple5",_0: ma,_1: mb,_2: mc,_3: md,_4: me}; + if (_p9.ctor === "_Tuple5" && _p9._0.ctor === "Just" && _p9._1.ctor === "Just" && _p9._2.ctor === "Just" && _p9._3.ctor === "Just" && _p9._4.ctor === "Just") + { + return Just(A5(func,_p9._0._0,_p9._1._0,_p9._2._0,_p9._3._0,_p9._4._0)); + } else { + return Nothing; + } + }); + return _elm.Maybe.values = {_op: _op + ,andThen: andThen + ,map: map + ,map2: map2 + ,map3: map3 + ,map4: map4 + ,map5: map5 + ,withDefault: withDefault + ,oneOf: oneOf + ,Just: Just + ,Nothing: Nothing}; +}; +Elm.Native.List = {}; +Elm.Native.List.make = function(localRuntime) { localRuntime.Native = localRuntime.Native || {}; - localRuntime.Native.Graphics = localRuntime.Native.Graphics || {}; - localRuntime.Native.Graphics.Element = localRuntime.Native.Graphics.Element || {}; - if ('values' in localRuntime.Native.Graphics.Element) + localRuntime.Native.List = localRuntime.Native.List || {}; + if (localRuntime.Native.List.values) { - return localRuntime.Native.Graphics.Element.values; + return localRuntime.Native.List.values; + } + if ('values' in Elm.Native.List) + { + return localRuntime.Native.List.values = Elm.Native.List.values; } - var Color = Elm.Native.Color.make(localRuntime); - var List = Elm.Native.List.make(localRuntime); - var Maybe = Elm.Maybe.make(localRuntime); - var Text = Elm.Native.Text.make(localRuntime); var Utils = Elm.Native.Utils.make(localRuntime); + var Nil = Utils.Nil; + var Cons = Utils.Cons; - // CREATION + var fromArray = Utils.list; - function createNode(elementType) + function toArray(xs) { - var node = document.createElement(elementType); - node.style.padding = "0"; - node.style.margin = "0"; - return node; + var out = []; + while (xs.ctor !== '[]') + { + out.push(xs._0); + xs = xs._1; + } + return out; } - - function newElement(width, height, elementPrim) + // f defined similarly for both foldl and foldr (NB: different from Haskell) + // ie, foldl : (a -> b -> b) -> b -> [a] -> b + function foldl(f, b, xs) { - return { - _: {}, - element: elementPrim, - props: { - _: {}, - id: Utils.guid(), - width: width, - height: height, - opacity: 1, - color: Maybe.Nothing, - href: "", - tag: "", - hover: Utils.Tuple0, - click: Utils.Tuple0 - } - }; + var acc = b; + while (xs.ctor !== '[]') + { + acc = A2(f, xs._0, acc); + xs = xs._1; + } + return acc; } - - // PROPERTIES - - function setProps(elem, node) + function foldr(f, b, xs) { - var props = elem.props; - - var element = elem.element; - var width = props.width - (element.adjustWidth || 0); - var height = props.height - (element.adjustHeight || 0); - node.style.width = (width |0) + 'px'; - node.style.height = (height|0) + 'px'; - - if (props.opacity !== 1) + var arr = toArray(xs); + var acc = b; + for (var i = arr.length; i--; ) { - node.style.opacity = props.opacity; + acc = A2(f, arr[i], acc); } + return acc; + } - if (props.color.ctor === 'Just') + function map2(f, xs, ys) + { + var arr = []; + while (xs.ctor !== '[]' && ys.ctor !== '[]') { - node.style.backgroundColor = Color.toCss(props.color._0); + arr.push(A2(f, xs._0, ys._0)); + xs = xs._1; + ys = ys._1; } + return fromArray(arr); + } - if (props.tag !== '') + function map3(f, xs, ys, zs) + { + var arr = []; + while (xs.ctor !== '[]' && ys.ctor !== '[]' && zs.ctor !== '[]') { - node.id = props.tag; + arr.push(A3(f, xs._0, ys._0, zs._0)); + xs = xs._1; + ys = ys._1; + zs = zs._1; } + return fromArray(arr); + } - if (props.hover.ctor !== '_Tuple0') + function map4(f, ws, xs, ys, zs) + { + var arr = []; + while ( ws.ctor !== '[]' + && xs.ctor !== '[]' + && ys.ctor !== '[]' + && zs.ctor !== '[]') { - addHover(node, props.hover); + arr.push(A4(f, ws._0, xs._0, ys._0, zs._0)); + ws = ws._1; + xs = xs._1; + ys = ys._1; + zs = zs._1; } + return fromArray(arr); + } - if (props.click.ctor !== '_Tuple0') + function map5(f, vs, ws, xs, ys, zs) + { + var arr = []; + while ( vs.ctor !== '[]' + && ws.ctor !== '[]' + && xs.ctor !== '[]' + && ys.ctor !== '[]' + && zs.ctor !== '[]') { - addClick(node, props.click); + arr.push(A5(f, vs._0, ws._0, xs._0, ys._0, zs._0)); + vs = vs._1; + ws = ws._1; + xs = xs._1; + ys = ys._1; + zs = zs._1; } + return fromArray(arr); + } - if (props.href !== '') + function sortBy(f, xs) + { + return fromArray(toArray(xs).sort(function(a, b) { + return Utils.cmp(f(a), f(b)); + })); + } + + function sortWith(f, xs) + { + return fromArray(toArray(xs).sort(function(a, b) { + var ord = f(a)(b).ctor; + return ord === 'EQ' ? 0 : ord === 'LT' ? -1 : 1; + })); + } + + function take(n, xs) + { + var arr = []; + while (xs.ctor !== '[]' && n > 0) { - var anchor = createNode('a'); - anchor.href = props.href; - anchor.style.display = 'block'; - anchor.style.pointerEvents = 'auto'; - anchor.appendChild(node); - node = anchor; + arr.push(xs._0); + xs = xs._1; + --n; } - - return node; + return fromArray(arr); } - function addClick(e, handler) + + Elm.Native.List.values = { + Nil: Nil, + Cons: Cons, + cons: F2(Cons), + toArray: toArray, + fromArray: fromArray, + + foldl: F3(foldl), + foldr: F3(foldr), + + map2: F3(map2), + map3: F4(map3), + map4: F5(map4), + map5: F6(map5), + sortBy: F2(sortBy), + sortWith: F2(sortWith), + take: F2(take) + }; + return localRuntime.Native.List.values = Elm.Native.List.values; +}; + +Elm.List = Elm.List || {}; +Elm.List.make = function (_elm) { + "use strict"; + _elm.List = _elm.List || {}; + if (_elm.List.values) return _elm.List.values; + var _U = Elm.Native.Utils.make(_elm),$Basics = Elm.Basics.make(_elm),$Maybe = Elm.Maybe.make(_elm),$Native$List = Elm.Native.List.make(_elm); + var _op = {}; + var sortWith = $Native$List.sortWith; + var sortBy = $Native$List.sortBy; + var sort = function (xs) { return A2(sortBy,$Basics.identity,xs);}; + var drop = F2(function (n,list) { + drop: while (true) if (_U.cmp(n,0) < 1) return list; else { + var _p0 = list; + if (_p0.ctor === "[]") { + return list; + } else { + var _v1 = n - 1,_v2 = _p0._1; + n = _v1; + list = _v2; + continue drop; + } + } + }); + var take = $Native$List.take; + var map5 = $Native$List.map5; + var map4 = $Native$List.map4; + var map3 = $Native$List.map3; + var map2 = $Native$List.map2; + var any = F2(function (isOkay,list) { + any: while (true) { + var _p1 = list; + if (_p1.ctor === "[]") { + return false; + } else { + if (isOkay(_p1._0)) return true; else { + var _v4 = isOkay,_v5 = _p1._1; + isOkay = _v4; + list = _v5; + continue any; + } + } + } + }); + var all = F2(function (isOkay,list) { return $Basics.not(A2(any,function (_p2) { return $Basics.not(isOkay(_p2));},list));}); + var foldr = $Native$List.foldr; + var foldl = $Native$List.foldl; + var length = function (xs) { return A3(foldl,F2(function (_p3,i) { return i + 1;}),0,xs);}; + var sum = function (numbers) { return A3(foldl,F2(function (x,y) { return x + y;}),0,numbers);}; + var product = function (numbers) { return A3(foldl,F2(function (x,y) { return x * y;}),1,numbers);}; + var maximum = function (list) { + var _p4 = list; + if (_p4.ctor === "::") { + return $Maybe.Just(A3(foldl,$Basics.max,_p4._0,_p4._1)); + } else { + return $Maybe.Nothing; + } + }; + var minimum = function (list) { + var _p5 = list; + if (_p5.ctor === "::") { + return $Maybe.Just(A3(foldl,$Basics.min,_p5._0,_p5._1)); + } else { + return $Maybe.Nothing; + } + }; + var indexedMap = F2(function (f,xs) { return A3(map2,f,_U.range(0,length(xs) - 1),xs);}); + var member = F2(function (x,xs) { return A2(any,function (a) { return _U.eq(a,x);},xs);}); + var isEmpty = function (xs) { var _p6 = xs;if (_p6.ctor === "[]") { return true;} else { return false;}}; + var tail = function (list) { var _p7 = list;if (_p7.ctor === "::") { return $Maybe.Just(_p7._1);} else { return $Maybe.Nothing;}}; + var head = function (list) { var _p8 = list;if (_p8.ctor === "::") { return $Maybe.Just(_p8._0);} else { return $Maybe.Nothing;}}; + _op["::"] = $Native$List.cons; + var map = F2(function (f,xs) { return A3(foldr,F2(function (x,acc) { return A2(_op["::"],f(x),acc);}),_U.list([]),xs);}); + var filter = F2(function (pred,xs) { + var conditionalCons = F2(function (x,xs$) { return pred(x) ? A2(_op["::"],x,xs$) : xs$;}); + return A3(foldr,conditionalCons,_U.list([]),xs); + }); + var maybeCons = F3(function (f,mx,xs) { var _p9 = f(mx);if (_p9.ctor === "Just") { return A2(_op["::"],_p9._0,xs);} else { return xs;}}); + var filterMap = F2(function (f,xs) { return A3(foldr,maybeCons(f),_U.list([]),xs);}); + var reverse = function (list) { return A3(foldl,F2(function (x,y) { return A2(_op["::"],x,y);}),_U.list([]),list);}; + var scanl = F3(function (f,b,xs) { + var scan1 = F2(function (x,accAcc) { + var _p10 = accAcc; + if (_p10.ctor === "::") { + return A2(_op["::"],A2(f,x,_p10._0),accAcc); + } else { + return _U.list([]); + } + }); + return reverse(A3(foldl,scan1,_U.list([b]),xs)); + }); + var append = F2(function (xs,ys) { + var _p11 = ys; + if (_p11.ctor === "[]") { + return xs; + } else { + return A3(foldr,F2(function (x,y) { return A2(_op["::"],x,y);}),ys,xs); + } + }); + var concat = function (lists) { return A3(foldr,append,_U.list([]),lists);}; + var concatMap = F2(function (f,list) { return concat(A2(map,f,list));}); + var partition = F2(function (pred,list) { + var step = F2(function (x,_p12) { + var _p13 = _p12; + var _p15 = _p13._0; + var _p14 = _p13._1; + return pred(x) ? {ctor: "_Tuple2",_0: A2(_op["::"],x,_p15),_1: _p14} : {ctor: "_Tuple2",_0: _p15,_1: A2(_op["::"],x,_p14)}; + }); + return A3(foldr,step,{ctor: "_Tuple2",_0: _U.list([]),_1: _U.list([])},list); + }); + var unzip = function (pairs) { + var step = F2(function (_p17,_p16) { + var _p18 = _p17; + var _p19 = _p16; + return {ctor: "_Tuple2",_0: A2(_op["::"],_p18._0,_p19._0),_1: A2(_op["::"],_p18._1,_p19._1)}; + }); + return A3(foldr,step,{ctor: "_Tuple2",_0: _U.list([]),_1: _U.list([])},pairs); + }; + var intersperse = F2(function (sep,xs) { + var _p20 = xs; + if (_p20.ctor === "[]") { + return _U.list([]); + } else { + var step = F2(function (x,rest) { return A2(_op["::"],sep,A2(_op["::"],x,rest));}); + var spersed = A3(foldr,step,_U.list([]),_p20._1); + return A2(_op["::"],_p20._0,spersed); + } + }); + var repeatHelp = F3(function (result,n,value) { + repeatHelp: while (true) if (_U.cmp(n,0) < 1) return result; else { + var _v18 = A2(_op["::"],value,result),_v19 = n - 1,_v20 = value; + result = _v18; + n = _v19; + value = _v20; + continue repeatHelp; + } + }); + var repeat = F2(function (n,value) { return A3(repeatHelp,_U.list([]),n,value);}); + return _elm.List.values = {_op: _op + ,isEmpty: isEmpty + ,length: length + ,reverse: reverse + ,member: member + ,head: head + ,tail: tail + ,filter: filter + ,take: take + ,drop: drop + ,repeat: repeat + ,append: append + ,concat: concat + ,intersperse: intersperse + ,partition: partition + ,unzip: unzip + ,map: map + ,map2: map2 + ,map3: map3 + ,map4: map4 + ,map5: map5 + ,filterMap: filterMap + ,concatMap: concatMap + ,indexedMap: indexedMap + ,foldr: foldr + ,foldl: foldl + ,sum: sum + ,product: product + ,maximum: maximum + ,minimum: minimum + ,all: all + ,any: any + ,scanl: scanl + ,sort: sort + ,sortBy: sortBy + ,sortWith: sortWith}; +}; +Elm.Array = Elm.Array || {}; +Elm.Array.make = function (_elm) { + "use strict"; + _elm.Array = _elm.Array || {}; + if (_elm.Array.values) return _elm.Array.values; + var _U = Elm.Native.Utils.make(_elm), + $Basics = Elm.Basics.make(_elm), + $List = Elm.List.make(_elm), + $Maybe = Elm.Maybe.make(_elm), + $Native$Array = Elm.Native.Array.make(_elm); + var _op = {}; + var append = $Native$Array.append; + var length = $Native$Array.length; + var isEmpty = function (array) { return _U.eq(length(array),0);}; + var slice = $Native$Array.slice; + var set = $Native$Array.set; + var get = F2(function (i,array) { + return _U.cmp(0,i) < 1 && _U.cmp(i,$Native$Array.length(array)) < 0 ? $Maybe.Just(A2($Native$Array.get,i,array)) : $Maybe.Nothing; + }); + var push = $Native$Array.push; + var empty = $Native$Array.empty; + var filter = F2(function (isOkay,arr) { + var update = F2(function (x,xs) { return isOkay(x) ? A2($Native$Array.push,x,xs) : xs;}); + return A3($Native$Array.foldl,update,$Native$Array.empty,arr); + }); + var foldr = $Native$Array.foldr; + var foldl = $Native$Array.foldl; + var indexedMap = $Native$Array.indexedMap; + var map = $Native$Array.map; + var toIndexedList = function (array) { + return A3($List.map2, + F2(function (v0,v1) { return {ctor: "_Tuple2",_0: v0,_1: v1};}), + _U.range(0,$Native$Array.length(array) - 1), + $Native$Array.toList(array)); + }; + var toList = $Native$Array.toList; + var fromList = $Native$Array.fromList; + var initialize = $Native$Array.initialize; + var repeat = F2(function (n,e) { return A2(initialize,n,$Basics.always(e));}); + var Array = {ctor: "Array"}; + return _elm.Array.values = {_op: _op + ,empty: empty + ,repeat: repeat + ,initialize: initialize + ,fromList: fromList + ,isEmpty: isEmpty + ,length: length + ,push: push + ,append: append + ,get: get + ,set: set + ,slice: slice + ,toList: toList + ,toIndexedList: toIndexedList + ,map: map + ,indexedMap: indexedMap + ,filter: filter + ,foldl: foldl + ,foldr: foldr}; +}; +Elm.Native.Char = {}; +Elm.Native.Char.make = function(localRuntime) { + localRuntime.Native = localRuntime.Native || {}; + localRuntime.Native.Char = localRuntime.Native.Char || {}; + if (localRuntime.Native.Char.values) { - e.style.pointerEvents = 'auto'; - e.elm_click_handler = handler; - function trigger(ev) - { - e.elm_click_handler(Utils.Tuple0); - ev.stopPropagation(); - } - e.elm_click_trigger = trigger; - e.addEventListener('click', trigger); + return localRuntime.Native.Char.values; } - function removeClick(e, handler) + var Utils = Elm.Native.Utils.make(localRuntime); + + return localRuntime.Native.Char.values = { + fromCode: function(c) { return Utils.chr(String.fromCharCode(c)); }, + toCode: function(c) { return c.charCodeAt(0); }, + toUpper: function(c) { return Utils.chr(c.toUpperCase()); }, + toLower: function(c) { return Utils.chr(c.toLowerCase()); }, + toLocaleUpper: function(c) { return Utils.chr(c.toLocaleUpperCase()); }, + toLocaleLower: function(c) { return Utils.chr(c.toLocaleLowerCase()); } + }; +}; + +Elm.Char = Elm.Char || {}; +Elm.Char.make = function (_elm) { + "use strict"; + _elm.Char = _elm.Char || {}; + if (_elm.Char.values) return _elm.Char.values; + var _U = Elm.Native.Utils.make(_elm),$Basics = Elm.Basics.make(_elm),$Native$Char = Elm.Native.Char.make(_elm); + var _op = {}; + var fromCode = $Native$Char.fromCode; + var toCode = $Native$Char.toCode; + var toLocaleLower = $Native$Char.toLocaleLower; + var toLocaleUpper = $Native$Char.toLocaleUpper; + var toLower = $Native$Char.toLower; + var toUpper = $Native$Char.toUpper; + var isBetween = F3(function (low,high,$char) { var code = toCode($char);return _U.cmp(code,toCode(low)) > -1 && _U.cmp(code,toCode(high)) < 1;}); + var isUpper = A2(isBetween,_U.chr("A"),_U.chr("Z")); + var isLower = A2(isBetween,_U.chr("a"),_U.chr("z")); + var isDigit = A2(isBetween,_U.chr("0"),_U.chr("9")); + var isOctDigit = A2(isBetween,_U.chr("0"),_U.chr("7")); + var isHexDigit = function ($char) { + return isDigit($char) || (A3(isBetween,_U.chr("a"),_U.chr("f"),$char) || A3(isBetween,_U.chr("A"),_U.chr("F"),$char)); + }; + return _elm.Char.values = {_op: _op + ,isUpper: isUpper + ,isLower: isLower + ,isDigit: isDigit + ,isOctDigit: isOctDigit + ,isHexDigit: isHexDigit + ,toUpper: toUpper + ,toLower: toLower + ,toLocaleUpper: toLocaleUpper + ,toLocaleLower: toLocaleLower + ,toCode: toCode + ,fromCode: fromCode}; +}; +Elm.Native.Color = {}; +Elm.Native.Color.make = function(localRuntime) { + localRuntime.Native = localRuntime.Native || {}; + localRuntime.Native.Color = localRuntime.Native.Color || {}; + if (localRuntime.Native.Color.values) { - if (e.elm_click_trigger) - { - e.removeEventListener('click', e.elm_click_trigger); - e.elm_click_trigger = null; - e.elm_click_handler = null; - } + return localRuntime.Native.Color.values; } - function addHover(e, handler) + function toCss(c) { - e.style.pointerEvents = 'auto'; - e.elm_hover_handler = handler; - e.elm_hover_count = 0; - - function over(evt) + var format = ''; + var colors = ''; + if (c.ctor === 'RGBA') { - if (e.elm_hover_count++ > 0) return; - e.elm_hover_handler(true); - evt.stopPropagation(); + format = 'rgb'; + colors = c._0 + ', ' + c._1 + ', ' + c._2; } - function out(evt) + else { - if (e.contains(evt.toElement || evt.relatedTarget)) return; - e.elm_hover_count = 0; - e.elm_hover_handler(false); - evt.stopPropagation(); + format = 'hsl'; + colors = (c._0 * 180 / Math.PI) + ', ' + + (c._1 * 100) + '%, ' + + (c._2 * 100) + '%'; } - e.elm_hover_over = over; - e.elm_hover_out = out; - e.addEventListener('mouseover', over); - e.addEventListener('mouseout', out); - } - - function removeHover(e) - { - e.elm_hover_handler = null; - if (e.elm_hover_over) + if (c._3 === 1) { - e.removeEventListener('mouseover', e.elm_hover_over); - e.elm_hover_over = null; + return format + '(' + colors + ')'; } - if (e.elm_hover_out) + else { - e.removeEventListener('mouseout', e.elm_hover_out); - e.elm_hover_out = null; + return format + 'a(' + colors + ', ' + c._3 + ')'; } } + return localRuntime.Native.Color.values = { + toCss: toCss + }; +}; - // IMAGES +Elm.Color = Elm.Color || {}; +Elm.Color.make = function (_elm) { + "use strict"; + _elm.Color = _elm.Color || {}; + if (_elm.Color.values) return _elm.Color.values; + var _U = Elm.Native.Utils.make(_elm),$Basics = Elm.Basics.make(_elm); + var _op = {}; + var Radial = F5(function (a,b,c,d,e) { return {ctor: "Radial",_0: a,_1: b,_2: c,_3: d,_4: e};}); + var radial = Radial; + var Linear = F3(function (a,b,c) { return {ctor: "Linear",_0: a,_1: b,_2: c};}); + var linear = Linear; + var fmod = F2(function (f,n) { var integer = $Basics.floor(f);return $Basics.toFloat(A2($Basics._op["%"],integer,n)) + f - $Basics.toFloat(integer);}); + var rgbToHsl = F3(function (red,green,blue) { + var b = $Basics.toFloat(blue) / 255; + var g = $Basics.toFloat(green) / 255; + var r = $Basics.toFloat(red) / 255; + var cMax = A2($Basics.max,A2($Basics.max,r,g),b); + var cMin = A2($Basics.min,A2($Basics.min,r,g),b); + var c = cMax - cMin; + var lightness = (cMax + cMin) / 2; + var saturation = _U.eq(lightness,0) ? 0 : c / (1 - $Basics.abs(2 * lightness - 1)); + var hue = $Basics.degrees(60) * (_U.eq(cMax,r) ? A2(fmod,(g - b) / c,6) : _U.eq(cMax,g) ? (b - r) / c + 2 : (r - g) / c + 4); + return {ctor: "_Tuple3",_0: hue,_1: saturation,_2: lightness}; + }); + var hslToRgb = F3(function (hue,saturation,lightness) { + var hue$ = hue / $Basics.degrees(60); + var chroma = (1 - $Basics.abs(2 * lightness - 1)) * saturation; + var x = chroma * (1 - $Basics.abs(A2(fmod,hue$,2) - 1)); + var _p0 = _U.cmp(hue$,0) < 0 ? {ctor: "_Tuple3",_0: 0,_1: 0,_2: 0} : _U.cmp(hue$,1) < 0 ? {ctor: "_Tuple3",_0: chroma,_1: x,_2: 0} : _U.cmp(hue$, + 2) < 0 ? {ctor: "_Tuple3",_0: x,_1: chroma,_2: 0} : _U.cmp(hue$,3) < 0 ? {ctor: "_Tuple3",_0: 0,_1: chroma,_2: x} : _U.cmp(hue$,4) < 0 ? {ctor: "_Tuple3" + ,_0: 0 + ,_1: x + ,_2: chroma} : _U.cmp(hue$, + 5) < 0 ? {ctor: "_Tuple3",_0: x,_1: 0,_2: chroma} : _U.cmp(hue$,6) < 0 ? {ctor: "_Tuple3",_0: chroma,_1: 0,_2: x} : {ctor: "_Tuple3",_0: 0,_1: 0,_2: 0}; + var r = _p0._0; + var g = _p0._1; + var b = _p0._2; + var m = lightness - chroma / 2; + return {ctor: "_Tuple3",_0: r + m,_1: g + m,_2: b + m}; + }); + var toRgb = function (color) { + var _p1 = color; + if (_p1.ctor === "RGBA") { + return {red: _p1._0,green: _p1._1,blue: _p1._2,alpha: _p1._3}; + } else { + var _p2 = A3(hslToRgb,_p1._0,_p1._1,_p1._2); + var r = _p2._0; + var g = _p2._1; + var b = _p2._2; + return {red: $Basics.round(255 * r),green: $Basics.round(255 * g),blue: $Basics.round(255 * b),alpha: _p1._3}; + } + }; + var toHsl = function (color) { + var _p3 = color; + if (_p3.ctor === "HSLA") { + return {hue: _p3._0,saturation: _p3._1,lightness: _p3._2,alpha: _p3._3}; + } else { + var _p4 = A3(rgbToHsl,_p3._0,_p3._1,_p3._2); + var h = _p4._0; + var s = _p4._1; + var l = _p4._2; + return {hue: h,saturation: s,lightness: l,alpha: _p3._3}; + } + }; + var HSLA = F4(function (a,b,c,d) { return {ctor: "HSLA",_0: a,_1: b,_2: c,_3: d};}); + var hsla = F4(function (hue,saturation,lightness,alpha) { + return A4(HSLA,hue - $Basics.turns($Basics.toFloat($Basics.floor(hue / (2 * $Basics.pi)))),saturation,lightness,alpha); + }); + var hsl = F3(function (hue,saturation,lightness) { return A4(hsla,hue,saturation,lightness,1);}); + var complement = function (color) { + var _p5 = color; + if (_p5.ctor === "HSLA") { + return A4(hsla,_p5._0 + $Basics.degrees(180),_p5._1,_p5._2,_p5._3); + } else { + var _p6 = A3(rgbToHsl,_p5._0,_p5._1,_p5._2); + var h = _p6._0; + var s = _p6._1; + var l = _p6._2; + return A4(hsla,h + $Basics.degrees(180),s,l,_p5._3); + } + }; + var grayscale = function (p) { return A4(HSLA,0,0,1 - p,1);}; + var greyscale = function (p) { return A4(HSLA,0,0,1 - p,1);}; + var RGBA = F4(function (a,b,c,d) { return {ctor: "RGBA",_0: a,_1: b,_2: c,_3: d};}); + var rgba = RGBA; + var rgb = F3(function (r,g,b) { return A4(RGBA,r,g,b,1);}); + var lightRed = A4(RGBA,239,41,41,1); + var red = A4(RGBA,204,0,0,1); + var darkRed = A4(RGBA,164,0,0,1); + var lightOrange = A4(RGBA,252,175,62,1); + var orange = A4(RGBA,245,121,0,1); + var darkOrange = A4(RGBA,206,92,0,1); + var lightYellow = A4(RGBA,255,233,79,1); + var yellow = A4(RGBA,237,212,0,1); + var darkYellow = A4(RGBA,196,160,0,1); + var lightGreen = A4(RGBA,138,226,52,1); + var green = A4(RGBA,115,210,22,1); + var darkGreen = A4(RGBA,78,154,6,1); + var lightBlue = A4(RGBA,114,159,207,1); + var blue = A4(RGBA,52,101,164,1); + var darkBlue = A4(RGBA,32,74,135,1); + var lightPurple = A4(RGBA,173,127,168,1); + var purple = A4(RGBA,117,80,123,1); + var darkPurple = A4(RGBA,92,53,102,1); + var lightBrown = A4(RGBA,233,185,110,1); + var brown = A4(RGBA,193,125,17,1); + var darkBrown = A4(RGBA,143,89,2,1); + var black = A4(RGBA,0,0,0,1); + var white = A4(RGBA,255,255,255,1); + var lightGrey = A4(RGBA,238,238,236,1); + var grey = A4(RGBA,211,215,207,1); + var darkGrey = A4(RGBA,186,189,182,1); + var lightGray = A4(RGBA,238,238,236,1); + var gray = A4(RGBA,211,215,207,1); + var darkGray = A4(RGBA,186,189,182,1); + var lightCharcoal = A4(RGBA,136,138,133,1); + var charcoal = A4(RGBA,85,87,83,1); + var darkCharcoal = A4(RGBA,46,52,54,1); + return _elm.Color.values = {_op: _op + ,rgb: rgb + ,rgba: rgba + ,hsl: hsl + ,hsla: hsla + ,greyscale: greyscale + ,grayscale: grayscale + ,complement: complement + ,linear: linear + ,radial: radial + ,toRgb: toRgb + ,toHsl: toHsl + ,red: red + ,orange: orange + ,yellow: yellow + ,green: green + ,blue: blue + ,purple: purple + ,brown: brown + ,lightRed: lightRed + ,lightOrange: lightOrange + ,lightYellow: lightYellow + ,lightGreen: lightGreen + ,lightBlue: lightBlue + ,lightPurple: lightPurple + ,lightBrown: lightBrown + ,darkRed: darkRed + ,darkOrange: darkOrange + ,darkYellow: darkYellow + ,darkGreen: darkGreen + ,darkBlue: darkBlue + ,darkPurple: darkPurple + ,darkBrown: darkBrown + ,white: white + ,lightGrey: lightGrey + ,grey: grey + ,darkGrey: darkGrey + ,lightCharcoal: lightCharcoal + ,charcoal: charcoal + ,darkCharcoal: darkCharcoal + ,black: black + ,lightGray: lightGray + ,gray: gray + ,darkGray: darkGray}; +}; +Elm.Native.Signal = {}; - function image(props, img) +Elm.Native.Signal.make = function(localRuntime) { + localRuntime.Native = localRuntime.Native || {}; + localRuntime.Native.Signal = localRuntime.Native.Signal || {}; + if (localRuntime.Native.Signal.values) { - switch (img._0.ctor) - { - case 'Plain': - return plainImage(img._3); + return localRuntime.Native.Signal.values; + } - case 'Fitted': - return fittedImage(props.width, props.height, img._3); - case 'Cropped': - return croppedImage(img,props.width,props.height,img._3); + var Task = Elm.Native.Task.make(localRuntime); + var Utils = Elm.Native.Utils.make(localRuntime); - case 'Tiled': - return tiledImage(img._3); - } - } - function plainImage(src) + function broadcastToKids(node, timestamp, update) { - var img = createNode('img'); - img.src = src; - img.name = src; - img.style.display = "block"; - return img; + var kids = node.kids; + for (var i = kids.length; i--; ) + { + kids[i].notify(timestamp, update, node.id); + } } - function tiledImage(src) - { - var div = createNode('div'); - div.style.backgroundImage = 'url(' + src + ')'; - return div; - } - function fittedImage(w, h, src) - { - var div = createNode('div'); - div.style.background = 'url(' + src + ') no-repeat center'; - div.style.webkitBackgroundSize = 'cover'; - div.style.MozBackgroundSize = 'cover'; - div.style.OBackgroundSize = 'cover'; - div.style.backgroundSize = 'cover'; - return div; - } + // INPUT - function croppedImage(elem, w, h, src) + function input(name, base) { - var pos = elem._0._0; - var e = createNode('div'); - e.style.overflow = "hidden"; - - var img = createNode('img'); - img.onload = function() { - var sw = w / elem._1, sh = h / elem._2; - img.style.width = ((this.width * sw)|0) + 'px'; - img.style.height = ((this.height * sh)|0) + 'px'; - img.style.marginLeft = ((- pos._0 * sw)|0) + 'px'; - img.style.marginTop = ((- pos._1 * sh)|0) + 'px'; + var node = { + id: Utils.guid(), + name: 'input-' + name, + value: base, + parents: [], + kids: [] }; - img.src = src; - img.name = src; - e.appendChild(img); - return e; - } + node.notify = function(timestamp, targetId, value) { + var update = targetId === node.id; + if (update) + { + node.value = value; + } + broadcastToKids(node, timestamp, update); + return update; + }; - // FLOW + localRuntime.inputs.push(node); - function goOut(node) - { - node.style.position = 'absolute'; - return node; - } - function goDown(node) - { - return node; - } - function goRight(node) - { - node.style.styleFloat = 'left'; - node.style.cssFloat = 'left'; return node; } - var directionTable = { - DUp : goDown, - DDown : goDown, - DLeft : goRight, - DRight : goRight, - DIn : goOut, - DOut : goOut - }; - function needsReversal(dir) + function constant(value) { - return dir == 'DUp' || dir == 'DLeft' || dir == 'DIn'; + return input('constant', value); } - function flow(dir,elist) + + // MAILBOX + + function mailbox(base) { - var array = List.toArray(elist); - var container = createNode('div'); - var goDir = directionTable[dir]; - if (goDir == goOut) - { - container.style.pointerEvents = 'none'; - } - if (needsReversal(dir)) - { - array.reverse(); - } - var len = array.length; - for (var i = 0; i < len; ++i) - { - container.appendChild(goDir(render(array[i]))); + var signal = input('mailbox', base); + + function send(value) { + return Task.asyncFunction(function(callback) { + localRuntime.setTimeout(function() { + localRuntime.notify(signal.id, value); + }, 0); + callback(Task.succeed(Utils.Tuple0)); + }); } - return container; + + return { + signal: signal, + address: { + ctor: 'Address', + _0: send + } + }; } + function sendMessage(message) + { + Task.perform(message._0); + } - // CONTAINER - function toPos(pos) + // OUTPUT + + function output(name, handler, parent) { - return pos.ctor === "Absolute" - ? pos._0 + "px" - : (pos._0 * 100) + "%"; + var node = { + id: Utils.guid(), + name: 'output-' + name, + parents: [parent], + isOutput: true + }; + + node.notify = function(timestamp, parentUpdate, parentID) + { + if (parentUpdate) + { + handler(parent.value); + } + }; + + parent.kids.push(node); + + return node; } - // must clear right, left, top, bottom, and transform - // before calling this function - function setPos(pos,elem,e) - { - var element = elem.element; - var props = elem.props; - var w = props.width + (element.adjustWidth ? element.adjustWidth : 0); - var h = props.height + (element.adjustHeight ? element.adjustHeight : 0); - e.style.position = 'absolute'; - e.style.margin = 'auto'; - var transform = ''; + // MAP - switch (pos.horizontal.ctor) - { - case 'P': - e.style.right = toPos(pos.x); - e.style.removeProperty('left'); - break; + function mapMany(refreshValue, args) + { + var node = { + id: Utils.guid(), + name: 'map' + args.length, + value: refreshValue(), + parents: args, + kids: [] + }; - case 'Z': - transform = 'translateX(' + ((-w/2)|0) + 'px) '; + var numberOfParents = args.length; + var count = 0; + var update = false; - case 'N': - e.style.left = toPos(pos.x); - e.style.removeProperty('right'); - break; - } - switch (pos.vertical.ctor) + node.notify = function(timestamp, parentUpdate, parentID) { - case 'N': - e.style.bottom = toPos(pos.y); - e.style.removeProperty('top'); - break; + ++count; - case 'Z': - transform += 'translateY(' + ((-h/2)|0) + 'px)'; + update = update || parentUpdate; - case 'P': - e.style.top = toPos(pos.y); - e.style.removeProperty('bottom'); - break; - } - if (transform !== '') + if (count === numberOfParents) + { + if (update) + { + node.value = refreshValue(); + } + broadcastToKids(node, timestamp, update); + update = false; + count = 0; + } + }; + + for (var i = numberOfParents; i--; ) { - addTransform(e.style, transform); + args[i].kids.push(node); } - return e; - } - function addTransform(style, transform) - { - style.transform = transform; - style.msTransform = transform; - style.MozTransform = transform; - style.webkitTransform = transform; - style.OTransform = transform; + return node; } - function container(pos,elem) + + function map(func, a) { - var e = render(elem); - setPos(pos, elem, e); - var div = createNode('div'); - div.style.position = 'relative'; - div.style.overflow = 'hidden'; - div.appendChild(e); - return div; + function refreshValue() + { + return func(a.value); + } + return mapMany(refreshValue, [a]); } - function rawHtml(elem) + function map2(func, a, b) { - var html = elem.html; - var guid = elem.guid; - var align = elem.align; - - var div = createNode('div'); - div.innerHTML = html; - div.style.visibility = "hidden"; - if (align) + function refreshValue() { - div.style.textAlign = align; + return A2( func, a.value, b.value ); } - div.style.visibility = 'visible'; - div.style.pointerEvents = 'auto'; - return div; + return mapMany(refreshValue, [a, b]); } - // RENDER - - function render(elem) - { - return setProps(elem, makeElement(elem)); - } - function makeElement(e) + function map3(func, a, b, c) { - var elem = e.element; - switch(elem.ctor) + function refreshValue() { - case 'Image': - return image(e.props, elem); - - case 'Flow': - return flow(elem._0.ctor, elem._1); - - case 'Container': - return container(elem._0, elem._1); - - case 'Spacer': - return createNode('div'); + return A3( func, a.value, b.value, c.value ); + } + return mapMany(refreshValue, [a, b, c]); + } - case 'RawHtml': - return rawHtml(elem); - case 'Custom': - return elem.render(elem.model); + function map4(func, a, b, c, d) + { + function refreshValue() + { + return A4( func, a.value, b.value, c.value, d.value ); } + return mapMany(refreshValue, [a, b, c, d]); } - function updateAndReplace(node, curr, next) + + function map5(func, a, b, c, d, e) { - var newNode = update(node, curr, next); - if (newNode !== node) + function refreshValue() { - node.parentNode.replaceChild(newNode, node); + return A5( func, a.value, b.value, c.value, d.value, e.value ); } - return newNode; + return mapMany(refreshValue, [a, b, c, d, e]); } - // UPDATE + // FOLD - function update(node, curr, next) + function foldp(update, state, signal) { - var rootNode = node; - if (node.tagName === 'A') - { - node = node.firstChild; - } - if (curr.props.id === next.props.id) - { - updateProps(node, curr, next); - return rootNode; - } - if (curr.element.ctor !== next.element.ctor) - { - return render(next); - } - var nextE = next.element; - var currE = curr.element; - switch(nextE.ctor) + var node = { + id: Utils.guid(), + name: 'foldp', + parents: [signal], + kids: [], + value: state + }; + + node.notify = function(timestamp, parentUpdate, parentID) { - case "Spacer": - updateProps(node, curr, next); - return rootNode; + if (parentUpdate) + { + node.value = A2( update, signal.value, node.value ); + } + broadcastToKids(node, timestamp, parentUpdate); + }; - case "RawHtml": - if(currE.html.valueOf() !== nextE.html.valueOf()) - { - node.innerHTML = nextE.html; - } - updateProps(node, curr, next); - return rootNode; + signal.kids.push(node); - case "Image": - if (nextE._0.ctor === 'Plain') - { - if (nextE._3 !== currE._3) - { - node.src = nextE._3; - } - } - else if (!Utils.eq(nextE,currE) - || next.props.width !== curr.props.width - || next.props.height !== curr.props.height) - { - return render(next); - } - updateProps(node, curr, next); - return rootNode; + return node; + } - case "Flow": - var arr = List.toArray(nextE._1); - for (var i = arr.length; i--; ) - { - arr[i] = arr[i].element.ctor; - } - if (nextE._0.ctor !== currE._0.ctor) - { - return render(next); - } - var nexts = List.toArray(nextE._1); - var kids = node.childNodes; - if (nexts.length !== kids.length) - { - return render(next); - } - var currs = List.toArray(currE._1); - var dir = nextE._0.ctor; - var goDir = directionTable[dir]; - var toReverse = needsReversal(dir); - var len = kids.length; - for (var i = len; i-- ;) - { - var subNode = kids[toReverse ? len - i - 1 : i]; - goDir(updateAndReplace(subNode, currs[i], nexts[i])); - } - updateProps(node, curr, next); - return rootNode; - case "Container": - var subNode = node.firstChild; - var newSubNode = updateAndReplace(subNode, currE._1, nextE._1); - setPos(nextE._0, nextE._1, newSubNode); - updateProps(node, curr, next); - return rootNode; + // TIME + + function timestamp(signal) + { + var node = { + id: Utils.guid(), + name: 'timestamp', + value: Utils.Tuple2(localRuntime.timer.programStart, signal.value), + parents: [signal], + kids: [] + }; + + node.notify = function(timestamp, parentUpdate, parentID) + { + if (parentUpdate) + { + node.value = Utils.Tuple2(timestamp, signal.value); + } + broadcastToKids(node, timestamp, parentUpdate); + }; - case "Custom": - if (currE.type === nextE.type) - { - var updatedNode = nextE.update(node, currE.model, nextE.model); - updateProps(updatedNode, curr, next); - return updatedNode; - } - return render(next); - } + signal.kids.push(node); + + return node; } - function updateProps(node, curr, next) + + function delay(time, signal) { - var nextProps = next.props; - var currProps = curr.props; + var delayed = input('delay-input-' + time, signal.value); - var element = next.element; - var width = nextProps.width - (element.adjustWidth || 0); - var height = nextProps.height - (element.adjustHeight || 0); - if (width !== currProps.width) - { - node.style.width = (width|0) + 'px'; - } - if (height !== currProps.height) + function handler(value) { - node.style.height = (height|0) + 'px'; + setTimeout(function() { + localRuntime.notify(delayed.id, value); + }, time); } - if (nextProps.opacity !== currProps.opacity) - { - node.style.opacity = nextProps.opacity; - } + output('delay-output-' + time, handler, signal); - var nextColor = nextProps.color.ctor === 'Just' - ? Color.toCss(nextProps.color._0) - : ''; - if (node.style.backgroundColor !== nextColor) - { - node.style.backgroundColor = nextColor; - } + return delayed; + } - if (nextProps.tag !== currProps.tag) - { - node.id = nextProps.tag; - } - if (nextProps.href !== currProps.href) - { - if (currProps.href === '') - { - // add a surrounding href - var anchor = createNode('a'); - anchor.href = nextProps.href; - anchor.style.display = 'block'; - anchor.style.pointerEvents = 'auto'; + // MERGING - node.parentNode.replaceChild(anchor, node); - anchor.appendChild(node); - } - else if (nextProps.href === '') - { - // remove the surrounding href - var anchor = node.parentNode; - anchor.parentNode.replaceChild(node, anchor); - } - else - { - // just update the link - node.parentNode.href = nextProps.href; - } - } + function genericMerge(tieBreaker, leftStream, rightStream) + { + var node = { + id: Utils.guid(), + name: 'merge', + value: A2(tieBreaker, leftStream.value, rightStream.value), + parents: [leftStream, rightStream], + kids: [] + }; - // update click and hover handlers - var removed = false; + var left = { touched: false, update: false, value: null }; + var right = { touched: false, update: false, value: null }; - // update hover handlers - if (currProps.hover.ctor === '_Tuple0') + node.notify = function(timestamp, parentUpdate, parentID) { - if (nextProps.hover.ctor !== '_Tuple0') + if (parentID === leftStream.id) { - addHover(node, nextProps.hover); + left.touched = true; + left.update = parentUpdate; + left.value = leftStream.value; } - } - else - { - if (nextProps.hover.ctor === '_Tuple0') + if (parentID === rightStream.id) { - removed = true; - removeHover(node); + right.touched = true; + right.update = parentUpdate; + right.value = rightStream.value; } - else + + if (left.touched && right.touched) { - node.elm_hover_handler = nextProps.hover; + var update = false; + if (left.update && right.update) + { + node.value = A2(tieBreaker, left.value, right.value); + update = true; + } + else if (left.update) + { + node.value = left.value; + update = true; + } + else if (right.update) + { + node.value = right.value; + update = true; + } + left.touched = false; + right.touched = false; + + broadcastToKids(node, timestamp, update); } - } + }; - // update click handlers - if (currProps.click.ctor === '_Tuple0') + leftStream.kids.push(node); + rightStream.kids.push(node); + + return node; + } + + + // FILTERING + + function filterMap(toMaybe, base, signal) + { + var maybe = toMaybe(signal.value); + var node = { + id: Utils.guid(), + name: 'filterMap', + value: maybe.ctor === 'Nothing' ? base : maybe._0, + parents: [signal], + kids: [] + }; + + node.notify = function(timestamp, parentUpdate, parentID) { - if (nextProps.click.ctor !== '_Tuple0') + var update = false; + if (parentUpdate) { - addClick(node, nextProps.click); + var maybe = toMaybe(signal.value); + if (maybe.ctor === 'Just') + { + update = true; + node.value = maybe._0; + } } - } - else + broadcastToKids(node, timestamp, update); + }; + + signal.kids.push(node); + + return node; + } + + + // SAMPLING + + function sampleOn(ticker, signal) + { + var node = { + id: Utils.guid(), + name: 'sampleOn', + value: signal.value, + parents: [ticker, signal], + kids: [] + }; + + var signalTouch = false; + var tickerTouch = false; + var tickerUpdate = false; + + node.notify = function(timestamp, parentUpdate, parentID) { - if (nextProps.click.ctor === '_Tuple0') + if (parentID === ticker.id) { - removed = true; - removeClick(node); + tickerTouch = true; + tickerUpdate = parentUpdate; } - else + if (parentID === signal.id) { - node.elm_click_handler = nextProps.click; + signalTouch = true; } - } - // stop capturing clicks if - if (removed - && nextProps.hover.ctor === '_Tuple0' - && nextProps.click.ctor === '_Tuple0') - { - node.style.pointerEvents = 'none'; - } - } + if (tickerTouch && signalTouch) + { + if (tickerUpdate) + { + node.value = signal.value; + } + tickerTouch = false; + signalTouch = false; + broadcastToKids(node, timestamp, tickerUpdate); + } + }; - // TEXT + ticker.kids.push(node); + signal.kids.push(node); - function block(align) - { - return function(text) - { - var raw = { - ctor :'RawHtml', - html : Text.renderHtml(text), - align: align - }; - var pos = htmlHeight(0, raw); - return newElement(pos._0, pos._1, raw); - } + return node; } - function markdown(text) + + // DROP REPEATS + + function dropRepeats(signal) { - var raw = { - ctor:'RawHtml', - html: text, - align: null + var node = { + id: Utils.guid(), + name: 'dropRepeats', + value: signal.value, + parents: [signal], + kids: [] }; - var pos = htmlHeight(0, raw); - return newElement(pos._0, pos._1, raw); - } - function htmlHeight(width, rawHtml) - { - // create dummy node - var temp = document.createElement('div'); - temp.innerHTML = rawHtml.html; - if (width > 0) + node.notify = function(timestamp, parentUpdate, parentID) { - temp.style.width = width + "px"; - } - temp.style.visibility = "hidden"; - temp.style.styleFloat = "left"; - temp.style.cssFloat = "left"; + var update = false; + if (parentUpdate && !Utils.eq(node.value, signal.value)) + { + node.value = signal.value; + update = true; + } + broadcastToKids(node, timestamp, update); + }; - document.body.appendChild(temp); + signal.kids.push(node); - // get dimensions - var style = window.getComputedStyle(temp, null); - var w = Math.ceil(style.getPropertyValue("width").slice(0,-2) - 0); - var h = Math.ceil(style.getPropertyValue("height").slice(0,-2) - 0); - document.body.removeChild(temp); - return Utils.Tuple2(w,h); + return node; } - return localRuntime.Native.Graphics.Element.values = { - render: render, - update: update, - updateAndReplace: updateAndReplace, - - createNode: createNode, - newElement: F3(newElement), - addTransform: addTransform, - htmlHeight: F2(htmlHeight), - guid: Utils.guid, - - block: block, - markdown: markdown + return localRuntime.Native.Signal.values = { + input: input, + constant: constant, + mailbox: mailbox, + sendMessage: sendMessage, + output: output, + map: F2(map), + map2: F3(map2), + map3: F4(map3), + map4: F5(map4), + map5: F6(map5), + foldp: F3(foldp), + genericMerge: F3(genericMerge), + filterMap: F3(filterMap), + sampleOn: F2(sampleOn), + dropRepeats: dropRepeats, + timestamp: timestamp, + delay: F2(delay) }; - }; -Elm.Native.Http = {}; -Elm.Native.Http.make = function(localRuntime) { +Elm.Native.Time = {}; +Elm.Native.Time.make = function(localRuntime) +{ localRuntime.Native = localRuntime.Native || {}; - localRuntime.Native.Http = localRuntime.Native.Http || {}; - if (localRuntime.Native.Http.values) + localRuntime.Native.Time = localRuntime.Native.Time || {}; + if (localRuntime.Native.Time.values) { - return localRuntime.Native.Http.values; + return localRuntime.Native.Time.values; } - var Dict = Elm.Dict.make(localRuntime); - var List = Elm.List.make(localRuntime); + var NS = Elm.Native.Signal.make(localRuntime); var Maybe = Elm.Maybe.make(localRuntime); - var Task = Elm.Native.Task.make(localRuntime); - var Utils = Elm.Native.Utils.make(localRuntime); - - function send(settings, request) - { - var req = new XMLHttpRequest(); - - var abortTask = Task.asyncFunction(function(callback) { - req.abort(); - return callback(Task.succeed(Utils.Tuple0)); - }); - - var sendTask = Task.asyncFunction(function(callback) { - - // start - if (settings.onStart.ctor === 'Just') - { - req.addEventListener('loadStart', function() { - var task = settings.onStart._0; - Task.spawn(task); - }); - } - // progress - if (settings.onProgress.ctor === 'Just') - { - req.addEventListener('progress', function(event) { - var progress = !event.lengthComputable - ? Maybe.Nothing - : Maybe.Just({ - _: {}, - loaded: event.loaded, - total: event.total - }); - var task = settings.onProgress._0(progress); - Task.spawn(task); - }); - } - // end - req.addEventListener('error', function() { - return callback(Task.fail({ ctor: 'RawNetworkError' })); - }); + // FRAMES PER SECOND - req.addEventListener('timeout', function() { - return callback(Task.fail({ ctor: 'RawTimeout' })); - }); + function fpsWhen(desiredFPS, isOn) + { + var msPerFrame = 1000 / desiredFPS; + var ticker = NS.input('fps-' + desiredFPS, null); - req.addEventListener('load', function() { - return callback(Task.succeed(toResponse(req))); - }); + function notifyTicker() + { + localRuntime.notify(ticker.id, null); + } - req.open(request.verb, request.url, true); + function firstArg(x, y) + { + return x; + } - // set all the headers - function setHeader(pair) { - req.setRequestHeader(pair._0, pair._1); - } - A2(List.map, setHeader, request.headers); + // input fires either when isOn changes, or when ticker fires. + // Its value is a tuple with the current timestamp, and the state of isOn + var input = NS.timestamp(A3(NS.map2, F2(firstArg), NS.dropRepeats(isOn), ticker)); - // set the timeout - req.timeout = settings.timeout; + var initialState = { + isOn: false, + time: localRuntime.timer.programStart, + delta: 0 + }; - // enable this withCredentials thing - req.withCredentials = settings.withCredentials; + var timeoutId; - // ask for a specific MIME type for the response - if (settings.desiredResponseType.ctor === 'Just') - { - req.overrideMimeType(settings.desiredResponseType._0); - } + function update(input, state) + { + var currentTime = input._0; + var isOn = input._1; + var wasOn = state.isOn; + var previousTime = state.time; - // actuall send the request - if(request.body.ctor === "BodyFormData") + if (isOn) { - req.send(request.body.formData) + timeoutId = localRuntime.setTimeout(notifyTicker, msPerFrame); } - else + else if (wasOn) { - req.send(request.body._0); + clearTimeout(timeoutId); } - }); - return {ctor: "_Tuple2" - ,_0: sendTask - ,_1: abortTask}; + return { + isOn: isOn, + time: currentTime, + delta: (isOn && !wasOn) ? 0 : currentTime - previousTime + }; + } + + return A2( + NS.map, + function(state) { return state.delta; }, + A3(NS.foldp, F2(update), update(input.value, initialState), input) + ); } - // deal with responses + // EVERY - function toResponse(req) + function every(t) { - var tag = req.responseType === 'blob' ? 'Blob' : 'Text' - var response = tag === 'Blob' ? req.response : req.responseText; - return { - _: {}, - status: req.status, - statusText: req.statusText, - headers: parseHeaders(req.getAllResponseHeaders()), - url: req.responseURL, - value: { ctor: tag, _0: response } - }; + var ticker = NS.input('every-' + t, null); + function tellTime() + { + localRuntime.notify(ticker.id, null); + } + var clock = A2(NS.map, fst, NS.timestamp(ticker)); + setInterval(tellTime, t); + return clock; } - function parseHeaders(rawHeaders) + function fst(pair) { - var headers = Dict.empty; - - if (!rawHeaders) - { - return headers; - } - - var headerPairs = rawHeaders.split('\u000d\u000a'); - for (var i = headerPairs.length; i--; ) - { - var headerPair = headerPairs[i]; - var index = headerPair.indexOf('\u003a\u0020'); - if (index > 0) - { - var key = headerPair.substring(0, index); - var value = headerPair.substring(index + 2); + return pair._0; + } - headers = A3(Dict.update, key, function(oldValue) { - if (oldValue.ctor === 'Just') - { - return Maybe.Just(value + ', ' + oldValue._0); - } - return Maybe.Just(value); - }, headers); - } - } - return headers; + function read(s) + { + var t = Date.parse(s); + return isNaN(t) ? Maybe.Nothing : Maybe.Just(t); } + return localRuntime.Native.Time.values = { + fpsWhen: F2(fpsWhen), + every: every, + toDate: function(t) { return new Date(t); }, + read: read + }; +}; - function multipart(dataList) +Elm.Native.Transform2D = {}; +Elm.Native.Transform2D.make = function(localRuntime) { + localRuntime.Native = localRuntime.Native || {}; + localRuntime.Native.Transform2D = localRuntime.Native.Transform2D || {}; + if (localRuntime.Native.Transform2D.values) { - var formData = new FormData(); + return localRuntime.Native.Transform2D.values; + } - while (dataList.ctor !== '[]') + var A; + if (typeof Float32Array === 'undefined') + { + A = function(arr) { - var data = dataList._0; - if (data.ctor === 'StringData') - { - formData.append(data._0, data._1); - } - else - { - var fileName = data._1.ctor === 'Nothing' - ? undefined - : data._1._0; - formData.append(data._0, data._2, fileName); - } - dataList = dataList._1; - } + this.length = arr.length; + this[0] = arr[0]; + this[1] = arr[1]; + this[2] = arr[2]; + this[3] = arr[3]; + this[4] = arr[4]; + this[5] = arr[5]; + }; + } + else + { + A = Float32Array; + } - return { ctor: 'BodyFormData', formData: formData }; + // layout of matrix in an array is + // + // | m11 m12 dx | + // | m21 m22 dy | + // | 0 0 1 | + // + // new A([ m11, m12, dx, m21, m22, dy ]) + + var identity = new A([1, 0, 0, 0, 1, 0]); + function matrix(m11, m12, m21, m22, dx, dy) + { + return new A([m11, m12, dx, m21, m22, dy]); } + function rotation(t) + { + var c = Math.cos(t); + var s = Math.sin(t); + return new A([c, -s, 0, s, c, 0]); + } - function uriEncode(string) + function rotate(t, m) { - return encodeURIComponent(string); + var c = Math.cos(t); + var s = Math.sin(t); + var m11 = m[0], m12 = m[1], m21 = m[3], m22 = m[4]; + return new A([m11 * c + m12 * s, -m11 * s + m12 * c, m[2], + m21 * c + m22 * s, -m21 * s + m22 * c, m[5]]); } + /* + function move(xy,m) { + var x = xy._0; + var y = xy._1; + var m11 = m[0], m12 = m[1], m21 = m[3], m22 = m[4]; + return new A([m11, m12, m11*x + m12*y + m[2], + m21, m22, m21*x + m22*y + m[5]]); + } + function scale(s,m) { return new A([m[0]*s, m[1]*s, m[2], m[3]*s, m[4]*s, m[5]]); } + function scaleX(x,m) { return new A([m[0]*x, m[1], m[2], m[3]*x, m[4], m[5]]); } + function scaleY(y,m) { return new A([m[0], m[1]*y, m[2], m[3], m[4]*y, m[5]]); } + function reflectX(m) { return new A([-m[0], m[1], m[2], -m[3], m[4], m[5]]); } + function reflectY(m) { return new A([m[0], -m[1], m[2], m[3], -m[4], m[5]]); } - function uriDecode(string) + function transform(m11, m21, m12, m22, mdx, mdy, n) { + var n11 = n[0], n12 = n[1], n21 = n[3], n22 = n[4], ndx = n[2], ndy = n[5]; + return new A([m11*n11 + m12*n21, + m11*n12 + m12*n22, + m11*ndx + m12*ndy + mdx, + m21*n11 + m22*n21, + m21*n12 + m22*n22, + m21*ndx + m22*ndy + mdy]); + } + */ + function multiply(m, n) { - return decodeURIComponent(string); + var m11 = m[0], m12 = m[1], m21 = m[3], m22 = m[4], mdx = m[2], mdy = m[5]; + var n11 = n[0], n12 = n[1], n21 = n[3], n22 = n[4], ndx = n[2], ndy = n[5]; + return new A([m11 * n11 + m12 * n21, + m11 * n12 + m12 * n22, + m11 * ndx + m12 * ndy + mdx, + m21 * n11 + m22 * n21, + m21 * n12 + m22 * n22, + m21 * ndx + m22 * ndy + mdy]); } - return localRuntime.Native.Http.values = { - send: F2(send), - multipart: multipart, - uriEncode: uriEncode, - uriDecode: uriDecode + return localRuntime.Native.Transform2D.values = { + identity: identity, + matrix: F6(matrix), + rotation: rotation, + multiply: F2(multiply) + /* + transform: F7(transform), + rotate: F2(rotate), + move: F2(move), + scale: F2(scale), + scaleX: F2(scaleX), + scaleY: F2(scaleY), + reflectX: reflectX, + reflectY: reflectY + */ }; }; -Elm.Native.Json = {}; -Elm.Native.Json.make = function(localRuntime) { +Elm.Transform2D = Elm.Transform2D || {}; +Elm.Transform2D.make = function (_elm) { + "use strict"; + _elm.Transform2D = _elm.Transform2D || {}; + if (_elm.Transform2D.values) return _elm.Transform2D.values; + var _U = Elm.Native.Utils.make(_elm),$Native$Transform2D = Elm.Native.Transform2D.make(_elm); + var _op = {}; + var multiply = $Native$Transform2D.multiply; + var rotation = $Native$Transform2D.rotation; + var matrix = $Native$Transform2D.matrix; + var translation = F2(function (x,y) { return A6(matrix,1,0,0,1,x,y);}); + var scale = function (s) { return A6(matrix,s,0,0,s,0,0);}; + var scaleX = function (x) { return A6(matrix,x,0,0,1,0,0);}; + var scaleY = function (y) { return A6(matrix,1,0,0,y,0,0);}; + var identity = $Native$Transform2D.identity; + var Transform2D = {ctor: "Transform2D"}; + return _elm.Transform2D.values = {_op: _op + ,identity: identity + ,matrix: matrix + ,multiply: multiply + ,rotation: rotation + ,translation: translation + ,scale: scale + ,scaleX: scaleX + ,scaleY: scaleY}; +}; + +// setup +Elm.Native = Elm.Native || {}; +Elm.Native.Graphics = Elm.Native.Graphics || {}; +Elm.Native.Graphics.Collage = Elm.Native.Graphics.Collage || {}; + +// definition +Elm.Native.Graphics.Collage.make = function(localRuntime) { + 'use strict'; + // attempt to short-circuit localRuntime.Native = localRuntime.Native || {}; - localRuntime.Native.Json = localRuntime.Native.Json || {}; - if (localRuntime.Native.Json.values) { - return localRuntime.Native.Json.values; + localRuntime.Native.Graphics = localRuntime.Native.Graphics || {}; + localRuntime.Native.Graphics.Collage = localRuntime.Native.Graphics.Collage || {}; + if ('values' in localRuntime.Native.Graphics.Collage) + { + return localRuntime.Native.Graphics.Collage.values; } - var ElmArray = Elm.Native.Array.make(localRuntime); + // okay, we cannot short-ciruit, so now we define everything + var Color = Elm.Native.Color.make(localRuntime); var List = Elm.Native.List.make(localRuntime); - var Maybe = Elm.Maybe.make(localRuntime); - var Result = Elm.Result.make(localRuntime); + var NativeElement = Elm.Native.Graphics.Element.make(localRuntime); + var Transform = Elm.Transform2D.make(localRuntime); var Utils = Elm.Native.Utils.make(localRuntime); + function setStrokeStyle(ctx, style) + { + ctx.lineWidth = style.width; - function crash(expected, actual) { - throw new Error( - 'expecting ' + expected + ' but got ' + JSON.stringify(actual) - ); - } - + var cap = style.cap.ctor; + ctx.lineCap = cap === 'Flat' + ? 'butt' + : cap === 'Round' + ? 'round' + : 'square'; - // PRIMITIVE VALUES + var join = style.join.ctor; + ctx.lineJoin = join === 'Smooth' + ? 'round' + : join === 'Sharp' + ? 'miter' + : 'bevel'; - function decodeNull(successValue) { - return function(value) { - if (value === null) { - return successValue; - } - crash('null', value); - }; + ctx.miterLimit = style.join._0 || 10; + ctx.strokeStyle = Color.toCss(style.color); } + function setFillStyle(redo, ctx, style) + { + var sty = style.ctor; + ctx.fillStyle = sty === 'Solid' + ? Color.toCss(style._0) + : sty === 'Texture' + ? texture(redo, ctx, style._0) + : gradient(ctx, style._0); + } - function decodeString(value) { - if (typeof value === 'string' || value instanceof String) { - return value; + function trace(ctx, path) + { + var points = List.toArray(path); + var i = points.length - 1; + if (i <= 0) + { + return; + } + ctx.moveTo(points[i]._0, points[i]._1); + while (i--) + { + ctx.lineTo(points[i]._0, points[i]._1); + } + if (path.closed) + { + i = points.length - 1; + ctx.lineTo(points[i]._0, points[i]._1); } - crash('a String', value); } - - function decodeFloat(value) { - if (typeof value === 'number') { - return value; + function line(ctx, style, path) + { + if (style.dashing.ctor === '[]') + { + trace(ctx, path); } - crash('a Float', value); + else + { + customLineHelp(ctx, style, path); + } + ctx.scale(1, -1); + ctx.stroke(); } - - function decodeInt(value) { - if (typeof value === 'number' && (value|0) === value) { - return value; + function customLineHelp(ctx, style, path) + { + var points = List.toArray(path); + if (path.closed) + { + points.push(points[0]); + } + var pattern = List.toArray(style.dashing); + var i = points.length - 1; + if (i <= 0) + { + return; + } + var x0 = points[i]._0, y0 = points[i]._1; + var x1 = 0, y1 = 0, dx = 0, dy = 0, remaining = 0; + var pindex = 0, plen = pattern.length; + var draw = true, segmentLength = pattern[0]; + ctx.moveTo(x0, y0); + while (i--) + { + x1 = points[i]._0; + y1 = points[i]._1; + dx = x1 - x0; + dy = y1 - y0; + remaining = Math.sqrt(dx * dx + dy * dy); + while (segmentLength <= remaining) + { + x0 += dx * segmentLength / remaining; + y0 += dy * segmentLength / remaining; + ctx[draw ? 'lineTo' : 'moveTo'](x0, y0); + // update starting position + dx = x1 - x0; + dy = y1 - y0; + remaining = Math.sqrt(dx * dx + dy * dy); + // update pattern + draw = !draw; + pindex = (pindex + 1) % plen; + segmentLength = pattern[pindex]; + } + if (remaining > 0) + { + ctx[draw ? 'lineTo' : 'moveTo'](x1, y1); + segmentLength -= remaining; + } + x0 = x1; + y0 = y1; } - crash('an Int', value); } - - function decodeBool(value) { - if (typeof value === 'boolean') { - return value; - } - crash('a Bool', value); + function drawLine(ctx, style, path) + { + setStrokeStyle(ctx, style); + return line(ctx, style, path); } - - // ARRAY - - function decodeArray(decoder) { - return function(value) { - if (value instanceof Array) { - var len = value.length; - var array = new Array(len); - for (var i = len; i-- ; ) { - array[i] = decoder(value[i]); - } - return ElmArray.fromJSArray(array); - } - crash('an Array', value); - }; + function texture(redo, ctx, src) + { + var img = new Image(); + img.src = src; + img.onload = redo; + return ctx.createPattern(img, 'repeat'); } + function gradient(ctx, grad) + { + var g; + var stops = []; + if (grad.ctor === 'Linear') + { + var p0 = grad._0, p1 = grad._1; + g = ctx.createLinearGradient(p0._0, -p0._1, p1._0, -p1._1); + stops = List.toArray(grad._2); + } + else + { + var p0 = grad._0, p2 = grad._2; + g = ctx.createRadialGradient(p0._0, -p0._1, grad._1, p2._0, -p2._1, grad._3); + stops = List.toArray(grad._4); + } + var len = stops.length; + for (var i = 0; i < len; ++i) + { + var stop = stops[i]; + g.addColorStop(stop._0, Color.toCss(stop._1)); + } + return g; + } - // LIST - - function decodeList(decoder) { - return function(value) { - if (value instanceof Array) { - var len = value.length; - var list = List.Nil; - for (var i = len; i-- ; ) { - list = List.Cons( decoder(value[i]), list ); - } - return list; - } - crash('a List', value); - }; + function drawShape(redo, ctx, style, path) + { + trace(ctx, path); + setFillStyle(redo, ctx, style); + ctx.scale(1, -1); + ctx.fill(); } - // MAYBE + // TEXT RENDERING - function decodeMaybe(decoder) { - return function(value) { - try { - return Maybe.Just(decoder(value)); - } catch(e) { - return Maybe.Nothing; - } - }; + function fillText(redo, ctx, text) + { + drawText(ctx, text, ctx.fillText); } - - // FIELDS - - function decodeField(field, decoder) { - return function(value) { - var subValue = value[field]; - if (subValue !== undefined) { - return decoder(subValue); - } - crash("an object with field '" + field + "'", value); - }; + function strokeText(redo, ctx, style, text) + { + setStrokeStyle(ctx, style); + // Use native canvas API for dashes only for text for now + // Degrades to non-dashed on IE 9 + 10 + if (style.dashing.ctor !== '[]' && ctx.setLineDash) + { + var pattern = List.toArray(style.dashing); + ctx.setLineDash(pattern); + } + drawText(ctx, text, ctx.strokeText); } + function drawText(ctx, text, canvasDrawFn) + { + var textChunks = chunkText(defaultContext, text); - // OBJECTS + var totalWidth = 0; + var maxHeight = 0; + var numChunks = textChunks.length; - function decodeKeyValuePairs(decoder) { - return function(value) { - var isObject = - typeof value === 'object' - && value !== null - && !(value instanceof Array); + ctx.scale(1,-1); - if (isObject) { - var keyValuePairs = List.Nil; - for (var key in value) { - var elmValue = decoder(value[key]); - var pair = Utils.Tuple2(key, elmValue); - keyValuePairs = List.Cons(pair, keyValuePairs); - } - return keyValuePairs; + for (var i = numChunks; i--; ) + { + var chunk = textChunks[i]; + ctx.font = chunk.font; + var metrics = ctx.measureText(chunk.text); + chunk.width = metrics.width; + totalWidth += chunk.width; + if (chunk.height > maxHeight) + { + maxHeight = chunk.height; } + } - crash("an object", value); - }; - } - - function decodeObject1(f, d1) { - return function(value) { - return f(d1(value)); - }; - } - - function decodeObject2(f, d1, d2) { - return function(value) { - return A2( f, d1(value), d2(value) ); - }; - } - - function decodeObject3(f, d1, d2, d3) { - return function(value) { - return A3( f, d1(value), d2(value), d3(value) ); - }; + var x = -totalWidth / 2.0; + for (var i = 0; i < numChunks; ++i) + { + var chunk = textChunks[i]; + ctx.font = chunk.font; + ctx.fillStyle = chunk.color; + canvasDrawFn.call(ctx, chunk.text, x, maxHeight / 2); + x += chunk.width; + } } - function decodeObject4(f, d1, d2, d3, d4) { - return function(value) { - return A4( f, d1(value), d2(value), d3(value), d4(value) ); - }; + function toFont(props) + { + return [ + props['font-style'], + props['font-variant'], + props['font-weight'], + props['font-size'], + props['font-family'] + ].join(' '); } - function decodeObject5(f, d1, d2, d3, d4, d5) { - return function(value) { - return A5( f, d1(value), d2(value), d3(value), d4(value), d5(value) ); - }; - } - function decodeObject6(f, d1, d2, d3, d4, d5, d6) { - return function(value) { - return A6( f, - d1(value), - d2(value), - d3(value), - d4(value), - d5(value), - d6(value) - ); - }; + // Convert the object returned by the text module + // into something we can use for styling canvas text + function chunkText(context, text) + { + var tag = text.ctor; + if (tag === 'Text:Append') + { + var leftChunks = chunkText(context, text._0); + var rightChunks = chunkText(context, text._1); + return leftChunks.concat(rightChunks); + } + if (tag === 'Text:Text') + { + return [{ + text: text._0, + color: context.color, + height: context['font-size'].slice(0, -2) | 0, + font: toFont(context) + }]; + } + if (tag === 'Text:Meta') + { + var newContext = freshContext(text._0, context); + return chunkText(newContext, text._1); + } } - function decodeObject7(f, d1, d2, d3, d4, d5, d6, d7) { - return function(value) { - return A7( f, - d1(value), - d2(value), - d3(value), - d4(value), - d5(value), - d6(value), - d7(value) - ); + function freshContext(props, ctx) + { + return { + 'font-style': props['font-style'] || ctx['font-style'], + 'font-variant': props['font-variant'] || ctx['font-variant'], + 'font-weight': props['font-weight'] || ctx['font-weight'], + 'font-size': props['font-size'] || ctx['font-size'], + 'font-family': props['font-family'] || ctx['font-family'], + 'color': props['color'] || ctx['color'] }; } - function decodeObject8(f, d1, d2, d3, d4, d5, d6, d7, d8) { - return function(value) { - return A8( f, - d1(value), - d2(value), - d3(value), - d4(value), - d5(value), - d6(value), - d7(value), - d8(value) - ); - }; - } + var defaultContext = { + 'font-style': 'normal', + 'font-variant': 'normal', + 'font-weight': 'normal', + 'font-size': '12px', + 'font-family': 'sans-serif', + 'color': 'black' + }; - // TUPLES + // IMAGES - function decodeTuple1(f, d1) { - return function(value) { - if ( !(value instanceof Array) || value.length !== 1 ) { - crash('a Tuple of length 1', value); - } - return f( d1(value[0]) ); - }; - } + function drawImage(redo, ctx, form) + { + var img = new Image(); + img.onload = redo; + img.src = form._3; + var w = form._0, + h = form._1, + pos = form._2, + srcX = pos._0, + srcY = pos._1, + srcW = w, + srcH = h, + destX = -w / 2, + destY = -h / 2, + destW = w, + destH = h; - function decodeTuple2(f, d1, d2) { - return function(value) { - if ( !(value instanceof Array) || value.length !== 2 ) { - crash('a Tuple of length 2', value); - } - return A2( f, d1(value[0]), d2(value[1]) ); - }; + ctx.scale(1, -1); + ctx.drawImage(img, srcX, srcY, srcW, srcH, destX, destY, destW, destH); } - function decodeTuple3(f, d1, d2, d3) { - return function(value) { - if ( !(value instanceof Array) || value.length !== 3 ) { - crash('a Tuple of length 3', value); - } - return A3( f, d1(value[0]), d2(value[1]), d3(value[2]) ); - }; - } + function renderForm(redo, ctx, form) + { + ctx.save(); + var x = form.x, + y = form.y, + theta = form.theta, + scale = form.scale; - function decodeTuple4(f, d1, d2, d3, d4) { - return function(value) { - if ( !(value instanceof Array) || value.length !== 4 ) { - crash('a Tuple of length 4', value); - } - return A4( f, d1(value[0]), d2(value[1]), d3(value[2]), d4(value[3]) ); - }; - } + if (x !== 0 || y !== 0) + { + ctx.translate(x, y); + } + if (theta !== 0) + { + ctx.rotate(theta % (Math.PI * 2)); + } + if (scale !== 1) + { + ctx.scale(scale, scale); + } + if (form.alpha !== 1) + { + ctx.globalAlpha = ctx.globalAlpha * form.alpha; + } + ctx.beginPath(); + var f = form.form; + switch (f.ctor) + { + case 'FPath': + drawLine(ctx, f._0, f._1); + break; - function decodeTuple5(f, d1, d2, d3, d4, d5) { - return function(value) { - if ( !(value instanceof Array) || value.length !== 5 ) { - crash('a Tuple of length 5', value); - } - return A5( f, - d1(value[0]), - d2(value[1]), - d3(value[2]), - d4(value[3]), - d5(value[4]) - ); - }; - } + case 'FImage': + drawImage(redo, ctx, f); + break; + case 'FShape': + if (f._0.ctor === 'Line') + { + f._1.closed = true; + drawLine(ctx, f._0._0, f._1); + } + else + { + drawShape(redo, ctx, f._0._0, f._1); + } + break; - function decodeTuple6(f, d1, d2, d3, d4, d5, d6) { - return function(value) { - if ( !(value instanceof Array) || value.length !== 6 ) { - crash('a Tuple of length 6', value); - } - return A6( f, - d1(value[0]), - d2(value[1]), - d3(value[2]), - d4(value[3]), - d5(value[4]), - d6(value[5]) - ); - }; - } + case 'FText': + fillText(redo, ctx, f._0); + break; - function decodeTuple7(f, d1, d2, d3, d4, d5, d6, d7) { - return function(value) { - if ( !(value instanceof Array) || value.length !== 7 ) { - crash('a Tuple of length 7', value); - } - return A7( f, - d1(value[0]), - d2(value[1]), - d3(value[2]), - d4(value[3]), - d5(value[4]), - d6(value[5]), - d7(value[6]) - ); - }; + case 'FOutlinedText': + strokeText(redo, ctx, f._0, f._1); + break; + } + ctx.restore(); } + function formToMatrix(form) + { + var scale = form.scale; + var matrix = A6( Transform.matrix, scale, 0, 0, scale, form.x, form.y ); - function decodeTuple8(f, d1, d2, d3, d4, d5, d6, d7, d8) { - return function(value) { - if ( !(value instanceof Array) || value.length !== 8 ) { - crash('a Tuple of length 8', value); - } - return A8( f, - d1(value[0]), - d2(value[1]), - d3(value[2]), - d4(value[3]), - d5(value[4]), - d6(value[5]), - d7(value[6]), - d8(value[7]) - ); - }; + var theta = form.theta; + if (theta !== 0) + { + matrix = A2( Transform.multiply, matrix, Transform.rotation(theta) ); + } + + return matrix; } + function str(n) + { + if (n < 0.00001 && n > -0.00001) + { + return 0; + } + return n; + } - // CUSTOM DECODERS + function makeTransform(w, h, form, matrices) + { + var props = form.form._0._0.props; + var m = A6( Transform.matrix, 1, 0, 0, -1, + (w - props.width ) / 2, + (h - props.height) / 2 ); + var len = matrices.length; + for (var i = 0; i < len; ++i) + { + m = A2( Transform.multiply, m, matrices[i] ); + } + m = A2( Transform.multiply, m, formToMatrix(form) ); - function decodeValue(value) { - return value; + return 'matrix(' + + str( m[0]) + ', ' + str( m[3]) + ', ' + + str(-m[1]) + ', ' + str(-m[4]) + ', ' + + str( m[2]) + ', ' + str( m[5]) + ')'; } - function runDecoderValue(decoder, value) { - try { - return Result.Ok(decoder(value)); - } catch(e) { - return Result.Err(e.message); + function stepperHelp(list) + { + var arr = List.toArray(list); + var i = 0; + function peekNext() + { + return i < arr.length ? arr[i]._0.form.ctor : ''; + } + // assumes that there is a next element + function next() + { + var out = arr[i]._0; + ++i; + return out; } + return { + peekNext: peekNext, + next: next + }; } - function customDecoder(decoder, callback) { - return function(value) { - var result = callback(decoder(value)); - if (result.ctor === 'Err') { - throw new Error('custom decoder failed: ' + result._0); + function formStepper(forms) + { + var ps = [stepperHelp(forms)]; + var matrices = []; + var alphas = []; + function peekNext() + { + var len = ps.length; + var formType = ''; + for (var i = 0; i < len; ++i ) + { + if (formType = ps[i].peekNext()) return formType; + } + return ''; + } + // assumes that there is a next element + function next(ctx) + { + while (!ps[0].peekNext()) + { + ps.shift(); + matrices.pop(); + alphas.shift(); + if (ctx) + { + ctx.restore(); + } + } + var out = ps[0].next(); + var f = out.form; + if (f.ctor === 'FGroup') + { + ps.unshift(stepperHelp(f._1)); + var m = A2(Transform.multiply, f._0, formToMatrix(out)); + ctx.save(); + ctx.transform(m[0], m[3], m[1], m[4], m[2], m[5]); + matrices.push(m); + + var alpha = (alphas[0] || 1) * out.alpha; + alphas.unshift(alpha); + ctx.globalAlpha = alpha; } - return result._0; + return out; } - } - - function andThen(decode, callback) { - return function(value) { - var result = decode(value); - return callback(result)(value); + function transforms() + { + return matrices; } - } - - function fail(msg) { - return function(value) { - throw new Error(msg); + function alpha() + { + return alphas[0] || 1; } + return { + peekNext: peekNext, + next: next, + transforms: transforms, + alpha: alpha + }; } - function succeed(successValue) { - return function(value) { - return successValue; - } + function makeCanvas(w, h) + { + var canvas = NativeElement.createNode('canvas'); + canvas.style.width = w + 'px'; + canvas.style.height = h + 'px'; + canvas.style.display = 'block'; + canvas.style.position = 'absolute'; + var ratio = window.devicePixelRatio || 1; + canvas.width = w * ratio; + canvas.height = h * ratio; + return canvas; } + function render(model) + { + var div = NativeElement.createNode('div'); + div.style.overflow = 'hidden'; + div.style.position = 'relative'; + update(div, model, model); + return div; + } - // ONE OF MANY + function nodeStepper(w, h, div) + { + var kids = div.childNodes; + var i = 0; + var ratio = window.devicePixelRatio || 1; - function oneOf(decoders) { - return function(value) { - var errors = []; - var temp = decoders; - while (temp.ctor !== '[]') { - try { - return temp._0(value); - } catch(e) { - errors.push(e.message); + function transform(transforms, ctx) + { + ctx.translate( w / 2 * ratio, h / 2 * ratio ); + ctx.scale( ratio, -ratio ); + var len = transforms.length; + for (var i = 0; i < len; ++i) + { + var m = transforms[i]; + ctx.save(); + ctx.transform(m[0], m[3], m[1], m[4], m[2], m[5]); + } + return ctx; + } + function nextContext(transforms) + { + while (i < kids.length) + { + var node = kids[i]; + if (node.getContext) + { + node.width = w * ratio; + node.height = h * ratio; + node.style.width = w + 'px'; + node.style.height = h + 'px'; + ++i; + return transform(transforms, node.getContext('2d')); } - temp = temp._1; + div.removeChild(node); } - throw new Error('expecting one of the following:\n ' + errors.join('\n ')); + var canvas = makeCanvas(w, h); + div.appendChild(canvas); + // we have added a new node, so we must step our position + ++i; + return transform(transforms, canvas.getContext('2d')); } - } + function addElement(matrices, alpha, form) + { + var kid = kids[i]; + var elem = form.form._0; - function get(decoder, value) { - try { - return Result.Ok(decoder(value)); - } catch(e) { - return Result.Err(e.message); + var node = (!kid || kid.getContext) + ? NativeElement.render(elem) + : NativeElement.update(kid, kid.oldElement, elem); + + node.style.position = 'absolute'; + node.style.opacity = alpha * form.alpha * elem._0.props.opacity; + NativeElement.addTransform(node.style, makeTransform(w, h, form, matrices)); + node.oldElement = elem; + ++i; + if (!kid) + { + div.appendChild(node); + } + else + { + div.insertBefore(node, kid); + } + } + function clearRest() + { + while (i < kids.length) + { + div.removeChild(kids[i]); + } } + return { + nextContext: nextContext, + addElement: addElement, + clearRest: clearRest + }; } - // ENCODE / DECODE - - function runDecoderString(decoder, string) { - try { - return Result.Ok(decoder(JSON.parse(string))); - } catch(e) { - return Result.Err(e.message); - } - } + function update(div, _, model) + { + var w = model.w; + var h = model.h; - function encode(indentLevel, value) { - return JSON.stringify(value, null, indentLevel); - } + var forms = formStepper(model.forms); + var nodes = nodeStepper(w, h, div); + var ctx = null; + var formType = ''; - function identity(value) { - return value; - } + while (formType = forms.peekNext()) + { + // make sure we have context if we need it + if (ctx === null && formType !== 'FElement') + { + ctx = nodes.nextContext(forms.transforms()); + ctx.globalAlpha = forms.alpha(); + } - function encodeObject(keyValuePairs) { - var obj = {}; - while (keyValuePairs.ctor !== '[]') { - var pair = keyValuePairs._0; - obj[pair._0] = pair._1; - keyValuePairs = keyValuePairs._1; + var form = forms.next(ctx); + // if it is FGroup, all updates are made within formStepper when next is called. + if (formType === 'FElement') + { + // update or insert an element, get a new context + nodes.addElement(forms.transforms(), forms.alpha(), form); + ctx = null; + } + else if (formType !== 'FGroup') + { + renderForm(function() { update(div, model, model); }, ctx, form); + } } - return obj; + nodes.clearRest(); + return div; } - return localRuntime.Native.Json.values = { - encode: F2(encode), - runDecoderString: F2(runDecoderString), - runDecoderValue: F2(runDecoderValue), - get: F2(get), - oneOf: oneOf, + function collage(w, h, forms) + { + return A3(NativeElement.newElement, w, h, { + ctor: 'Custom', + type: 'Collage', + render: render, + update: update, + model: {w: w, h: h, forms: forms} + }); + } - decodeNull: decodeNull, - decodeInt: decodeInt, - decodeFloat: decodeFloat, - decodeString: decodeString, - decodeBool: decodeBool, + return localRuntime.Native.Graphics.Collage.values = { + collage: F3(collage) + }; +}; - decodeMaybe: decodeMaybe, - decodeList: decodeList, - decodeArray: decodeArray, +// setup +Elm.Native = Elm.Native || {}; +Elm.Native.Graphics = Elm.Native.Graphics || {}; +Elm.Native.Graphics.Element = Elm.Native.Graphics.Element || {}; - decodeField: F2(decodeField), +// definition +Elm.Native.Graphics.Element.make = function(localRuntime) { + 'use strict'; - decodeObject1: F2(decodeObject1), - decodeObject2: F3(decodeObject2), - decodeObject3: F4(decodeObject3), - decodeObject4: F5(decodeObject4), - decodeObject5: F6(decodeObject5), - decodeObject6: F7(decodeObject6), - decodeObject7: F8(decodeObject7), - decodeObject8: F9(decodeObject8), - decodeKeyValuePairs: decodeKeyValuePairs, + // attempt to short-circuit + localRuntime.Native = localRuntime.Native || {}; + localRuntime.Native.Graphics = localRuntime.Native.Graphics || {}; + localRuntime.Native.Graphics.Element = localRuntime.Native.Graphics.Element || {}; + if ('values' in localRuntime.Native.Graphics.Element) + { + return localRuntime.Native.Graphics.Element.values; + } - decodeTuple1: F2(decodeTuple1), - decodeTuple2: F3(decodeTuple2), - decodeTuple3: F4(decodeTuple3), - decodeTuple4: F5(decodeTuple4), - decodeTuple5: F6(decodeTuple5), - decodeTuple6: F7(decodeTuple6), - decodeTuple7: F8(decodeTuple7), - decodeTuple8: F9(decodeTuple8), + var Color = Elm.Native.Color.make(localRuntime); + var List = Elm.Native.List.make(localRuntime); + var Maybe = Elm.Maybe.make(localRuntime); + var Text = Elm.Native.Text.make(localRuntime); + var Utils = Elm.Native.Utils.make(localRuntime); - andThen: F2(andThen), - decodeValue: decodeValue, - customDecoder: F2(customDecoder), - fail: fail, - succeed: succeed, - identity: identity, - encodeNull: null, - encodeArray: ElmArray.toJSArray, - encodeList: List.toArray, - encodeObject: encodeObject + // CREATION - }; + var createNode = + typeof document === 'undefined' + ? + function(_) + { + return { + style: {}, + appendChild: function() {} + }; + } + : + function(elementType) + { + var node = document.createElement(elementType); + node.style.padding = '0'; + node.style.margin = '0'; + return node; + } + ; -}; -Elm.Native.List = {}; -Elm.Native.List.make = function(localRuntime) { - localRuntime.Native = localRuntime.Native || {}; - localRuntime.Native.List = localRuntime.Native.List || {}; - if (localRuntime.Native.List.values) - { - return localRuntime.Native.List.values; - } - if ('values' in Elm.Native.List) + function newElement(width, height, elementPrim) { - return localRuntime.Native.List.values = Elm.Native.List.values; + return { + ctor: 'Element_elm_builtin', + _0: { + element: elementPrim, + props: { + id: Utils.guid(), + width: width, + height: height, + opacity: 1, + color: Maybe.Nothing, + href: '', + tag: '', + hover: Utils.Tuple0, + click: Utils.Tuple0 + } + } + }; } - var Utils = Elm.Native.Utils.make(localRuntime); - var Nil = Utils.Nil; - var Cons = Utils.Cons; + // PROPERTIES - function toArray(xs) + function setProps(elem, node) { - var out = []; - while (xs.ctor !== '[]') + var props = elem.props; + + var element = elem.element; + var width = props.width - (element.adjustWidth || 0); + var height = props.height - (element.adjustHeight || 0); + node.style.width = (width | 0) + 'px'; + node.style.height = (height | 0) + 'px'; + + if (props.opacity !== 1) { - out.push(xs._0); - xs = xs._1; + node.style.opacity = props.opacity; } - return out; - } - function fromArray(arr) - { - var out = Nil; - for (var i = arr.length; i--; ) + if (props.color.ctor === 'Just') { - out = Cons(arr[i], out); + node.style.backgroundColor = Color.toCss(props.color._0); } - return out; - } - function range(lo,hi) - { - var lst = Nil; - if (lo <= hi) + if (props.tag !== '') { - do { lst = Cons(hi,lst) } while (hi-->lo); + node.id = props.tag; } - return lst - } - // f defined similarly for both foldl and foldr (NB: different from Haskell) - // ie, foldl : (a -> b -> b) -> b -> [a] -> b - function foldl(f, b, xs) - { - var acc = b; - while (xs.ctor !== '[]') + if (props.hover.ctor !== '_Tuple0') { - acc = A2(f, xs._0, acc); - xs = xs._1; + addHover(node, props.hover); } - return acc; - } - function foldr(f, b, xs) - { - var arr = toArray(xs); - var acc = b; - for (var i = arr.length; i--; ) + if (props.click.ctor !== '_Tuple0') { - acc = A2(f, arr[i], acc); + addClick(node, props.click); } - return acc; + + if (props.href !== '') + { + var anchor = createNode('a'); + anchor.href = props.href; + anchor.style.display = 'block'; + anchor.style.pointerEvents = 'auto'; + anchor.appendChild(node); + node = anchor; + } + + return node; } - function any(pred, xs) + function addClick(e, handler) { - while (xs.ctor !== '[]') + e.style.pointerEvents = 'auto'; + e.elm_click_handler = handler; + function trigger(ev) { - if (pred(xs._0)) - { - return true; - } - xs = xs._1; + e.elm_click_handler(Utils.Tuple0); + ev.stopPropagation(); } - return false; + e.elm_click_trigger = trigger; + e.addEventListener('click', trigger); } - function map2(f, xs, ys) + function removeClick(e, handler) { - var arr = []; - while (xs.ctor !== '[]' && ys.ctor !== '[]') + if (e.elm_click_trigger) { - arr.push(A2(f, xs._0, ys._0)); - xs = xs._1; - ys = ys._1; + e.removeEventListener('click', e.elm_click_trigger); + e.elm_click_trigger = null; + e.elm_click_handler = null; } - return fromArray(arr); } - function map3(f, xs, ys, zs) + function addHover(e, handler) { - var arr = []; - while (xs.ctor !== '[]' && ys.ctor !== '[]' && zs.ctor !== '[]') + e.style.pointerEvents = 'auto'; + e.elm_hover_handler = handler; + e.elm_hover_count = 0; + + function over(evt) { - arr.push(A3(f, xs._0, ys._0, zs._0)); - xs = xs._1; - ys = ys._1; - zs = zs._1; + if (e.elm_hover_count++ > 0) return; + e.elm_hover_handler(true); + evt.stopPropagation(); } - return fromArray(arr); + function out(evt) + { + if (e.contains(evt.toElement || evt.relatedTarget)) return; + e.elm_hover_count = 0; + e.elm_hover_handler(false); + evt.stopPropagation(); + } + e.elm_hover_over = over; + e.elm_hover_out = out; + e.addEventListener('mouseover', over); + e.addEventListener('mouseout', out); } - function map4(f, ws, xs, ys, zs) + function removeHover(e) { - var arr = []; - while ( ws.ctor !== '[]' - && xs.ctor !== '[]' - && ys.ctor !== '[]' - && zs.ctor !== '[]') + e.elm_hover_handler = null; + if (e.elm_hover_over) { - arr.push(A4(f, ws._0, xs._0, ys._0, zs._0)); - ws = ws._1; - xs = xs._1; - ys = ys._1; - zs = zs._1; + e.removeEventListener('mouseover', e.elm_hover_over); + e.elm_hover_over = null; + } + if (e.elm_hover_out) + { + e.removeEventListener('mouseout', e.elm_hover_out); + e.elm_hover_out = null; } - return fromArray(arr); } - function map5(f, vs, ws, xs, ys, zs) + + // IMAGES + + function image(props, img) { - var arr = []; - while ( vs.ctor !== '[]' - && ws.ctor !== '[]' - && xs.ctor !== '[]' - && ys.ctor !== '[]' - && zs.ctor !== '[]') + switch (img._0.ctor) { - arr.push(A5(f, vs._0, ws._0, xs._0, ys._0, zs._0)); - vs = vs._1; - ws = ws._1; - xs = xs._1; - ys = ys._1; - zs = zs._1; + case 'Plain': + return plainImage(img._3); + + case 'Fitted': + return fittedImage(props.width, props.height, img._3); + + case 'Cropped': + return croppedImage(img, props.width, props.height, img._3); + + case 'Tiled': + return tiledImage(img._3); } - return fromArray(arr); } - - function sortBy(f, xs) + + function plainImage(src) + { + var img = createNode('img'); + img.src = src; + img.name = src; + img.style.display = 'block'; + return img; + } + + function tiledImage(src) + { + var div = createNode('div'); + div.style.backgroundImage = 'url(' + src + ')'; + return div; + } + + function fittedImage(w, h, src) + { + var div = createNode('div'); + div.style.background = 'url(' + src + ') no-repeat center'; + div.style.webkitBackgroundSize = 'cover'; + div.style.MozBackgroundSize = 'cover'; + div.style.OBackgroundSize = 'cover'; + div.style.backgroundSize = 'cover'; + return div; + } + + function croppedImage(elem, w, h, src) + { + var pos = elem._0._0; + var e = createNode('div'); + e.style.overflow = 'hidden'; + + var img = createNode('img'); + img.onload = function() { + var sw = w / elem._1, sh = h / elem._2; + img.style.width = ((this.width * sw) | 0) + 'px'; + img.style.height = ((this.height * sh) | 0) + 'px'; + img.style.marginLeft = ((- pos._0 * sw) | 0) + 'px'; + img.style.marginTop = ((- pos._1 * sh) | 0) + 'px'; + }; + img.src = src; + img.name = src; + e.appendChild(img); + return e; + } + + + // FLOW + + function goOut(node) + { + node.style.position = 'absolute'; + return node; + } + function goDown(node) + { + return node; + } + function goRight(node) { - return fromArray(toArray(xs).sort(function(a,b){ - return Utils.cmp(f(a), f(b)); - })); + node.style.styleFloat = 'left'; + node.style.cssFloat = 'left'; + return node; } - function sortWith(f, xs) + var directionTable = { + DUp: goDown, + DDown: goDown, + DLeft: goRight, + DRight: goRight, + DIn: goOut, + DOut: goOut + }; + function needsReversal(dir) { - return fromArray(toArray(xs).sort(function(a,b){ - var ord = f(a)(b).ctor; - return ord === 'EQ' ? 0 : ord === 'LT' ? -1 : 1; - })); + return dir === 'DUp' || dir === 'DLeft' || dir === 'DIn'; } - function take(n, xs) + function flow(dir, elist) { - var arr = []; - while (xs.ctor !== '[]' && n > 0) + var array = List.toArray(elist); + var container = createNode('div'); + var goDir = directionTable[dir]; + if (goDir === goOut) { - arr.push(xs._0); - xs = xs._1; - --n; + container.style.pointerEvents = 'none'; } - return fromArray(arr); - } - - function drop(n, xs) - { - while (xs.ctor !== '[]' && n > 0) + if (needsReversal(dir)) { - xs = xs._1; - --n; + array.reverse(); } - return xs; - } - - function repeat(n, x) - { - var arr = []; - var pattern = [x]; - while (n > 0) + var len = array.length; + for (var i = 0; i < len; ++i) { - if (n & 1) - { - arr = arr.concat(pattern); - } - n >>= 1, pattern = pattern.concat(pattern); + container.appendChild(goDir(render(array[i]))); } - return fromArray(arr); + return container; } - Elm.Native.List.values = { - Nil:Nil, - Cons:Cons, - cons:F2(Cons), - toArray:toArray, - fromArray:fromArray, - range:range, - - foldl:F3(foldl), - foldr:F3(foldr), - - any:F2(any), - map2:F3(map2), - map3:F4(map3), - map4:F5(map4), - map5:F6(map5), - sortBy:F2(sortBy), - sortWith:F2(sortWith), - take:F2(take), - drop:F2(drop), - repeat:F2(repeat) - }; - return localRuntime.Native.List.values = Elm.Native.List.values; - -}; - -Elm.Native.Port = {}; -Elm.Native.Port.make = function(localRuntime) { + // CONTAINER - localRuntime.Native = localRuntime.Native || {}; - localRuntime.Native.Port = localRuntime.Native.Port || {}; - if (localRuntime.Native.Port.values) + function toPos(pos) { - return localRuntime.Native.Port.values; + return pos.ctor === 'Absolute' + ? pos._0 + 'px' + : (pos._0 * 100) + '%'; } - var NS; - var Utils = Elm.Native.Utils.make(localRuntime); - - - // INBOUND - - function inbound(name, type, converter) + // must clear right, left, top, bottom, and transform + // before calling this function + function setPos(pos, wrappedElement, e) { - if (!localRuntime.argsTracker[name]) - { - throw new Error( - "Port Error:\n" + - "No argument was given for the port named '" + name + "' with type:\n\n" + - " " + type.split('\n').join('\n ') + "\n\n" + - "You need to provide an initial value!\n\n" + - "Find out more about ports here " - ); - } - var arg = localRuntime.argsTracker[name]; - arg.used = true; + var elem = wrappedElement._0; + var element = elem.element; + var props = elem.props; + var w = props.width + (element.adjustWidth ? element.adjustWidth : 0); + var h = props.height + (element.adjustHeight ? element.adjustHeight : 0); - return jsToElm(name, type, converter, arg.value); - } + e.style.position = 'absolute'; + e.style.margin = 'auto'; + var transform = ''; + switch (pos.horizontal.ctor) + { + case 'P': + e.style.right = toPos(pos.x); + e.style.removeProperty('left'); + break; - function inboundSignal(name, type, converter) - { - var initialValue = inbound(name, type, converter); + case 'Z': + transform = 'translateX(' + ((-w / 2) | 0) + 'px) '; - if (!NS) - { - NS = Elm.Native.Signal.make(localRuntime); + case 'N': + e.style.left = toPos(pos.x); + e.style.removeProperty('right'); + break; } - var signal = NS.input('inbound-port-' + name, initialValue); - - function send(jsValue) + switch (pos.vertical.ctor) { - var elmValue = jsToElm(name, type, converter, jsValue); - setTimeout(function() { - localRuntime.notify(signal.id, elmValue); - }, 0); - } - - localRuntime.ports[name] = { send: send }; - - return signal; - } + case 'N': + e.style.bottom = toPos(pos.y); + e.style.removeProperty('top'); + break; + case 'Z': + transform += 'translateY(' + ((-h / 2) | 0) + 'px)'; - function jsToElm(name, type, converter, value) - { - try - { - return converter(value); + case 'P': + e.style.top = toPos(pos.y); + e.style.removeProperty('bottom'); + break; } - catch(e) + if (transform !== '') { - throw new Error( - "Port Error:\n" + - "Regarding the port named '" + name + "' with type:\n\n" + - " " + type.split('\n').join('\n ') + "\n\n" + - "You just sent the value:\n\n" + - " " + JSON.stringify(value) + "\n\n" + - "but it cannot be converted to the necessary type.\n" + - e.message - ); + addTransform(e.style, transform); } + return e; } + function addTransform(style, transform) + { + style.transform = transform; + style.msTransform = transform; + style.MozTransform = transform; + style.webkitTransform = transform; + style.OTransform = transform; + } - // OUTBOUND - - function outbound(name, converter, elmValue) + function container(pos, elem) { - localRuntime.ports[name] = converter(elmValue); + var e = render(elem); + setPos(pos, elem, e); + var div = createNode('div'); + div.style.position = 'relative'; + div.style.overflow = 'hidden'; + div.appendChild(e); + return div; } - function outboundSignal(name, converter, signal) + function rawHtml(elem) { - var subscribers = []; - - function subscribe(handler) - { - subscribers.push(handler); - } - function unsubscribe(handler) - { - subscribers.pop(subscribers.indexOf(handler)); - } + var html = elem.html; + var align = elem.align; - function notify(elmValue) + var div = createNode('div'); + div.innerHTML = html; + div.style.visibility = 'hidden'; + if (align) { - var jsValue = converter(elmValue); - var len = subscribers.length; - for (var i = 0; i < len; ++i) - { - subscribers[i](jsValue); - } + div.style.textAlign = align; } + div.style.visibility = 'visible'; + div.style.pointerEvents = 'auto'; + return div; + } - if (!NS) - { - NS = Elm.Native.Signal.make(localRuntime); - } - NS.output('outbound-port-' + name, notify, signal); - localRuntime.ports[name] = { - subscribe: subscribe, - unsubscribe: unsubscribe - }; + // RENDER - return signal; + function render(wrappedElement) + { + var elem = wrappedElement._0; + return setProps(elem, makeElement(elem)); } + function makeElement(e) + { + var elem = e.element; + switch (elem.ctor) + { + case 'Image': + return image(e.props, elem); - return localRuntime.Native.Port.values = { - inbound: inbound, - outbound: outbound, - inboundSignal: inboundSignal, - outboundSignal: outboundSignal - }; -}; + case 'Flow': + return flow(elem._0.ctor, elem._1); + case 'Container': + return container(elem._0, elem._1); -if (!Elm.fullscreen) { + case 'Spacer': + return createNode('div'); - (function() { - 'use strict'; + case 'RawHtml': + return rawHtml(elem); - var Display = { - FULLSCREEN: 0, - COMPONENT: 1, - NONE: 2 - }; + case 'Custom': + return elem.render(elem.model); + } + } - Elm.fullscreen = function(module, args) + function updateAndReplace(node, curr, next) + { + var newNode = update(node, curr, next); + if (newNode !== node) { - var container = document.createElement('div'); - document.body.appendChild(container); - return init(Display.FULLSCREEN, container, module, args || {}); - }; + node.parentNode.replaceChild(newNode, node); + } + return newNode; + } - Elm.embed = function(module, container, args) - { - var tag = container.tagName; - if (tag !== 'DIV') - { - throw new Error('Elm.node must be given a DIV, not a ' + tag + '.'); - } - return init(Display.COMPONENT, container, module, args || {}); - }; - Elm.worker = function(module, args) - { - return init(Display.NONE, {}, module, args || {}); - }; + // UPDATE - function init(display, container, module, args, moduleToReplace) + function update(node, wrappedCurrent, wrappedNext) + { + var curr = wrappedCurrent._0; + var next = wrappedNext._0; + var rootNode = node; + if (node.tagName === 'A') { - // defining state needed for an instance of the Elm RTS - var inputs = []; + node = node.firstChild; + } + if (curr.props.id === next.props.id) + { + updateProps(node, curr, next); + return rootNode; + } + if (curr.element.ctor !== next.element.ctor) + { + return render(wrappedNext); + } + var nextE = next.element; + var currE = curr.element; + switch (nextE.ctor) + { + case 'Spacer': + updateProps(node, curr, next); + return rootNode; - /* OFFSET - * Elm's time traveling debugger lets you pause time. This means - * "now" may be shifted a bit into the past. By wrapping Date.now() - * we can manage this. - */ - var timer = { - programStart: Date.now(), - now: function() + case 'RawHtml': + if(currE.html.valueOf() !== nextE.html.valueOf()) { - return Date.now(); + node.innerHTML = nextE.html; } - }; + updateProps(node, curr, next); + return rootNode; - var updateInProgress = false; - function notify(id, v) - { - if (updateInProgress) + case 'Image': + if (nextE._0.ctor === 'Plain') { - throw new Error( - 'The notify function has been called synchronously!\n' + - 'This can lead to frames being dropped.\n' + - 'Definitely report this to \n'); + if (nextE._3 !== currE._3) + { + node.src = nextE._3; + } } - updateInProgress = true; - var timestep = timer.now(); - for (var i = inputs.length; i--; ) + else if (!Utils.eq(nextE, currE) + || next.props.width !== curr.props.width + || next.props.height !== curr.props.height) { - inputs[i].notify(timestep, id, v); + return render(wrappedNext); } - updateInProgress = false; - } - function setTimeout(func, delay) - { - return window.setTimeout(func, delay); - } - - var listeners = []; - function addListener(relevantInputs, domNode, eventName, func) - { - domNode.addEventListener(eventName, func); - var listener = { - relevantInputs: relevantInputs, - domNode: domNode, - eventName: eventName, - func: func - }; - listeners.push(listener); - } - - var argsTracker = {}; - for (var name in args) - { - argsTracker[name] = { - value: args[name], - used: false - }; - } - - // create the actual RTS. Any impure modules will attach themselves to this - // object. This permits many Elm programs to be embedded per document. - var elm = { - notify: notify, - setTimeout: setTimeout, - node: container, - addListener: addListener, - inputs: inputs, - timer: timer, - argsTracker: argsTracker, - ports: {}, - - isFullscreen: function() { return display === Display.FULLSCREEN; }, - isEmbed: function() { return display === Display.COMPONENT; }, - isWorker: function() { return display === Display.NONE; } - }; - - function swap(newModule) - { - removeListeners(listeners); - var div = document.createElement('div'); - var newElm = init(display, div, newModule, args, elm); - inputs = []; - // elm.swap = newElm.swap; - return newElm; - } - - function dispose() - { - removeListeners(listeners); - inputs = []; - } + updateProps(node, curr, next); + return rootNode; - var Module = {}; - try - { - Module = module.make(elm); - checkInputs(elm); - } - catch (error) - { - if (typeof container.appendChild == 'undefined') + case 'Flow': + var arr = List.toArray(nextE._1); + for (var i = arr.length; i--; ) { - console.log(error.message); + arr[i] = arr[i]._0.element.ctor; } - else + if (nextE._0.ctor !== currE._0.ctor) { - container.appendChild(errorNode(error.message)); + return render(wrappedNext); } - throw error; - } + var nexts = List.toArray(nextE._1); + var kids = node.childNodes; + if (nexts.length !== kids.length) + { + return render(wrappedNext); + } + var currs = List.toArray(currE._1); + var dir = nextE._0.ctor; + var goDir = directionTable[dir]; + var toReverse = needsReversal(dir); + var len = kids.length; + for (var i = len; i--; ) + { + var subNode = kids[toReverse ? len - i - 1 : i]; + goDir(updateAndReplace(subNode, currs[i], nexts[i])); + } + updateProps(node, curr, next); + return rootNode; - if (display !== Display.NONE) - { - var graphicsNode = initGraphics(elm, Module); - } + case 'Container': + var subNode = node.firstChild; + var newSubNode = updateAndReplace(subNode, currE._1, nextE._1); + setPos(nextE._0, nextE._1, newSubNode); + updateProps(node, curr, next); + return rootNode; - var rootNode = { kids: inputs }; - trimDeadNodes(rootNode); - inputs = rootNode.kids; - filterListeners(inputs, listeners); + case 'Custom': + if (currE.type === nextE.type) + { + var updatedNode = nextE.update(node, currE.model, nextE.model); + updateProps(updatedNode, curr, next); + return updatedNode; + } + return render(wrappedNext); + } + } - addReceivers(elm.ports); + function updateProps(node, curr, next) + { + var nextProps = next.props; + var currProps = curr.props; - if (typeof moduleToReplace !== 'undefined') - { - hotSwap(moduleToReplace, elm); + var element = next.element; + var width = nextProps.width - (element.adjustWidth || 0); + var height = nextProps.height - (element.adjustHeight || 0); + if (width !== currProps.width) + { + node.style.width = (width | 0) + 'px'; + } + if (height !== currProps.height) + { + node.style.height = (height | 0) + 'px'; + } - // rerender scene if graphics are enabled. - if (typeof graphicsNode !== 'undefined') - { - graphicsNode.notify(0, true, 0); - } - } + if (nextProps.opacity !== currProps.opacity) + { + node.style.opacity = nextProps.opacity; + } - return { - swap: swap, - ports: elm.ports, - dispose: dispose - }; - }; + var nextColor = nextProps.color.ctor === 'Just' + ? Color.toCss(nextProps.color._0) + : ''; + if (node.style.backgroundColor !== nextColor) + { + node.style.backgroundColor = nextColor; + } - function checkInputs(elm) + if (nextProps.tag !== currProps.tag) { - var argsTracker = elm.argsTracker; - for (var name in argsTracker) - { - if (!argsTracker[name].used) - { - throw new Error( - "Port Error:\nYou provided an argument named '" + name + - "' but there is no corresponding port!\n\n" + - "Maybe add a port '" + name + "' to your Elm module?\n" + - "Maybe remove the '" + name + "' argument from your initialization code in JS?" - ); - } - } + node.id = nextProps.tag; } - function errorNode(message) + if (nextProps.href !== currProps.href) { - var code = document.createElement('code'); + if (currProps.href === '') + { + // add a surrounding href + var anchor = createNode('a'); + anchor.href = nextProps.href; + anchor.style.display = 'block'; + anchor.style.pointerEvents = 'auto'; - var lines = message.split('\n'); - code.appendChild(document.createTextNode(lines[0])); - code.appendChild(document.createElement('br')); - code.appendChild(document.createElement('br')); - for (var i = 1; i < lines.length; ++i) + node.parentNode.replaceChild(anchor, node); + anchor.appendChild(node); + } + else if (nextProps.href === '') + { + // remove the surrounding href + var anchor = node.parentNode; + anchor.parentNode.replaceChild(node, anchor); + } + else { - code.appendChild(document.createTextNode('\u00A0 \u00A0 ' + lines[i].replace(/ /g, '\u00A0 '))); - code.appendChild(document.createElement('br')); + // just update the link + node.parentNode.href = nextProps.href; } - code.appendChild(document.createElement('br')); - code.appendChild(document.createTextNode("Open the developer console for more details.")); - return code; } + // update click and hover handlers + var removed = false; - //// FILTER SIGNALS //// - - // TODO: move this code into the signal module and create a function - // Signal.initializeGraph that actually instantiates everything. - - function filterListeners(inputs, listeners) + // update hover handlers + if (currProps.hover.ctor === '_Tuple0') { - loop: - for (var i = listeners.length; i--; ) + if (nextProps.hover.ctor !== '_Tuple0') { - var listener = listeners[i]; - for (var j = inputs.length; j--; ) - { - if (listener.relevantInputs.indexOf(inputs[j].id) >= 0) - { - continue loop; - } - } - listener.domNode.removeEventListener(listener.eventName, listener.func); + addHover(node, nextProps.hover); } } - - function removeListeners(listeners) + else { - for (var i = listeners.length; i--; ) + if (nextProps.hover.ctor === '_Tuple0') { - var listener = listeners[i]; - listener.domNode.removeEventListener(listener.eventName, listener.func); + removed = true; + removeHover(node); + } + else + { + node.elm_hover_handler = nextProps.hover; } } - // add receivers for built-in ports if they are defined - function addReceivers(ports) + // update click handlers + if (currProps.click.ctor === '_Tuple0') { - if ('title' in ports) - { - if (typeof ports.title === 'string') - { - document.title = ports.title; - } - else - { - ports.title.subscribe(function(v) { document.title = v; }); - } - } - if ('redirect' in ports) + if (nextProps.click.ctor !== '_Tuple0') { - ports.redirect.subscribe(function(v) { - if (v.length > 0) - { - window.location = v; - } - }); + addClick(node, nextProps.click); } } - - - // returns a boolean representing whether the node is alive or not. - function trimDeadNodes(node) + else { - if (node.isOutput) + if (nextProps.click.ctor === '_Tuple0') { - return true; + removed = true; + removeClick(node); } - - var liveKids = []; - for (var i = node.kids.length; i--; ) + else { - var kid = node.kids[i]; - if (trimDeadNodes(kid)) - { - liveKids.push(kid); - } + node.elm_click_handler = nextProps.click; } - node.kids = liveKids; + } - return liveKids.length > 0; + // stop capturing clicks if + if (removed + && nextProps.hover.ctor === '_Tuple0' + && nextProps.click.ctor === '_Tuple0') + { + node.style.pointerEvents = 'none'; } + } - //// RENDERING //// + // TEXT - function initGraphics(elm, Module) + function block(align) + { + return function(text) { - if (!('main' in Module)) - { - throw new Error("'main' is missing! What do I display?!"); - } + var raw = { + ctor: 'RawHtml', + html: Text.renderHtml(text), + align: align + }; + var pos = htmlHeight(0, raw); + return newElement(pos._0, pos._1, raw); + }; + } - var signalGraph = Module.main; + function markdown(text) + { + var raw = { + ctor: 'RawHtml', + html: text, + align: null + }; + var pos = htmlHeight(0, raw); + return newElement(pos._0, pos._1, raw); + } - // make sure the signal graph is actually a signal & extract the visual model - if (!('notify' in signalGraph)) - { - signalGraph = Elm.Signal.make(elm).constant(signalGraph); - } - var initialScene = signalGraph.value; + var htmlHeight = + typeof document !== 'undefined' + ? realHtmlHeight + : function(a, b) { return Utils.Tuple2(0, 0); }; - // Figure out what the render functions should be - var render; - var update; - if (initialScene.props) - { - var Element = Elm.Native.Graphics.Element.make(elm); - render = Element.render; - update = Element.updateAndReplace; - } - else - { - var VirtualDom = Elm.Native.VirtualDom.make(elm); - render = VirtualDom.render; - update = VirtualDom.updateAndReplace; - } + function realHtmlHeight(width, rawHtml) + { + // create dummy node + var temp = document.createElement('div'); + temp.innerHTML = rawHtml.html; + if (width > 0) + { + temp.style.width = width + 'px'; + } + temp.style.visibility = 'hidden'; + temp.style.styleFloat = 'left'; + temp.style.cssFloat = 'left'; - // Add the initialScene to the DOM - var container = elm.node; - var node = render(initialScene); - while (container.firstChild) - { - container.removeChild(container.firstChild); - } - container.appendChild(node); + document.body.appendChild(temp); - var _requestAnimationFrame = - typeof requestAnimationFrame !== 'undefined' - ? requestAnimationFrame - : function(cb) { setTimeout(cb, 1000/60); } - ; + // get dimensions + var style = window.getComputedStyle(temp, null); + var w = Math.ceil(style.getPropertyValue('width').slice(0, -2) - 0); + var h = Math.ceil(style.getPropertyValue('height').slice(0, -2) - 0); + document.body.removeChild(temp); + return Utils.Tuple2(w, h); + } - // domUpdate is called whenever the main Signal changes. - // - // domUpdate and drawCallback implement a small state machine in order - // to schedule only 1 draw per animation frame. This enforces that - // once draw has been called, it will not be called again until the - // next frame. - // - // drawCallback is scheduled whenever - // 1. The state transitions from PENDING_REQUEST to EXTRA_REQUEST, or - // 2. The state transitions from NO_REQUEST to PENDING_REQUEST - // - // Invariants: - // 1. In the NO_REQUEST state, there is never a scheduled drawCallback. - // 2. In the PENDING_REQUEST and EXTRA_REQUEST states, there is always exactly 1 - // scheduled drawCallback. - var NO_REQUEST = 0; - var PENDING_REQUEST = 1; - var EXTRA_REQUEST = 2; - var state = NO_REQUEST; - var savedScene = initialScene; - var scheduledScene = initialScene; - function domUpdate(newScene) - { - scheduledScene = newScene; + return localRuntime.Native.Graphics.Element.values = { + render: render, + update: update, + updateAndReplace: updateAndReplace, - switch (state) - { - case NO_REQUEST: - _requestAnimationFrame(drawCallback); - state = PENDING_REQUEST; - return; - case PENDING_REQUEST: - state = PENDING_REQUEST; - return; - case EXTRA_REQUEST: - state = PENDING_REQUEST; - return; - } - } + createNode: createNode, + newElement: F3(newElement), + addTransform: addTransform, + htmlHeight: F2(htmlHeight), + guid: Utils.guid, - function drawCallback() - { - switch (state) - { - case NO_REQUEST: - // This state should not be possible. How can there be no - // request, yet somehow we are actively fulfilling a - // request? - throw new Error( - "Unexpected draw callback.\n" + - "Please report this to ." - ); + block: block, + markdown: markdown + }; +}; - case PENDING_REQUEST: - // At this point, we do not *know* that another frame is - // needed, but we make an extra request to rAF just in - // case. It's possible to drop a frame if rAF is called - // too late, so we just do it preemptively. - _requestAnimationFrame(drawCallback); - state = EXTRA_REQUEST; +Elm.Native.Text = {}; +Elm.Native.Text.make = function(localRuntime) { + localRuntime.Native = localRuntime.Native || {}; + localRuntime.Native.Text = localRuntime.Native.Text || {}; + if (localRuntime.Native.Text.values) + { + return localRuntime.Native.Text.values; + } + + var toCss = Elm.Native.Color.make(localRuntime).toCss; + var List = Elm.Native.List.make(localRuntime); + + + // CONSTRUCTORS + + function fromString(str) + { + return { + ctor: 'Text:Text', + _0: str + }; + } - // There's also stuff we definitely need to draw. - draw(); - return; + function append(a, b) + { + return { + ctor: 'Text:Append', + _0: a, + _1: b + }; + } - case EXTRA_REQUEST: - // Turns out the extra request was not needed, so we will - // stop calling rAF. No reason to call it all the time if - // no one needs it. - state = NO_REQUEST; - return; - } - } + function addMeta(field, value, text) + { + var newProps = {}; + var newText = { + ctor: 'Text:Meta', + _0: newProps, + _1: text + }; - function draw() + if (text.ctor === 'Text:Meta') + { + newText._1 = text._1; + var props = text._0; + for (var i = metaKeys.length; i--; ) { - update(elm.node.firstChild, savedScene, scheduledScene); - if (elm.Native.Window) + var key = metaKeys[i]; + var val = props[key]; + if (val) { - elm.Native.Window.values.resizeIfNeeded(); + newProps[key] = val; } - savedScene = scheduledScene; } + } + newProps[field] = value; + return newText; + } - var renderer = Elm.Native.Signal.make(elm).output('main', domUpdate, signalGraph); + var metaKeys = [ + 'font-size', + 'font-family', + 'font-style', + 'font-weight', + 'href', + 'text-decoration', + 'color' + ]; - // must check for resize after 'renderer' is created so - // that changes show up. - if (elm.Native.Window) + + // conversions from Elm values to CSS + + function toTypefaces(list) + { + var typefaces = List.toArray(list); + for (var i = typefaces.length; i--; ) + { + var typeface = typefaces[i]; + if (typeface.indexOf(' ') > -1) { - elm.Native.Window.values.resizeIfNeeded(); + typefaces[i] = "'" + typeface + "'"; } + } + return typefaces.join(','); + } - return renderer; + function toLine(line) + { + var ctor = line.ctor; + return ctor === 'Under' + ? 'underline' + : ctor === 'Over' + ? 'overline' + : 'line-through'; + } + + // setting styles of Text + + function style(style, text) + { + var newText = addMeta('color', toCss(style.color), text); + var props = newText._0; + + if (style.typeface.ctor !== '[]') + { + props['font-family'] = toTypefaces(style.typeface); + } + if (style.height.ctor !== 'Nothing') + { + props['font-size'] = style.height._0 + 'px'; + } + if (style.bold) + { + props['font-weight'] = 'bold'; + } + if (style.italic) + { + props['font-style'] = 'italic'; + } + if (style.line.ctor !== 'Nothing') + { + props['text-decoration'] = toLine(style.line._0); } + return newText; + } - //// HOT SWAPPING //// + function height(px, text) + { + return addMeta('font-size', px + 'px', text); + } - // Returns boolean indicating if the swap was successful. - // Requires that the two signal graphs have exactly the same - // structure. - function hotSwap(from, to) + function typeface(names, text) + { + return addMeta('font-family', toTypefaces(names), text); + } + + function monospace(text) + { + return addMeta('font-family', 'monospace', text); + } + + function italic(text) + { + return addMeta('font-style', 'italic', text); + } + + function bold(text) + { + return addMeta('font-weight', 'bold', text); + } + + function link(href, text) + { + return addMeta('href', href, text); + } + + function line(line, text) + { + return addMeta('text-decoration', toLine(line), text); + } + + function color(color, text) + { + return addMeta('color', toCss(color), text); + } + + + // RENDER + + function renderHtml(text) + { + var tag = text.ctor; + if (tag === 'Text:Append') { - function similar(nodeOld,nodeNew) - { - if (nodeOld.id !== nodeNew.id) - { - return false; - } - if (nodeOld.isOutput) - { - return nodeNew.isOutput; - } - return nodeOld.kids.length === nodeNew.kids.length; - } - function swap(nodeOld,nodeNew) - { - nodeNew.value = nodeOld.value; - return true; - } - var canSwap = depthFirstTraversals(similar, from.inputs, to.inputs); - if (canSwap) + return renderHtml(text._0) + renderHtml(text._1); + } + if (tag === 'Text:Text') + { + return properEscape(text._0); + } + if (tag === 'Text:Meta') + { + return renderMeta(text._0, renderHtml(text._1)); + } + } + + function renderMeta(metas, string) + { + var href = metas.href; + if (href) + { + string = '' + string + ''; + } + var styles = ''; + for (var key in metas) + { + if (key === 'href') { - depthFirstTraversals(swap, from.inputs, to.inputs); + continue; } - from.node.parentNode.replaceChild(to.node, from.node); + styles += key + ':' + metas[key] + ';'; + } + if (styles) + { + string = '' + string + ''; + } + return string; + } - return canSwap; + function properEscape(str) + { + if (str.length === 0) + { + return str; + } + str = str //.replace(/&/g, '&') + .replace(/"/g, '"') + .replace(/'/g, ''') + .replace(//g, '>'); + var arr = str.split('\n'); + for (var i = arr.length; i--; ) + { + arr[i] = makeSpaces(arr[i]); } + return arr.join('
'); + } - // Returns false if the node operation f ever fails. - function depthFirstTraversals(f, queueOld, queueNew) + function makeSpaces(s) + { + if (s.length === 0) { - if (queueOld.length !== queueNew.length) + return s; + } + var arr = s.split(''); + if (arr[0] === ' ') + { + arr[0] = ' '; + } + for (var i = arr.length; --i; ) + { + if (arr[i][0] === ' ' && arr[i - 1] === ' ') { - return false; + arr[i - 1] = arr[i - 1] + arr[i]; + arr[i] = ''; } - queueOld = queueOld.slice(0); - queueNew = queueNew.slice(0); - - var seen = []; - while (queueOld.length > 0 && queueNew.length > 0) + } + for (var i = arr.length; i--; ) + { + if (arr[i].length > 1 && arr[i][0] === ' ') { - var nodeOld = queueOld.pop(); - var nodeNew = queueNew.pop(); - if (seen.indexOf(nodeOld.id) < 0) + var spaces = arr[i].split(''); + for (var j = spaces.length - 2; j >= 0; j -= 2) { - if (!f(nodeOld, nodeNew)) - { - return false; - } - queueOld = queueOld.concat(nodeOld.kids || []); - queueNew = queueNew.concat(nodeNew.kids || []); - seen.push(nodeOld.id); + spaces[j] = ' '; } + arr[i] = spaces.join(''); } - return true; } - }()); - - function F2(fun) - { - function wrapper(a) { return function(b) { return fun(a,b) } } - wrapper.arity = 2; - wrapper.func = fun; - return wrapper; - } - - function F3(fun) - { - function wrapper(a) { - return function(b) { return function(c) { return fun(a,b,c) }} + arr = arr.join(''); + if (arr[arr.length - 1] === ' ') + { + return arr.slice(0, -1) + ' '; } - wrapper.arity = 3; - wrapper.func = fun; - return wrapper; + return arr; } - function F4(fun) + + return localRuntime.Native.Text.values = { + fromString: fromString, + append: F2(append), + + height: F2(height), + italic: italic, + bold: bold, + line: F2(line), + monospace: monospace, + typeface: F2(typeface), + color: F2(color), + link: F2(link), + style: F2(style), + + toTypefaces: toTypefaces, + toLine: toLine, + renderHtml: renderHtml + }; +}; + +Elm.Text = Elm.Text || {}; +Elm.Text.make = function (_elm) { + "use strict"; + _elm.Text = _elm.Text || {}; + if (_elm.Text.values) return _elm.Text.values; + var _U = Elm.Native.Utils.make(_elm), + $Color = Elm.Color.make(_elm), + $List = Elm.List.make(_elm), + $Maybe = Elm.Maybe.make(_elm), + $Native$Text = Elm.Native.Text.make(_elm); + var _op = {}; + var line = $Native$Text.line; + var italic = $Native$Text.italic; + var bold = $Native$Text.bold; + var color = $Native$Text.color; + var height = $Native$Text.height; + var link = $Native$Text.link; + var monospace = $Native$Text.monospace; + var typeface = $Native$Text.typeface; + var style = $Native$Text.style; + var append = $Native$Text.append; + var fromString = $Native$Text.fromString; + var empty = fromString(""); + var concat = function (texts) { return A3($List.foldr,append,empty,texts);}; + var join = F2(function (seperator,texts) { return concat(A2($List.intersperse,seperator,texts));}); + var defaultStyle = {typeface: _U.list([]),height: $Maybe.Nothing,color: $Color.black,bold: false,italic: false,line: $Maybe.Nothing}; + var Style = F6(function (a,b,c,d,e,f) { return {typeface: a,height: b,color: c,bold: d,italic: e,line: f};}); + var Through = {ctor: "Through"}; + var Over = {ctor: "Over"}; + var Under = {ctor: "Under"}; + var Text = {ctor: "Text"}; + return _elm.Text.values = {_op: _op + ,fromString: fromString + ,empty: empty + ,append: append + ,concat: concat + ,join: join + ,link: link + ,style: style + ,defaultStyle: defaultStyle + ,typeface: typeface + ,monospace: monospace + ,height: height + ,color: color + ,bold: bold + ,italic: italic + ,line: line + ,Style: Style + ,Under: Under + ,Over: Over + ,Through: Through}; +}; +Elm.Graphics = Elm.Graphics || {}; +Elm.Graphics.Element = Elm.Graphics.Element || {}; +Elm.Graphics.Element.make = function (_elm) { + "use strict"; + _elm.Graphics = _elm.Graphics || {}; + _elm.Graphics.Element = _elm.Graphics.Element || {}; + if (_elm.Graphics.Element.values) return _elm.Graphics.Element.values; + var _U = Elm.Native.Utils.make(_elm), + $Basics = Elm.Basics.make(_elm), + $Color = Elm.Color.make(_elm), + $List = Elm.List.make(_elm), + $Maybe = Elm.Maybe.make(_elm), + $Native$Graphics$Element = Elm.Native.Graphics.Element.make(_elm), + $Text = Elm.Text.make(_elm); + var _op = {}; + var DOut = {ctor: "DOut"}; + var outward = DOut; + var DIn = {ctor: "DIn"}; + var inward = DIn; + var DRight = {ctor: "DRight"}; + var right = DRight; + var DLeft = {ctor: "DLeft"}; + var left = DLeft; + var DDown = {ctor: "DDown"}; + var down = DDown; + var DUp = {ctor: "DUp"}; + var up = DUp; + var RawPosition = F4(function (a,b,c,d) { return {horizontal: a,vertical: b,x: c,y: d};}); + var Position = function (a) { return {ctor: "Position",_0: a};}; + var Relative = function (a) { return {ctor: "Relative",_0: a};}; + var relative = Relative; + var Absolute = function (a) { return {ctor: "Absolute",_0: a};}; + var absolute = Absolute; + var N = {ctor: "N"}; + var bottomLeft = Position({horizontal: N,vertical: N,x: Absolute(0),y: Absolute(0)}); + var bottomLeftAt = F2(function (x,y) { return Position({horizontal: N,vertical: N,x: x,y: y});}); + var Z = {ctor: "Z"}; + var middle = Position({horizontal: Z,vertical: Z,x: Relative(0.5),y: Relative(0.5)}); + var midLeft = Position({horizontal: N,vertical: Z,x: Absolute(0),y: Relative(0.5)}); + var midBottom = Position({horizontal: Z,vertical: N,x: Relative(0.5),y: Absolute(0)}); + var middleAt = F2(function (x,y) { return Position({horizontal: Z,vertical: Z,x: x,y: y});}); + var midLeftAt = F2(function (x,y) { return Position({horizontal: N,vertical: Z,x: x,y: y});}); + var midBottomAt = F2(function (x,y) { return Position({horizontal: Z,vertical: N,x: x,y: y});}); + var P = {ctor: "P"}; + var topLeft = Position({horizontal: N,vertical: P,x: Absolute(0),y: Absolute(0)}); + var topRight = Position({horizontal: P,vertical: P,x: Absolute(0),y: Absolute(0)}); + var bottomRight = Position({horizontal: P,vertical: N,x: Absolute(0),y: Absolute(0)}); + var midRight = Position({horizontal: P,vertical: Z,x: Absolute(0),y: Relative(0.5)}); + var midTop = Position({horizontal: Z,vertical: P,x: Relative(0.5),y: Absolute(0)}); + var topLeftAt = F2(function (x,y) { return Position({horizontal: N,vertical: P,x: x,y: y});}); + var topRightAt = F2(function (x,y) { return Position({horizontal: P,vertical: P,x: x,y: y});}); + var bottomRightAt = F2(function (x,y) { return Position({horizontal: P,vertical: N,x: x,y: y});}); + var midRightAt = F2(function (x,y) { return Position({horizontal: P,vertical: Z,x: x,y: y});}); + var midTopAt = F2(function (x,y) { return Position({horizontal: Z,vertical: P,x: x,y: y});}); + var justified = $Native$Graphics$Element.block("justify"); + var centered = $Native$Graphics$Element.block("center"); + var rightAligned = $Native$Graphics$Element.block("right"); + var leftAligned = $Native$Graphics$Element.block("left"); + var show = function (value) { return leftAligned($Text.monospace($Text.fromString($Basics.toString(value))));}; + var Tiled = {ctor: "Tiled"}; + var Cropped = function (a) { return {ctor: "Cropped",_0: a};}; + var Fitted = {ctor: "Fitted"}; + var Plain = {ctor: "Plain"}; + var Custom = {ctor: "Custom"}; + var RawHtml = {ctor: "RawHtml"}; + var Spacer = {ctor: "Spacer"}; + var Flow = F2(function (a,b) { return {ctor: "Flow",_0: a,_1: b};}); + var Container = F2(function (a,b) { return {ctor: "Container",_0: a,_1: b};}); + var Image = F4(function (a,b,c,d) { return {ctor: "Image",_0: a,_1: b,_2: c,_3: d};}); + var newElement = $Native$Graphics$Element.newElement; + var image = F3(function (w,h,src) { return A3(newElement,w,h,A4(Image,Plain,w,h,src));}); + var fittedImage = F3(function (w,h,src) { return A3(newElement,w,h,A4(Image,Fitted,w,h,src));}); + var croppedImage = F4(function (pos,w,h,src) { return A3(newElement,w,h,A4(Image,Cropped(pos),w,h,src));}); + var tiledImage = F3(function (w,h,src) { return A3(newElement,w,h,A4(Image,Tiled,w,h,src));}); + var container = F4(function (w,h,_p0,e) { var _p1 = _p0;return A3(newElement,w,h,A2(Container,_p1._0,e));}); + var spacer = F2(function (w,h) { return A3(newElement,w,h,Spacer);}); + var sizeOf = function (_p2) { var _p3 = _p2;var _p4 = _p3._0;return {ctor: "_Tuple2",_0: _p4.props.width,_1: _p4.props.height};}; + var heightOf = function (_p5) { var _p6 = _p5;return _p6._0.props.height;}; + var widthOf = function (_p7) { var _p8 = _p7;return _p8._0.props.width;}; + var above = F2(function (hi,lo) { + return A3(newElement,A2($Basics.max,widthOf(hi),widthOf(lo)),heightOf(hi) + heightOf(lo),A2(Flow,DDown,_U.list([hi,lo]))); + }); + var below = F2(function (lo,hi) { + return A3(newElement,A2($Basics.max,widthOf(hi),widthOf(lo)),heightOf(hi) + heightOf(lo),A2(Flow,DDown,_U.list([hi,lo]))); + }); + var beside = F2(function (lft,rht) { + return A3(newElement,widthOf(lft) + widthOf(rht),A2($Basics.max,heightOf(lft),heightOf(rht)),A2(Flow,right,_U.list([lft,rht]))); + }); + var layers = function (es) { + var hs = A2($List.map,heightOf,es); + var ws = A2($List.map,widthOf,es); + return A3(newElement,A2($Maybe.withDefault,0,$List.maximum(ws)),A2($Maybe.withDefault,0,$List.maximum(hs)),A2(Flow,DOut,es)); + }; + var empty = A2(spacer,0,0); + var flow = F2(function (dir,es) { + var newFlow = F2(function (w,h) { return A3(newElement,w,h,A2(Flow,dir,es));}); + var maxOrZero = function (list) { return A2($Maybe.withDefault,0,$List.maximum(list));}; + var hs = A2($List.map,heightOf,es); + var ws = A2($List.map,widthOf,es); + if (_U.eq(es,_U.list([]))) return empty; else { + var _p9 = dir; + switch (_p9.ctor) + {case "DUp": return A2(newFlow,maxOrZero(ws),$List.sum(hs)); + case "DDown": return A2(newFlow,maxOrZero(ws),$List.sum(hs)); + case "DLeft": return A2(newFlow,$List.sum(ws),maxOrZero(hs)); + case "DRight": return A2(newFlow,$List.sum(ws),maxOrZero(hs)); + case "DIn": return A2(newFlow,maxOrZero(ws),maxOrZero(hs)); + default: return A2(newFlow,maxOrZero(ws),maxOrZero(hs));} + } + }); + var Properties = F9(function (a,b,c,d,e,f,g,h,i) { return {id: a,width: b,height: c,opacity: d,color: e,href: f,tag: g,hover: h,click: i};}); + var Element_elm_builtin = function (a) { return {ctor: "Element_elm_builtin",_0: a};}; + var width = F2(function (newWidth,_p10) { + var _p11 = _p10; + var _p14 = _p11._0.props; + var _p13 = _p11._0.element; + var newHeight = function () { + var _p12 = _p13; + switch (_p12.ctor) + {case "Image": return $Basics.round($Basics.toFloat(_p12._2) / $Basics.toFloat(_p12._1) * $Basics.toFloat(newWidth)); + case "RawHtml": return $Basics.snd(A2($Native$Graphics$Element.htmlHeight,newWidth,_p13)); + default: return _p14.height;} + }(); + return Element_elm_builtin({element: _p13,props: _U.update(_p14,{width: newWidth,height: newHeight})}); + }); + var height = F2(function (newHeight,_p15) { + var _p16 = _p15; + return Element_elm_builtin({element: _p16._0.element,props: _U.update(_p16._0.props,{height: newHeight})}); + }); + var size = F3(function (w,h,e) { return A2(height,h,A2(width,w,e));}); + var opacity = F2(function (givenOpacity,_p17) { + var _p18 = _p17; + return Element_elm_builtin({element: _p18._0.element,props: _U.update(_p18._0.props,{opacity: givenOpacity})}); + }); + var color = F2(function (clr,_p19) { + var _p20 = _p19; + return Element_elm_builtin({element: _p20._0.element,props: _U.update(_p20._0.props,{color: $Maybe.Just(clr)})}); + }); + var tag = F2(function (name,_p21) { var _p22 = _p21;return Element_elm_builtin({element: _p22._0.element,props: _U.update(_p22._0.props,{tag: name})});}); + var link = F2(function (href,_p23) { + var _p24 = _p23; + return Element_elm_builtin({element: _p24._0.element,props: _U.update(_p24._0.props,{href: href})}); + }); + return _elm.Graphics.Element.values = {_op: _op + ,image: image + ,fittedImage: fittedImage + ,croppedImage: croppedImage + ,tiledImage: tiledImage + ,leftAligned: leftAligned + ,rightAligned: rightAligned + ,centered: centered + ,justified: justified + ,show: show + ,width: width + ,height: height + ,size: size + ,color: color + ,opacity: opacity + ,link: link + ,tag: tag + ,widthOf: widthOf + ,heightOf: heightOf + ,sizeOf: sizeOf + ,flow: flow + ,up: up + ,down: down + ,left: left + ,right: right + ,inward: inward + ,outward: outward + ,layers: layers + ,above: above + ,below: below + ,beside: beside + ,empty: empty + ,spacer: spacer + ,container: container + ,middle: middle + ,midTop: midTop + ,midBottom: midBottom + ,midLeft: midLeft + ,midRight: midRight + ,topLeft: topLeft + ,topRight: topRight + ,bottomLeft: bottomLeft + ,bottomRight: bottomRight + ,absolute: absolute + ,relative: relative + ,middleAt: middleAt + ,midTopAt: midTopAt + ,midBottomAt: midBottomAt + ,midLeftAt: midLeftAt + ,midRightAt: midRightAt + ,topLeftAt: topLeftAt + ,topRightAt: topRightAt + ,bottomLeftAt: bottomLeftAt + ,bottomRightAt: bottomRightAt}; +}; +Elm.Graphics = Elm.Graphics || {}; +Elm.Graphics.Collage = Elm.Graphics.Collage || {}; +Elm.Graphics.Collage.make = function (_elm) { + "use strict"; + _elm.Graphics = _elm.Graphics || {}; + _elm.Graphics.Collage = _elm.Graphics.Collage || {}; + if (_elm.Graphics.Collage.values) return _elm.Graphics.Collage.values; + var _U = Elm.Native.Utils.make(_elm), + $Basics = Elm.Basics.make(_elm), + $Color = Elm.Color.make(_elm), + $Graphics$Element = Elm.Graphics.Element.make(_elm), + $List = Elm.List.make(_elm), + $Native$Graphics$Collage = Elm.Native.Graphics.Collage.make(_elm), + $Text = Elm.Text.make(_elm), + $Transform2D = Elm.Transform2D.make(_elm); + var _op = {}; + var Shape = function (a) { return {ctor: "Shape",_0: a};}; + var polygon = function (points) { return Shape(points);}; + var rect = F2(function (w,h) { + var hh = h / 2; + var hw = w / 2; + return Shape(_U.list([{ctor: "_Tuple2",_0: 0 - hw,_1: 0 - hh} + ,{ctor: "_Tuple2",_0: 0 - hw,_1: hh} + ,{ctor: "_Tuple2",_0: hw,_1: hh} + ,{ctor: "_Tuple2",_0: hw,_1: 0 - hh}])); + }); + var square = function (n) { return A2(rect,n,n);}; + var oval = F2(function (w,h) { + var hh = h / 2; + var hw = w / 2; + var n = 50; + var t = 2 * $Basics.pi / n; + var f = function (i) { return {ctor: "_Tuple2",_0: hw * $Basics.cos(t * i),_1: hh * $Basics.sin(t * i)};}; + return Shape(A2($List.map,f,_U.range(0,n - 1))); + }); + var circle = function (r) { return A2(oval,2 * r,2 * r);}; + var ngon = F2(function (n,r) { + var m = $Basics.toFloat(n); + var t = 2 * $Basics.pi / m; + var f = function (i) { return {ctor: "_Tuple2",_0: r * $Basics.cos(t * i),_1: r * $Basics.sin(t * i)};}; + return Shape(A2($List.map,f,_U.range(0,m - 1))); + }); + var Path = function (a) { return {ctor: "Path",_0: a};}; + var path = function (ps) { return Path(ps);}; + var segment = F2(function (p1,p2) { return Path(_U.list([p1,p2]));}); + var collage = $Native$Graphics$Collage.collage; + var Fill = function (a) { return {ctor: "Fill",_0: a};}; + var Line = function (a) { return {ctor: "Line",_0: a};}; + var FGroup = F2(function (a,b) { return {ctor: "FGroup",_0: a,_1: b};}); + var FElement = function (a) { return {ctor: "FElement",_0: a};}; + var FImage = F4(function (a,b,c,d) { return {ctor: "FImage",_0: a,_1: b,_2: c,_3: d};}); + var FText = function (a) { return {ctor: "FText",_0: a};}; + var FOutlinedText = F2(function (a,b) { return {ctor: "FOutlinedText",_0: a,_1: b};}); + var FShape = F2(function (a,b) { return {ctor: "FShape",_0: a,_1: b};}); + var FPath = F2(function (a,b) { return {ctor: "FPath",_0: a,_1: b};}); + var LineStyle = F6(function (a,b,c,d,e,f) { return {color: a,width: b,cap: c,join: d,dashing: e,dashOffset: f};}); + var Clipped = {ctor: "Clipped"}; + var Sharp = function (a) { return {ctor: "Sharp",_0: a};}; + var Smooth = {ctor: "Smooth"}; + var Padded = {ctor: "Padded"}; + var Round = {ctor: "Round"}; + var Flat = {ctor: "Flat"}; + var defaultLine = {color: $Color.black,width: 1,cap: Flat,join: Sharp(10),dashing: _U.list([]),dashOffset: 0}; + var solid = function (clr) { return _U.update(defaultLine,{color: clr});}; + var dashed = function (clr) { return _U.update(defaultLine,{color: clr,dashing: _U.list([8,4])});}; + var dotted = function (clr) { return _U.update(defaultLine,{color: clr,dashing: _U.list([3,3])});}; + var Grad = function (a) { return {ctor: "Grad",_0: a};}; + var Texture = function (a) { return {ctor: "Texture",_0: a};}; + var Solid = function (a) { return {ctor: "Solid",_0: a};}; + var Form_elm_builtin = function (a) { return {ctor: "Form_elm_builtin",_0: a};}; + var form = function (f) { return Form_elm_builtin({theta: 0,scale: 1,x: 0,y: 0,alpha: 1,form: f});}; + var fill = F2(function (style,_p0) { var _p1 = _p0;return form(A2(FShape,Fill(style),_p1._0));}); + var filled = F2(function (color,shape) { return A2(fill,Solid(color),shape);}); + var textured = F2(function (src,shape) { return A2(fill,Texture(src),shape);}); + var gradient = F2(function (grad,shape) { return A2(fill,Grad(grad),shape);}); + var outlined = F2(function (style,_p2) { var _p3 = _p2;return form(A2(FShape,Line(style),_p3._0));}); + var traced = F2(function (style,_p4) { var _p5 = _p4;return form(A2(FPath,style,_p5._0));}); + var sprite = F4(function (w,h,pos,src) { return form(A4(FImage,w,h,pos,src));}); + var toForm = function (e) { return form(FElement(e));}; + var group = function (fs) { return form(A2(FGroup,$Transform2D.identity,fs));}; + var groupTransform = F2(function (matrix,fs) { return form(A2(FGroup,matrix,fs));}); + var text = function (t) { return form(FText(t));}; + var outlinedText = F2(function (ls,t) { return form(A2(FOutlinedText,ls,t));}); + var move = F2(function (_p7,_p6) { + var _p8 = _p7; + var _p9 = _p6; + var _p10 = _p9._0; + return Form_elm_builtin(_U.update(_p10,{x: _p10.x + _p8._0,y: _p10.y + _p8._1})); + }); + var moveX = F2(function (x,_p11) { var _p12 = _p11;var _p13 = _p12._0;return Form_elm_builtin(_U.update(_p13,{x: _p13.x + x}));}); + var moveY = F2(function (y,_p14) { var _p15 = _p14;var _p16 = _p15._0;return Form_elm_builtin(_U.update(_p16,{y: _p16.y + y}));}); + var scale = F2(function (s,_p17) { var _p18 = _p17;var _p19 = _p18._0;return Form_elm_builtin(_U.update(_p19,{scale: _p19.scale * s}));}); + var rotate = F2(function (t,_p20) { var _p21 = _p20;var _p22 = _p21._0;return Form_elm_builtin(_U.update(_p22,{theta: _p22.theta + t}));}); + var alpha = F2(function (a,_p23) { var _p24 = _p23;return Form_elm_builtin(_U.update(_p24._0,{alpha: a}));}); + return _elm.Graphics.Collage.values = {_op: _op + ,collage: collage + ,toForm: toForm + ,filled: filled + ,textured: textured + ,gradient: gradient + ,outlined: outlined + ,traced: traced + ,text: text + ,outlinedText: outlinedText + ,move: move + ,moveX: moveX + ,moveY: moveY + ,scale: scale + ,rotate: rotate + ,alpha: alpha + ,group: group + ,groupTransform: groupTransform + ,rect: rect + ,oval: oval + ,square: square + ,circle: circle + ,ngon: ngon + ,polygon: polygon + ,segment: segment + ,path: path + ,solid: solid + ,dashed: dashed + ,dotted: dotted + ,defaultLine: defaultLine + ,LineStyle: LineStyle + ,Flat: Flat + ,Round: Round + ,Padded: Padded + ,Smooth: Smooth + ,Sharp: Sharp + ,Clipped: Clipped}; +}; +Elm.Native.Debug = {}; +Elm.Native.Debug.make = function(localRuntime) { + localRuntime.Native = localRuntime.Native || {}; + localRuntime.Native.Debug = localRuntime.Native.Debug || {}; + if (localRuntime.Native.Debug.values) { - function wrapper(a) { return function(b) { return function(c) { - return function(d) { return fun(a,b,c,d) }}} - } - wrapper.arity = 4; - wrapper.func = fun; - return wrapper; + return localRuntime.Native.Debug.values; } - function F5(fun) + var toString = Elm.Native.Utils.make(localRuntime).toString; + + function log(tag, value) { - function wrapper(a) { return function(b) { return function(c) { - return function(d) { return function(e) { return fun(a,b,c,d,e) }}}} + var msg = tag + ': ' + toString(value); + var process = process || {}; + if (process.stdout) + { + process.stdout.write(msg); } - wrapper.arity = 5; - wrapper.func = fun; - return wrapper; + else + { + console.log(msg); + } + return value; } - function F6(fun) + function crash(message) { - function wrapper(a) { return function(b) { return function(c) { - return function(d) { return function(e) { return function(f) { - return fun(a,b,c,d,e,f) }}}}} - } - wrapper.arity = 6; - wrapper.func = fun; - return wrapper; + throw new Error(message); } - function F7(fun) + function tracePath(tag, form) { - function wrapper(a) { return function(b) { return function(c) { - return function(d) { return function(e) { return function(f) { - return function(g) { return fun(a,b,c,d,e,f,g) }}}}}} + if (localRuntime.debug) + { + return localRuntime.debug.trace(tag, form); } - wrapper.arity = 7; - wrapper.func = fun; - return wrapper; + return form; } - function F8(fun) + function watch(tag, value) { - function wrapper(a) { return function(b) { return function(c) { - return function(d) { return function(e) { return function(f) { - return function(g) { return function(h) { - return fun(a,b,c,d,e,f,g,h)}}}}}}} + if (localRuntime.debug) + { + localRuntime.debug.watch(tag, value); } - wrapper.arity = 8; - wrapper.func = fun; - return wrapper; + return value; } - function F9(fun) + function watchSummary(tag, summarize, value) { - function wrapper(a) { return function(b) { return function(c) { - return function(d) { return function(e) { return function(f) { - return function(g) { return function(h) { return function(i) { - return fun(a,b,c,d,e,f,g,h,i) }}}}}}}} + if (localRuntime.debug) + { + localRuntime.debug.watch(tag, summarize(value)); } - wrapper.arity = 9; - wrapper.func = fun; - return wrapper; + return value; } - function A2(fun,a,b) - { - return fun.arity === 2 - ? fun.func(a,b) - : fun(a)(b); - } - function A3(fun,a,b,c) + return localRuntime.Native.Debug.values = { + crash: crash, + tracePath: F2(tracePath), + log: F2(log), + watch: F2(watch), + watchSummary: F3(watchSummary) + }; +}; + +Elm.Debug = Elm.Debug || {}; +Elm.Debug.make = function (_elm) { + "use strict"; + _elm.Debug = _elm.Debug || {}; + if (_elm.Debug.values) return _elm.Debug.values; + var _U = Elm.Native.Utils.make(_elm),$Graphics$Collage = Elm.Graphics.Collage.make(_elm),$Native$Debug = Elm.Native.Debug.make(_elm); + var _op = {}; + var trace = $Native$Debug.tracePath; + var watchSummary = $Native$Debug.watchSummary; + var watch = $Native$Debug.watch; + var crash = $Native$Debug.crash; + var log = $Native$Debug.log; + return _elm.Debug.values = {_op: _op,log: log,crash: crash,watch: watch,watchSummary: watchSummary,trace: trace}; +}; +Elm.Native.Task = {}; + +Elm.Native.Task.make = function(localRuntime) { + localRuntime.Native = localRuntime.Native || {}; + localRuntime.Native.Task = localRuntime.Native.Task || {}; + if (localRuntime.Native.Task.values) { - return fun.arity === 3 - ? fun.func(a,b,c) - : fun(a)(b)(c); + return localRuntime.Native.Task.values; } - function A4(fun,a,b,c,d) + + var Result = Elm.Result.make(localRuntime); + var Signal; + var Utils = Elm.Native.Utils.make(localRuntime); + + + // CONSTRUCTORS + + function succeed(value) { - return fun.arity === 4 - ? fun.func(a,b,c,d) - : fun(a)(b)(c)(d); + return { + tag: 'Succeed', + value: value + }; } - function A5(fun,a,b,c,d,e) + + function fail(error) { - return fun.arity === 5 - ? fun.func(a,b,c,d,e) - : fun(a)(b)(c)(d)(e); + return { + tag: 'Fail', + value: error + }; } - function A6(fun,a,b,c,d,e,f) + + function asyncFunction(func) { - return fun.arity === 6 - ? fun.func(a,b,c,d,e,f) - : fun(a)(b)(c)(d)(e)(f); + return { + tag: 'Async', + asyncFunction: func + }; } - function A7(fun,a,b,c,d,e,f,g) + + function andThen(task, callback) { - return fun.arity === 7 - ? fun.func(a,b,c,d,e,f,g) - : fun(a)(b)(c)(d)(e)(f)(g); + return { + tag: 'AndThen', + task: task, + callback: callback + }; } - function A8(fun,a,b,c,d,e,f,g,h) + + function catch_(task, callback) { - return fun.arity === 8 - ? fun.func(a,b,c,d,e,f,g,h) - : fun(a)(b)(c)(d)(e)(f)(g)(h); + return { + tag: 'Catch', + task: task, + callback: callback + }; } - function A9(fun,a,b,c,d,e,f,g,h,i) - { - return fun.arity === 9 - ? fun.func(a,b,c,d,e,f,g,h,i) - : fun(a)(b)(c)(d)(e)(f)(g)(h)(i); + + + // RUNNER + + function perform(task) { + runTask({ task: task }, function() {}); } -} -Elm.Native.Show = {}; -Elm.Native.Show.make = function(localRuntime) { - localRuntime.Native = localRuntime.Native || {}; - localRuntime.Native.Show = localRuntime.Native.Show || {}; - if (localRuntime.Native.Show.values) + function performSignal(name, signal) { - return localRuntime.Native.Show.values; - } + var workQueue = []; - var _Array; - var Dict; - var List; - var Utils = Elm.Native.Utils.make(localRuntime); + function onComplete() + { + workQueue.shift(); - var toString = function(v) - { - var type = typeof v; - if (type === "function") + if (workQueue.length > 0) + { + var task = workQueue[0]; + + setTimeout(function() { + runTask(task, onComplete); + }, 0); + } + } + + function register(task) { - var name = v.func ? v.func.name : v.name; - return ''; + var root = { task: task }; + workQueue.push(root); + if (workQueue.length === 1) + { + runTask(root, onComplete); + } } - else if (type === "boolean") + + if (!Signal) { - return v ? "True" : "False"; + Signal = Elm.Native.Signal.make(localRuntime); } - else if (type === "number") + Signal.output('perform-tasks-' + name, register, signal); + + register(signal.value); + + return signal; + } + + function mark(status, task) + { + return { status: status, task: task }; + } + + function runTask(root, onComplete) + { + var result = mark('runnable', root.task); + while (result.status === 'runnable') { - return v + ""; + result = stepTask(onComplete, root, result.task); } - else if ((v instanceof String) && v.isChar) + + if (result.status === 'done') { - return "'" + addSlashes(v, true) + "'"; + root.task = result.task; + onComplete(); } - else if (type === "string") + + if (result.status === 'blocked') { - return '"' + addSlashes(v, false) + '"'; + root.task = result.task; } - else if (type === "object" && '_' in v && probablyPublic(v)) + } + + function stepTask(onComplete, root, task) + { + var tag = task.tag; + + if (tag === 'Succeed' || tag === 'Fail') { - var output = []; - for (var k in v._) - { - for (var i = v._[k].length; i--; ) - { - output.push(k + " = " + toString(v._[k][i])); - } - } - for (var k in v) - { - if (k === '_') continue; - output.push(k + " = " + toString(v[k])); - } - if (output.length === 0) - { - return "{}"; - } - return "{ " + output.join(", ") + " }"; + return mark('done', task); } - else if (type === "object" && 'ctor' in v) + + if (tag === 'Async') { - if (v.ctor.substring(0,6) === "_Tuple") - { - var output = []; - for (var k in v) - { - if (k === 'ctor') continue; - output.push(toString(v[k])); - } - return "(" + output.join(",") + ")"; - } - else if (v.ctor === "_Array") - { - if (!_Array) + var placeHolder = {}; + var couldBeSync = true; + var wasSync = false; + + task.asyncFunction(function(result) { + placeHolder.tag = result.tag; + placeHolder.value = result.value; + if (couldBeSync) { - _Array = Elm.Array.make(localRuntime); + wasSync = true; } - var list = _Array.toList(v); - return "Array.fromList " + toString(list); - } - else if (v.ctor === "::") - { - var output = '[' + toString(v._0); - v = v._1; - while (v.ctor === "::") + else { - output += "," + toString(v._0); - v = v._1; + runTask(root, onComplete); } - return output + ']'; - } - else if (v.ctor === "[]") - { - return "[]"; - } - else if (v.ctor === "RBNode" || v.ctor === "RBEmpty") + }); + couldBeSync = false; + return mark(wasSync ? 'done' : 'blocked', placeHolder); + } + + if (tag === 'AndThen' || tag === 'Catch') + { + var result = mark('runnable', task.task); + while (result.status === 'runnable') { - if (!Dict) - { - Dict = Elm.Dict.make(localRuntime); - } - if (!List) - { - List = Elm.List.make(localRuntime); - } - var list = Dict.toList(v); - var name = "Dict"; - if (list.ctor === "::" && list._0._1.ctor === "_Tuple0") - { - name = "Set"; - list = A2(List.map, function(x){return x._0}, list); - } - return name + ".fromList " + toString(list); + result = stepTask(onComplete, root, result.task); } - else if (v.ctor.slice(0,5) === "Text:") + + if (result.status === 'done') { - return '' + var activeTask = result.task; + var activeTag = activeTask.tag; + + var succeedChain = activeTag === 'Succeed' && tag === 'AndThen'; + var failChain = activeTag === 'Fail' && tag === 'Catch'; + + return (succeedChain || failChain) + ? mark('runnable', task.callback(activeTask.value)) + : mark('runnable', activeTask); } - else + if (result.status === 'blocked') { - var output = ""; - for (var i in v) - { - if (i === 'ctor') continue; - var str = toString(v[i]); - var parenless = str[0] === '{' || str[0] === '<' || str.indexOf(' ') < 0; - output += ' ' + (parenless ? str : '(' + str + ')'); - } - return v.ctor + output; + return mark('blocked', { + tag: tag, + task: result.task, + callback: task.callback + }); } } - if (type === 'object' && 'notify' in v && 'id' in v) - { - return ''; - } - return ""; - }; + } - function addSlashes(str, isChar) - { - var s = str.replace(/\\/g, '\\\\') - .replace(/\n/g, '\\n') - .replace(/\t/g, '\\t') - .replace(/\r/g, '\\r') - .replace(/\v/g, '\\v') - .replace(/\0/g, '\\0'); - if (isChar) - { - return s.replace(/\'/g, "\\'") - } - else - { - return s.replace(/\"/g, '\\"'); - } + + // THREADS + + function sleep(time) { + return asyncFunction(function(callback) { + setTimeout(function() { + callback(succeed(Utils.Tuple0)); + }, time); + }); } - function probablyPublic(v) - { - var keys = Object.keys(v); - var len = keys.length; - if (len === 3 - && 'props' in v - && 'element' in v) - { - return false; - } - else if (len === 5 - && 'horizontal' in v - && 'vertical' in v - && 'x' in v - && 'y' in v) - { - return false; - } - else if (len === 7 - && 'theta' in v - && 'scale' in v - && 'x' in v - && 'y' in v - && 'alpha' in v - && 'form' in v) - { - return false; - } - return true; + function spawn(task) { + return asyncFunction(function(callback) { + var id = setTimeout(function() { + perform(task); + }, 0); + callback(succeed(id)); + }); } - return localRuntime.Native.Show.values = { - toString: toString + + return localRuntime.Native.Task.values = { + succeed: succeed, + fail: fail, + asyncFunction: asyncFunction, + andThen: F2(andThen), + catch_: F2(catch_), + perform: perform, + performSignal: performSignal, + spawn: spawn, + sleep: sleep }; }; -Elm.Native.Signal = {}; -Elm.Native.Signal.make = function(localRuntime) { +Elm.Result = Elm.Result || {}; +Elm.Result.make = function (_elm) { + "use strict"; + _elm.Result = _elm.Result || {}; + if (_elm.Result.values) return _elm.Result.values; + var _U = Elm.Native.Utils.make(_elm),$Maybe = Elm.Maybe.make(_elm); + var _op = {}; + var toMaybe = function (result) { var _p0 = result;if (_p0.ctor === "Ok") { return $Maybe.Just(_p0._0);} else { return $Maybe.Nothing;}}; + var withDefault = F2(function (def,result) { var _p1 = result;if (_p1.ctor === "Ok") { return _p1._0;} else { return def;}}); + var Err = function (a) { return {ctor: "Err",_0: a};}; + var andThen = F2(function (result,callback) { var _p2 = result;if (_p2.ctor === "Ok") { return callback(_p2._0);} else { return Err(_p2._0);}}); + var Ok = function (a) { return {ctor: "Ok",_0: a};}; + var map = F2(function (func,ra) { var _p3 = ra;if (_p3.ctor === "Ok") { return Ok(func(_p3._0));} else { return Err(_p3._0);}}); + var map2 = F3(function (func,ra,rb) { + var _p4 = {ctor: "_Tuple2",_0: ra,_1: rb}; + if (_p4._0.ctor === "Ok") { + if (_p4._1.ctor === "Ok") { + return Ok(A2(func,_p4._0._0,_p4._1._0)); + } else { + return Err(_p4._1._0); + } + } else { + return Err(_p4._0._0); + } + }); + var map3 = F4(function (func,ra,rb,rc) { + var _p5 = {ctor: "_Tuple3",_0: ra,_1: rb,_2: rc}; + if (_p5._0.ctor === "Ok") { + if (_p5._1.ctor === "Ok") { + if (_p5._2.ctor === "Ok") { + return Ok(A3(func,_p5._0._0,_p5._1._0,_p5._2._0)); + } else { + return Err(_p5._2._0); + } + } else { + return Err(_p5._1._0); + } + } else { + return Err(_p5._0._0); + } + }); + var map4 = F5(function (func,ra,rb,rc,rd) { + var _p6 = {ctor: "_Tuple4",_0: ra,_1: rb,_2: rc,_3: rd}; + if (_p6._0.ctor === "Ok") { + if (_p6._1.ctor === "Ok") { + if (_p6._2.ctor === "Ok") { + if (_p6._3.ctor === "Ok") { + return Ok(A4(func,_p6._0._0,_p6._1._0,_p6._2._0,_p6._3._0)); + } else { + return Err(_p6._3._0); + } + } else { + return Err(_p6._2._0); + } + } else { + return Err(_p6._1._0); + } + } else { + return Err(_p6._0._0); + } + }); + var map5 = F6(function (func,ra,rb,rc,rd,re) { + var _p7 = {ctor: "_Tuple5",_0: ra,_1: rb,_2: rc,_3: rd,_4: re}; + if (_p7._0.ctor === "Ok") { + if (_p7._1.ctor === "Ok") { + if (_p7._2.ctor === "Ok") { + if (_p7._3.ctor === "Ok") { + if (_p7._4.ctor === "Ok") { + return Ok(A5(func,_p7._0._0,_p7._1._0,_p7._2._0,_p7._3._0,_p7._4._0)); + } else { + return Err(_p7._4._0); + } + } else { + return Err(_p7._3._0); + } + } else { + return Err(_p7._2._0); + } + } else { + return Err(_p7._1._0); + } + } else { + return Err(_p7._0._0); + } + }); + var formatError = F2(function (f,result) { var _p8 = result;if (_p8.ctor === "Ok") { return Ok(_p8._0);} else { return Err(f(_p8._0));}}); + var fromMaybe = F2(function (err,maybe) { var _p9 = maybe;if (_p9.ctor === "Just") { return Ok(_p9._0);} else { return Err(err);}}); + return _elm.Result.values = {_op: _op + ,withDefault: withDefault + ,map: map + ,map2: map2 + ,map3: map3 + ,map4: map4 + ,map5: map5 + ,andThen: andThen + ,toMaybe: toMaybe + ,fromMaybe: fromMaybe + ,formatError: formatError + ,Ok: Ok + ,Err: Err}; +}; +Elm.Task = Elm.Task || {}; +Elm.Task.make = function (_elm) { + "use strict"; + _elm.Task = _elm.Task || {}; + if (_elm.Task.values) return _elm.Task.values; + var _U = Elm.Native.Utils.make(_elm), + $List = Elm.List.make(_elm), + $Maybe = Elm.Maybe.make(_elm), + $Native$Task = Elm.Native.Task.make(_elm), + $Result = Elm.Result.make(_elm); + var _op = {}; + var sleep = $Native$Task.sleep; + var spawn = $Native$Task.spawn; + var ThreadID = function (a) { return {ctor: "ThreadID",_0: a};}; + var onError = $Native$Task.catch_; + var andThen = $Native$Task.andThen; + var fail = $Native$Task.fail; + var mapError = F2(function (f,task) { return A2(onError,task,function (err) { return fail(f(err));});}); + var succeed = $Native$Task.succeed; + var map = F2(function (func,taskA) { return A2(andThen,taskA,function (a) { return succeed(func(a));});}); + var map2 = F3(function (func,taskA,taskB) { + return A2(andThen,taskA,function (a) { return A2(andThen,taskB,function (b) { return succeed(A2(func,a,b));});}); + }); + var map3 = F4(function (func,taskA,taskB,taskC) { + return A2(andThen, + taskA, + function (a) { + return A2(andThen,taskB,function (b) { return A2(andThen,taskC,function (c) { return succeed(A3(func,a,b,c));});}); + }); + }); + var map4 = F5(function (func,taskA,taskB,taskC,taskD) { + return A2(andThen, + taskA, + function (a) { + return A2(andThen, + taskB, + function (b) { + return A2(andThen,taskC,function (c) { return A2(andThen,taskD,function (d) { return succeed(A4(func,a,b,c,d));});}); + }); + }); + }); + var map5 = F6(function (func,taskA,taskB,taskC,taskD,taskE) { + return A2(andThen, + taskA, + function (a) { + return A2(andThen, + taskB, + function (b) { + return A2(andThen, + taskC, + function (c) { + return A2(andThen,taskD,function (d) { return A2(andThen,taskE,function (e) { return succeed(A5(func,a,b,c,d,e));});}); + }); + }); + }); + }); + var andMap = F2(function (taskFunc,taskValue) { + return A2(andThen,taskFunc,function (func) { return A2(andThen,taskValue,function (value) { return succeed(func(value));});}); + }); + var sequence = function (tasks) { + var _p0 = tasks; + if (_p0.ctor === "[]") { + return succeed(_U.list([])); + } else { + return A3(map2,F2(function (x,y) { return A2($List._op["::"],x,y);}),_p0._0,sequence(_p0._1)); + } + }; + var toMaybe = function (task) { return A2(onError,A2(map,$Maybe.Just,task),function (_p1) { return succeed($Maybe.Nothing);});}; + var fromMaybe = F2(function ($default,maybe) { var _p2 = maybe;if (_p2.ctor === "Just") { return succeed(_p2._0);} else { return fail($default);}}); + var toResult = function (task) { return A2(onError,A2(map,$Result.Ok,task),function (msg) { return succeed($Result.Err(msg));});}; + var fromResult = function (result) { var _p3 = result;if (_p3.ctor === "Ok") { return succeed(_p3._0);} else { return fail(_p3._0);}}; + var Task = {ctor: "Task"}; + return _elm.Task.values = {_op: _op + ,succeed: succeed + ,fail: fail + ,map: map + ,map2: map2 + ,map3: map3 + ,map4: map4 + ,map5: map5 + ,andMap: andMap + ,sequence: sequence + ,andThen: andThen + ,onError: onError + ,mapError: mapError + ,toMaybe: toMaybe + ,fromMaybe: fromMaybe + ,toResult: toResult + ,fromResult: fromResult + ,spawn: spawn + ,sleep: sleep}; +}; +Elm.Signal = Elm.Signal || {}; +Elm.Signal.make = function (_elm) { + "use strict"; + _elm.Signal = _elm.Signal || {}; + if (_elm.Signal.values) return _elm.Signal.values; + var _U = Elm.Native.Utils.make(_elm), + $Basics = Elm.Basics.make(_elm), + $Debug = Elm.Debug.make(_elm), + $List = Elm.List.make(_elm), + $Maybe = Elm.Maybe.make(_elm), + $Native$Signal = Elm.Native.Signal.make(_elm), + $Task = Elm.Task.make(_elm); + var _op = {}; + var send = F2(function (_p0,value) { + var _p1 = _p0; + return A2($Task.onError,_p1._0(value),function (_p2) { return $Task.succeed({ctor: "_Tuple0"});}); + }); + var Message = function (a) { return {ctor: "Message",_0: a};}; + var message = F2(function (_p3,value) { var _p4 = _p3;return Message(_p4._0(value));}); + var mailbox = $Native$Signal.mailbox; + var Address = function (a) { return {ctor: "Address",_0: a};}; + var forwardTo = F2(function (_p5,f) { var _p6 = _p5;return Address(function (x) { return _p6._0(f(x));});}); + var Mailbox = F2(function (a,b) { return {address: a,signal: b};}); + var sampleOn = $Native$Signal.sampleOn; + var dropRepeats = $Native$Signal.dropRepeats; + var filterMap = $Native$Signal.filterMap; + var filter = F3(function (isOk,base,signal) { + return A3(filterMap,function (value) { return isOk(value) ? $Maybe.Just(value) : $Maybe.Nothing;},base,signal); + }); + var merge = F2(function (left,right) { return A3($Native$Signal.genericMerge,$Basics.always,left,right);}); + var mergeMany = function (signalList) { + var _p7 = $List.reverse(signalList); + if (_p7.ctor === "[]") { + return _U.crashCase("Signal",{start: {line: 184,column: 3},end: {line: 189,column: 40}},_p7)("mergeMany was given an empty list!"); + } else { + return A3($List.foldl,merge,_p7._0,_p7._1); + } + }; + var foldp = $Native$Signal.foldp; + var map5 = $Native$Signal.map5; + var map4 = $Native$Signal.map4; + var map3 = $Native$Signal.map3; + var map2 = $Native$Signal.map2; + var map = $Native$Signal.map; + var constant = $Native$Signal.constant; + var Signal = {ctor: "Signal"}; + return _elm.Signal.values = {_op: _op + ,merge: merge + ,mergeMany: mergeMany + ,map: map + ,map2: map2 + ,map3: map3 + ,map4: map4 + ,map5: map5 + ,constant: constant + ,dropRepeats: dropRepeats + ,filter: filter + ,filterMap: filterMap + ,sampleOn: sampleOn + ,foldp: foldp + ,mailbox: mailbox + ,send: send + ,message: message + ,forwardTo: forwardTo + ,Mailbox: Mailbox}; +}; +Elm.Time = Elm.Time || {}; +Elm.Time.make = function (_elm) { + "use strict"; + _elm.Time = _elm.Time || {}; + if (_elm.Time.values) return _elm.Time.values; + var _U = Elm.Native.Utils.make(_elm), + $Basics = Elm.Basics.make(_elm), + $Native$Signal = Elm.Native.Signal.make(_elm), + $Native$Time = Elm.Native.Time.make(_elm), + $Signal = Elm.Signal.make(_elm); + var _op = {}; + var delay = $Native$Signal.delay; + var since = F2(function (time,signal) { + var stop = A2($Signal.map,$Basics.always(-1),A2(delay,time,signal)); + var start = A2($Signal.map,$Basics.always(1),signal); + var delaydiff = A3($Signal.foldp,F2(function (x,y) { return x + y;}),0,A2($Signal.merge,start,stop)); + return A2($Signal.map,F2(function (x,y) { return !_U.eq(x,y);})(0),delaydiff); + }); + var timestamp = $Native$Signal.timestamp; + var every = $Native$Time.every; + var fpsWhen = $Native$Time.fpsWhen; + var fps = function (targetFrames) { return A2(fpsWhen,targetFrames,$Signal.constant(true));}; + var inMilliseconds = function (t) { return t;}; + var millisecond = 1; + var second = 1000 * millisecond; + var minute = 60 * second; + var hour = 60 * minute; + var inHours = function (t) { return t / hour;}; + var inMinutes = function (t) { return t / minute;}; + var inSeconds = function (t) { return t / second;}; + return _elm.Time.values = {_op: _op + ,millisecond: millisecond + ,second: second + ,minute: minute + ,hour: hour + ,inMilliseconds: inMilliseconds + ,inSeconds: inSeconds + ,inMinutes: inMinutes + ,inHours: inHours + ,fps: fps + ,fpsWhen: fpsWhen + ,every: every + ,timestamp: timestamp + ,delay: delay + ,since: since}; +}; +Elm.Native.String = {}; +Elm.Native.String.make = function(localRuntime) { localRuntime.Native = localRuntime.Native || {}; - localRuntime.Native.Signal = localRuntime.Native.Signal || {}; - if (localRuntime.Native.Signal.values) + localRuntime.Native.String = localRuntime.Native.String || {}; + if (localRuntime.Native.String.values) { - return localRuntime.Native.Signal.values; + return localRuntime.Native.String.values; } - - - var Task = Elm.Native.Task.make(localRuntime); - var Utils = Elm.Native.Utils.make(localRuntime); - - - function broadcastToKids(node, timestamp, update) + if ('values' in Elm.Native.String) { - var kids = node.kids; - for (var i = kids.length; i--; ) - { - kids[i].notify(timestamp, update, node.id); - } + return localRuntime.Native.String.values = Elm.Native.String.values; } - // INPUT + var Char = Elm.Char.make(localRuntime); + var List = Elm.Native.List.make(localRuntime); + var Maybe = Elm.Maybe.make(localRuntime); + var Result = Elm.Result.make(localRuntime); + var Utils = Elm.Native.Utils.make(localRuntime); - function input(name, base) + function isEmpty(str) { - var node = { - id: Utils.guid(), - name: 'input-' + name, - value: base, - parents: [], - kids: [] - }; - - node.notify = function(timestamp, targetId, value) { - var update = targetId === node.id; - if (update) - { - node.value = value; - } - broadcastToKids(node, timestamp, update); - return update; - }; - - localRuntime.inputs.push(node); - - return node; + return str.length === 0; } - - function constant(value) + function cons(chr, str) { - return input('constant', value); + return chr + str; } - - - // MAILBOX - - function mailbox(base) + function uncons(str) { - var signal = input('mailbox', base); - - function send(value) { - return Task.asyncFunction(function(callback) { - localRuntime.setTimeout(function() { - localRuntime.notify(signal.id, value); - }, 0); - callback(Task.succeed(Utils.Tuple0)); - }); + var hd = str[0]; + if (hd) + { + return Maybe.Just(Utils.Tuple2(Utils.chr(hd), str.slice(1))); } - - return { - _: {}, - signal: signal, - address: { - ctor: 'Address', - _0: send - } - }; + return Maybe.Nothing; } - - function sendMessage(message) + function append(a, b) { - Task.perform(message._0); + return a + b; } - - - // OUTPUT - - function output(name, handler, parent) + function concat(strs) { - var node = { - id: Utils.guid(), - name: 'output-' + name, - parents: [parent], - isOutput: true - }; - - node.notify = function(timestamp, parentUpdate, parentID) - { - if (parentUpdate) - { - handler(parent.value); - } - }; - - parent.kids.push(node); - - return node; + return List.toArray(strs).join(''); } - - - // MAP - - function mapMany(refreshValue, args) + function length(str) { - var node = { - id: Utils.guid(), - name: 'map' + args.length, - value: refreshValue(), - parents: args, - kids: [] - }; - - var numberOfParents = args.length; - var count = 0; - var update = false; - - node.notify = function(timestamp, parentUpdate, parentID) - { - ++count; - - update = update || parentUpdate; - - if (count === numberOfParents) - { - if (update) - { - node.value = refreshValue(); - } - broadcastToKids(node, timestamp, update); - update = false; - count = 0; - } - }; - - for (var i = numberOfParents; i--; ) - { - args[i].kids.push(node); - } - - return node; - } - - - function map(func, a) + return str.length; + } + function map(f, str) { - function refreshValue() + var out = str.split(''); + for (var i = out.length; i--; ) { - return func(a.value); + out[i] = f(Utils.chr(out[i])); } - return mapMany(refreshValue, [a]); + return out.join(''); } - - - function map2(func, a, b) + function filter(pred, str) { - function refreshValue() - { - return A2( func, a.value, b.value ); - } - return mapMany(refreshValue, [a,b]); + return str.split('').map(Utils.chr).filter(pred).join(''); } - - - function map3(func, a, b, c) + function reverse(str) { - function refreshValue() - { - return A3( func, a.value, b.value, c.value ); - } - return mapMany(refreshValue, [a,b,c]); + return str.split('').reverse().join(''); } - - - function map4(func, a, b, c, d) + function foldl(f, b, str) { - function refreshValue() + var len = str.length; + for (var i = 0; i < len; ++i) { - return A4( func, a.value, b.value, c.value, d.value ); + b = A2(f, Utils.chr(str[i]), b); } - return mapMany(refreshValue, [a,b,c,d]); + return b; } - - - function map5(func, a, b, c, d, e) + function foldr(f, b, str) { - function refreshValue() + for (var i = str.length; i--; ) { - return A5( func, a.value, b.value, c.value, d.value, e.value ); + b = A2(f, Utils.chr(str[i]), b); } - return mapMany(refreshValue, [a,b,c,d,e]); + return b; } - - - - // FOLD - - function foldp(update, state, signal) + function split(sep, str) { - var node = { - id: Utils.guid(), - name: 'foldp', - parents: [signal], - kids: [], - value: state - }; - - node.notify = function(timestamp, parentUpdate, parentID) + return List.fromArray(str.split(sep)); + } + function join(sep, strs) + { + return List.toArray(strs).join(sep); + } + function repeat(n, str) + { + var result = ''; + while (n > 0) { - if (parentUpdate) + if (n & 1) { - node.value = A2( update, signal.value, node.value ); + result += str; } - broadcastToKids(node, timestamp, parentUpdate); - }; - - signal.kids.push(node); - - return node; + n >>= 1, str += str; + } + return result; + } + function slice(start, end, str) + { + return str.slice(start, end); + } + function left(n, str) + { + return n < 1 ? '' : str.slice(0, n); + } + function right(n, str) + { + return n < 1 ? '' : str.slice(-n); + } + function dropLeft(n, str) + { + return n < 1 ? str : str.slice(n); + } + function dropRight(n, str) + { + return n < 1 ? str : str.slice(0, -n); + } + function pad(n, chr, str) + { + var half = (n - str.length) / 2; + return repeat(Math.ceil(half), chr) + str + repeat(half | 0, chr); + } + function padRight(n, chr, str) + { + return str + repeat(n - str.length, chr); + } + function padLeft(n, chr, str) + { + return repeat(n - str.length, chr) + str; } + function trim(str) + { + return str.trim(); + } + function trimLeft(str) + { + return str.replace(/^\s+/, ''); + } + function trimRight(str) + { + return str.replace(/\s+$/, ''); + } - // TIME + function words(str) + { + return List.fromArray(str.trim().split(/\s+/g)); + } + function lines(str) + { + return List.fromArray(str.split(/\r\n|\r|\n/g)); + } - function timestamp(signal) + function toUpper(str) { - var node = { - id: Utils.guid(), - name: 'timestamp', - value: Utils.Tuple2(localRuntime.timer.programStart, signal.value), - parents: [signal], - kids: [] - }; + return str.toUpperCase(); + } + function toLower(str) + { + return str.toLowerCase(); + } - node.notify = function(timestamp, parentUpdate, parentID) + function any(pred, str) + { + for (var i = str.length; i--; ) { - if (parentUpdate) + if (pred(Utils.chr(str[i]))) { - node.value = Utils.Tuple2(timestamp, signal.value); + return true; } - broadcastToKids(node, timestamp, parentUpdate); - }; - - signal.kids.push(node); - - return node; + } + return false; } - - - function delay(time, signal) + function all(pred, str) { - var delayed = input('delay-input-' + time, signal.value); - - function handler(value) + for (var i = str.length; i--; ) { - setTimeout(function() { - localRuntime.notify(delayed.id, value); - }, time); + if (!pred(Utils.chr(str[i]))) + { + return false; + } } - - output('delay-output-' + time, handler, signal); - - return delayed; + return true; } - - // MERGING - - function genericMerge(tieBreaker, leftStream, rightStream) + function contains(sub, str) { - var node = { - id: Utils.guid(), - name: 'merge', - value: A2(tieBreaker, leftStream.value, rightStream.value), - parents: [leftStream, rightStream], - kids: [] - }; - - var left = { touched: false, update: false, value: null }; - var right = { touched: false, update: false, value: null }; - - node.notify = function(timestamp, parentUpdate, parentID) + return str.indexOf(sub) > -1; + } + function startsWith(sub, str) + { + return str.indexOf(sub) === 0; + } + function endsWith(sub, str) + { + return str.length >= sub.length && + str.lastIndexOf(sub) === str.length - sub.length; + } + function indexes(sub, str) + { + var subLen = sub.length; + var i = 0; + var is = []; + while ((i = str.indexOf(sub, i)) > -1) { - if (parentID === leftStream.id) - { - left.touched = true; - left.update = parentUpdate; - left.value = leftStream.value; - } - if (parentID === rightStream.id) - { - right.touched = true; - right.update = parentUpdate; - right.value = rightStream.value; - } - - if (left.touched && right.touched) - { - var update = false; - if (left.update && right.update) - { - node.value = A2(tieBreaker, left.value, right.value); - update = true; - } - else if (left.update) - { - node.value = left.value; - update = true; - } - else if (right.update) - { - node.value = right.value; - update = true; - } - left.touched = false; - right.touched = false; - - broadcastToKids(node, timestamp, update); - } - }; - - leftStream.kids.push(node); - rightStream.kids.push(node); - - return node; + is.push(i); + i = i + subLen; + } + return List.fromArray(is); } - - // FILTERING - - function filterMap(toMaybe, base, signal) + function toInt(s) { - var maybe = toMaybe(signal.value); - var node = { - id: Utils.guid(), - name: 'filterMap', - value: maybe.ctor === 'Nothing' ? base : maybe._0, - parents: [signal], - kids: [] - }; - - node.notify = function(timestamp, parentUpdate, parentID) + var len = s.length; + if (len === 0) { - var update = false; - if (parentUpdate) + return Result.Err("could not convert string '" + s + "' to an Int" ); + } + var start = 0; + if (s[0] === '-') + { + if (len === 1) { - var maybe = toMaybe(signal.value); - if (maybe.ctor === 'Just') - { - update = true; - node.value = maybe._0; - } + return Result.Err("could not convert string '" + s + "' to an Int" ); } - broadcastToKids(node, timestamp, update); - }; - - signal.kids.push(node); - - return node; + start = 1; + } + for (var i = start; i < len; ++i) + { + if (!Char.isDigit(s[i])) + { + return Result.Err("could not convert string '" + s + "' to an Int" ); + } + } + return Result.Ok(parseInt(s, 10)); } - - // SAMPLING - - function sampleOn(ticker, signal) + function toFloat(s) { - var node = { - id: Utils.guid(), - name: 'sampleOn', - value: signal.value, - parents: [ticker, signal], - kids: [] - }; - - var signalTouch = false; - var tickerTouch = false; - var tickerUpdate = false; - - node.notify = function(timestamp, parentUpdate, parentID) + var len = s.length; + if (len === 0) { - if (parentID === ticker.id) + return Result.Err("could not convert string '" + s + "' to a Float" ); + } + var start = 0; + if (s[0] === '-') + { + if (len === 1) { - tickerTouch = true; - tickerUpdate = parentUpdate; + return Result.Err("could not convert string '" + s + "' to a Float" ); } - if (parentID === signal.id) + start = 1; + } + var dotCount = 0; + for (var i = start; i < len; ++i) + { + if (Char.isDigit(s[i])) { - signalTouch = true; + continue; } - - if (tickerTouch && signalTouch) + if (s[i] === '.') { - if (tickerUpdate) + dotCount += 1; + if (dotCount <= 1) { - node.value = signal.value; + continue; } - tickerTouch = false; - signalTouch = false; - - broadcastToKids(node, timestamp, tickerUpdate); } - }; - - ticker.kids.push(node); - signal.kids.push(node); + return Result.Err("could not convert string '" + s + "' to a Float" ); + } + return Result.Ok(parseFloat(s)); + } - return node; + function toList(str) + { + return List.fromArray(str.split('').map(Utils.chr)); + } + function fromList(chars) + { + return List.toArray(chars).join(''); } + return Elm.Native.String.values = { + isEmpty: isEmpty, + cons: F2(cons), + uncons: uncons, + append: F2(append), + concat: concat, + length: length, + map: F2(map), + filter: F2(filter), + reverse: reverse, + foldl: F3(foldl), + foldr: F3(foldr), - // DROP REPEATS + split: F2(split), + join: F2(join), + repeat: F2(repeat), - function dropRepeats(signal) - { - var node = { - id: Utils.guid(), - name: 'dropRepeats', - value: signal.value, - parents: [signal], - kids: [] - }; + slice: F3(slice), + left: F2(left), + right: F2(right), + dropLeft: F2(dropLeft), + dropRight: F2(dropRight), - node.notify = function(timestamp, parentUpdate, parentID) - { - var update = false; - if (parentUpdate && !Utils.eq(node.value, signal.value)) - { - node.value = signal.value; - update = true; - } - broadcastToKids(node, timestamp, update); - }; + pad: F3(pad), + padLeft: F3(padLeft), + padRight: F3(padRight), - signal.kids.push(node); + trim: trim, + trimLeft: trimLeft, + trimRight: trimRight, - return node; - } + words: words, + lines: lines, + toUpper: toUpper, + toLower: toLower, - return localRuntime.Native.Signal.values = { - input: input, - constant: constant, - mailbox: mailbox, - sendMessage: sendMessage, - output: output, - map: F2(map), - map2: F3(map2), - map3: F4(map3), - map4: F5(map4), - map5: F6(map5), - foldp: F3(foldp), - genericMerge: F3(genericMerge), - filterMap: F3(filterMap), - sampleOn: F2(sampleOn), - dropRepeats: dropRepeats, - timestamp: timestamp, - delay: F2(delay) + any: F2(any), + all: F2(all), + + contains: F2(contains), + startsWith: F2(startsWith), + endsWith: F2(endsWith), + indexes: F2(indexes), + + toInt: toInt, + toFloat: toFloat, + toList: toList, + fromList: fromList }; }; -Elm.Native.String = {}; -Elm.Native.String.make = function(localRuntime) { - +Elm.String = Elm.String || {}; +Elm.String.make = function (_elm) { + "use strict"; + _elm.String = _elm.String || {}; + if (_elm.String.values) return _elm.String.values; + var _U = Elm.Native.Utils.make(_elm),$Maybe = Elm.Maybe.make(_elm),$Native$String = Elm.Native.String.make(_elm),$Result = Elm.Result.make(_elm); + var _op = {}; + var fromList = $Native$String.fromList; + var toList = $Native$String.toList; + var toFloat = $Native$String.toFloat; + var toInt = $Native$String.toInt; + var indices = $Native$String.indexes; + var indexes = $Native$String.indexes; + var endsWith = $Native$String.endsWith; + var startsWith = $Native$String.startsWith; + var contains = $Native$String.contains; + var all = $Native$String.all; + var any = $Native$String.any; + var toLower = $Native$String.toLower; + var toUpper = $Native$String.toUpper; + var lines = $Native$String.lines; + var words = $Native$String.words; + var trimRight = $Native$String.trimRight; + var trimLeft = $Native$String.trimLeft; + var trim = $Native$String.trim; + var padRight = $Native$String.padRight; + var padLeft = $Native$String.padLeft; + var pad = $Native$String.pad; + var dropRight = $Native$String.dropRight; + var dropLeft = $Native$String.dropLeft; + var right = $Native$String.right; + var left = $Native$String.left; + var slice = $Native$String.slice; + var repeat = $Native$String.repeat; + var join = $Native$String.join; + var split = $Native$String.split; + var foldr = $Native$String.foldr; + var foldl = $Native$String.foldl; + var reverse = $Native$String.reverse; + var filter = $Native$String.filter; + var map = $Native$String.map; + var length = $Native$String.length; + var concat = $Native$String.concat; + var append = $Native$String.append; + var uncons = $Native$String.uncons; + var cons = $Native$String.cons; + var fromChar = function ($char) { return A2(cons,$char,"");}; + var isEmpty = $Native$String.isEmpty; + return _elm.String.values = {_op: _op + ,isEmpty: isEmpty + ,length: length + ,reverse: reverse + ,repeat: repeat + ,cons: cons + ,uncons: uncons + ,fromChar: fromChar + ,append: append + ,concat: concat + ,split: split + ,join: join + ,words: words + ,lines: lines + ,slice: slice + ,left: left + ,right: right + ,dropLeft: dropLeft + ,dropRight: dropRight + ,contains: contains + ,startsWith: startsWith + ,endsWith: endsWith + ,indexes: indexes + ,indices: indices + ,toInt: toInt + ,toFloat: toFloat + ,toList: toList + ,fromList: fromList + ,toUpper: toUpper + ,toLower: toLower + ,pad: pad + ,padLeft: padLeft + ,padRight: padRight + ,trim: trim + ,trimLeft: trimLeft + ,trimRight: trimRight + ,map: map + ,filter: filter + ,foldl: foldl + ,foldr: foldr + ,any: any + ,all: all}; +}; +Elm.Dict = Elm.Dict || {}; +Elm.Dict.make = function (_elm) { + "use strict"; + _elm.Dict = _elm.Dict || {}; + if (_elm.Dict.values) return _elm.Dict.values; + var _U = Elm.Native.Utils.make(_elm), + $Basics = Elm.Basics.make(_elm), + $List = Elm.List.make(_elm), + $Maybe = Elm.Maybe.make(_elm), + $Native$Debug = Elm.Native.Debug.make(_elm), + $String = Elm.String.make(_elm); + var _op = {}; + var foldr = F3(function (f,acc,t) { + foldr: while (true) { + var _p0 = t; + if (_p0.ctor === "RBEmpty_elm_builtin") { + return acc; + } else { + var _v1 = f,_v2 = A3(f,_p0._1,_p0._2,A3(foldr,f,acc,_p0._4)),_v3 = _p0._3; + f = _v1; + acc = _v2; + t = _v3; + continue foldr; + } + } + }); + var keys = function (dict) { return A3(foldr,F3(function (key,value,keyList) { return A2($List._op["::"],key,keyList);}),_U.list([]),dict);}; + var values = function (dict) { return A3(foldr,F3(function (key,value,valueList) { return A2($List._op["::"],value,valueList);}),_U.list([]),dict);}; + var toList = function (dict) { + return A3(foldr,F3(function (key,value,list) { return A2($List._op["::"],{ctor: "_Tuple2",_0: key,_1: value},list);}),_U.list([]),dict); + }; + var foldl = F3(function (f,acc,dict) { + foldl: while (true) { + var _p1 = dict; + if (_p1.ctor === "RBEmpty_elm_builtin") { + return acc; + } else { + var _v5 = f,_v6 = A3(f,_p1._1,_p1._2,A3(foldl,f,acc,_p1._3)),_v7 = _p1._4; + f = _v5; + acc = _v6; + dict = _v7; + continue foldl; + } + } + }); + var reportRemBug = F4(function (msg,c,lgot,rgot) { + return $Native$Debug.crash($String.concat(_U.list(["Internal red-black tree invariant violated, expected " + ,msg + ," and got " + ,$Basics.toString(c) + ,"/" + ,lgot + ,"/" + ,rgot + ,"\nPlease report this bug to "]))); + }); + var isBBlack = function (dict) { + var _p2 = dict; + _v8_2: do { + if (_p2.ctor === "RBNode_elm_builtin") { + if (_p2._0.ctor === "BBlack") { + return true; + } else { + break _v8_2; + } + } else { + if (_p2._0.ctor === "LBBlack") { + return true; + } else { + break _v8_2; + } + } + } while (false); + return false; + }; + var Same = {ctor: "Same"}; + var Remove = {ctor: "Remove"}; + var Insert = {ctor: "Insert"}; + var sizeHelp = F2(function (n,dict) { + sizeHelp: while (true) { + var _p3 = dict; + if (_p3.ctor === "RBEmpty_elm_builtin") { + return n; + } else { + var _v10 = A2(sizeHelp,n + 1,_p3._4),_v11 = _p3._3; + n = _v10; + dict = _v11; + continue sizeHelp; + } + } + }); + var size = function (dict) { return A2(sizeHelp,0,dict);}; + var get = F2(function (targetKey,dict) { + get: while (true) { + var _p4 = dict; + if (_p4.ctor === "RBEmpty_elm_builtin") { + return $Maybe.Nothing; + } else { + var _p5 = A2($Basics.compare,targetKey,_p4._1); + switch (_p5.ctor) + {case "LT": var _v14 = targetKey,_v15 = _p4._3; + targetKey = _v14; + dict = _v15; + continue get; + case "EQ": return $Maybe.Just(_p4._2); + default: var _v16 = targetKey,_v17 = _p4._4; + targetKey = _v16; + dict = _v17; + continue get;} + } + } + }); + var member = F2(function (key,dict) { var _p6 = A2(get,key,dict);if (_p6.ctor === "Just") { return true;} else { return false;}}); + var maxWithDefault = F3(function (k,v,r) { + maxWithDefault: while (true) { + var _p7 = r; + if (_p7.ctor === "RBEmpty_elm_builtin") { + return {ctor: "_Tuple2",_0: k,_1: v}; + } else { + var _v20 = _p7._1,_v21 = _p7._2,_v22 = _p7._4; + k = _v20; + v = _v21; + r = _v22; + continue maxWithDefault; + } + } + }); + var RBEmpty_elm_builtin = function (a) { return {ctor: "RBEmpty_elm_builtin",_0: a};}; + var RBNode_elm_builtin = F5(function (a,b,c,d,e) { return {ctor: "RBNode_elm_builtin",_0: a,_1: b,_2: c,_3: d,_4: e};}); + var LBBlack = {ctor: "LBBlack"}; + var LBlack = {ctor: "LBlack"}; + var empty = RBEmpty_elm_builtin(LBlack); + var isEmpty = function (dict) { return _U.eq(dict,empty);}; + var map = F2(function (f,dict) { + var _p8 = dict; + if (_p8.ctor === "RBEmpty_elm_builtin") { + return RBEmpty_elm_builtin(LBlack); + } else { + var _p9 = _p8._1; + return A5(RBNode_elm_builtin,_p8._0,_p9,A2(f,_p9,_p8._2),A2(map,f,_p8._3),A2(map,f,_p8._4)); + } + }); + var NBlack = {ctor: "NBlack"}; + var BBlack = {ctor: "BBlack"}; + var Black = {ctor: "Black"}; + var ensureBlackRoot = function (dict) { + var _p10 = dict; + if (_p10.ctor === "RBNode_elm_builtin" && _p10._0.ctor === "Red") { + return A5(RBNode_elm_builtin,Black,_p10._1,_p10._2,_p10._3,_p10._4); + } else { + return dict; + } + }; + var blackish = function (t) { + var _p11 = t; + if (_p11.ctor === "RBNode_elm_builtin") { + var _p12 = _p11._0; + return _U.eq(_p12,Black) || _U.eq(_p12,BBlack); + } else { + return true; + } + }; + var blacken = function (t) { + var _p13 = t; + if (_p13.ctor === "RBEmpty_elm_builtin") { + return RBEmpty_elm_builtin(LBlack); + } else { + return A5(RBNode_elm_builtin,Black,_p13._1,_p13._2,_p13._3,_p13._4); + } + }; + var Red = {ctor: "Red"}; + var moreBlack = function (color) { + var _p14 = color; + switch (_p14.ctor) + {case "Black": return BBlack; + case "Red": return Black; + case "NBlack": return Red; + default: return $Native$Debug.crash("Can\'t make a double black node more black!");} + }; + var lessBlack = function (color) { + var _p15 = color; + switch (_p15.ctor) + {case "BBlack": return Black; + case "Black": return Red; + case "Red": return NBlack; + default: return $Native$Debug.crash("Can\'t make a negative black node less black!");} + }; + var lessBlackTree = function (dict) { + var _p16 = dict; + if (_p16.ctor === "RBNode_elm_builtin") { + return A5(RBNode_elm_builtin,lessBlack(_p16._0),_p16._1,_p16._2,_p16._3,_p16._4); + } else { + return RBEmpty_elm_builtin(LBlack); + } + }; + var balancedTree = function (col) { + return function (xk) { + return function (xv) { + return function (yk) { + return function (yv) { + return function (zk) { + return function (zv) { + return function (a) { + return function (b) { + return function (c) { + return function (d) { + return A5(RBNode_elm_builtin, + lessBlack(col), + yk, + yv, + A5(RBNode_elm_builtin,Black,xk,xv,a,b), + A5(RBNode_elm_builtin,Black,zk,zv,c,d)); + }; + }; + }; + }; + }; + }; + }; + }; + }; + }; + }; + var redden = function (t) { + var _p17 = t; + if (_p17.ctor === "RBEmpty_elm_builtin") { + return $Native$Debug.crash("can\'t make a Leaf red"); + } else { + return A5(RBNode_elm_builtin,Red,_p17._1,_p17._2,_p17._3,_p17._4); + } + }; + var balanceHelp = function (tree) { + var _p18 = tree; + _v31_6: do { + _v31_5: do { + _v31_4: do { + _v31_3: do { + _v31_2: do { + _v31_1: do { + _v31_0: do { + if (_p18.ctor === "RBNode_elm_builtin") { + if (_p18._3.ctor === "RBNode_elm_builtin") { + if (_p18._4.ctor === "RBNode_elm_builtin") { + switch (_p18._3._0.ctor) + {case "Red": switch (_p18._4._0.ctor) + {case "Red": if (_p18._3._3.ctor === "RBNode_elm_builtin" && _p18._3._3._0.ctor === "Red") { + break _v31_0; + } else { + if (_p18._3._4.ctor === "RBNode_elm_builtin" && _p18._3._4._0.ctor === "Red") { + break _v31_1; + } else { + if (_p18._4._3.ctor === "RBNode_elm_builtin" && _p18._4._3._0.ctor === "Red") { + break _v31_2; + } else { + if (_p18._4._4.ctor === "RBNode_elm_builtin" && _p18._4._4._0.ctor === "Red") { + break _v31_3; + } else { + break _v31_6; + } + } + } + } + case "NBlack": if (_p18._3._3.ctor === "RBNode_elm_builtin" && _p18._3._3._0.ctor === "Red") { + break _v31_0; + } else { + if (_p18._3._4.ctor === "RBNode_elm_builtin" && _p18._3._4._0.ctor === "Red") { + break _v31_1; + } else { + if (_p18._0.ctor === "BBlack" && _p18._4._3.ctor === "RBNode_elm_builtin" && _p18._4._3._0.ctor === "Black" && _p18._4._4.ctor === "RBNode_elm_builtin" && _p18._4._4._0.ctor === "Black") + { + break _v31_4; + } else { + break _v31_6; + } + } + } + default: if (_p18._3._3.ctor === "RBNode_elm_builtin" && _p18._3._3._0.ctor === "Red") { + break _v31_0; + } else { + if (_p18._3._4.ctor === "RBNode_elm_builtin" && _p18._3._4._0.ctor === "Red") { + break _v31_1; + } else { + break _v31_6; + } + }} + case "NBlack": switch (_p18._4._0.ctor) + {case "Red": if (_p18._4._3.ctor === "RBNode_elm_builtin" && _p18._4._3._0.ctor === "Red") { + break _v31_2; + } else { + if (_p18._4._4.ctor === "RBNode_elm_builtin" && _p18._4._4._0.ctor === "Red") { + break _v31_3; + } else { + if (_p18._0.ctor === "BBlack" && _p18._3._3.ctor === "RBNode_elm_builtin" && _p18._3._3._0.ctor === "Black" && _p18._3._4.ctor === "RBNode_elm_builtin" && _p18._3._4._0.ctor === "Black") + { + break _v31_5; + } else { + break _v31_6; + } + } + } + case "NBlack": if (_p18._0.ctor === "BBlack") { + if (_p18._4._3.ctor === "RBNode_elm_builtin" && _p18._4._3._0.ctor === "Black" && _p18._4._4.ctor === "RBNode_elm_builtin" && _p18._4._4._0.ctor === "Black") + { + break _v31_4; + } else { + if (_p18._3._3.ctor === "RBNode_elm_builtin" && _p18._3._3._0.ctor === "Black" && _p18._3._4.ctor === "RBNode_elm_builtin" && _p18._3._4._0.ctor === "Black") + { + break _v31_5; + } else { + break _v31_6; + } + } + } else { + break _v31_6; + } + default: + if (_p18._0.ctor === "BBlack" && _p18._3._3.ctor === "RBNode_elm_builtin" && _p18._3._3._0.ctor === "Black" && _p18._3._4.ctor === "RBNode_elm_builtin" && _p18._3._4._0.ctor === "Black") + { + break _v31_5; + } else { + break _v31_6; + }} + default: switch (_p18._4._0.ctor) + {case "Red": if (_p18._4._3.ctor === "RBNode_elm_builtin" && _p18._4._3._0.ctor === "Red") { + break _v31_2; + } else { + if (_p18._4._4.ctor === "RBNode_elm_builtin" && _p18._4._4._0.ctor === "Red") { + break _v31_3; + } else { + break _v31_6; + } + } + case "NBlack": + if (_p18._0.ctor === "BBlack" && _p18._4._3.ctor === "RBNode_elm_builtin" && _p18._4._3._0.ctor === "Black" && _p18._4._4.ctor === "RBNode_elm_builtin" && _p18._4._4._0.ctor === "Black") + { + break _v31_4; + } else { + break _v31_6; + } + default: break _v31_6;}} + } else { + switch (_p18._3._0.ctor) + {case "Red": if (_p18._3._3.ctor === "RBNode_elm_builtin" && _p18._3._3._0.ctor === "Red") { + break _v31_0; + } else { + if (_p18._3._4.ctor === "RBNode_elm_builtin" && _p18._3._4._0.ctor === "Red") { + break _v31_1; + } else { + break _v31_6; + } + } + case "NBlack": + if (_p18._0.ctor === "BBlack" && _p18._3._3.ctor === "RBNode_elm_builtin" && _p18._3._3._0.ctor === "Black" && _p18._3._4.ctor === "RBNode_elm_builtin" && _p18._3._4._0.ctor === "Black") + { + break _v31_5; + } else { + break _v31_6; + } + default: break _v31_6;} + } + } else { + if (_p18._4.ctor === "RBNode_elm_builtin") { + switch (_p18._4._0.ctor) + {case "Red": if (_p18._4._3.ctor === "RBNode_elm_builtin" && _p18._4._3._0.ctor === "Red") { + break _v31_2; + } else { + if (_p18._4._4.ctor === "RBNode_elm_builtin" && _p18._4._4._0.ctor === "Red") { + break _v31_3; + } else { + break _v31_6; + } + } + case "NBlack": + if (_p18._0.ctor === "BBlack" && _p18._4._3.ctor === "RBNode_elm_builtin" && _p18._4._3._0.ctor === "Black" && _p18._4._4.ctor === "RBNode_elm_builtin" && _p18._4._4._0.ctor === "Black") + { + break _v31_4; + } else { + break _v31_6; + } + default: break _v31_6;} + } else { + break _v31_6; + } + } + } else { + break _v31_6; + } + } while (false); + return balancedTree(_p18._0)(_p18._3._3._1)(_p18._3._3._2)(_p18._3._1)(_p18._3._2)(_p18._1)(_p18._2)(_p18._3._3._3)(_p18._3._3._4)(_p18._3._4)(_p18._4); + } while (false); + return balancedTree(_p18._0)(_p18._3._1)(_p18._3._2)(_p18._3._4._1)(_p18._3._4._2)(_p18._1)(_p18._2)(_p18._3._3)(_p18._3._4._3)(_p18._3._4._4)(_p18._4); + } while (false); + return balancedTree(_p18._0)(_p18._1)(_p18._2)(_p18._4._3._1)(_p18._4._3._2)(_p18._4._1)(_p18._4._2)(_p18._3)(_p18._4._3._3)(_p18._4._3._4)(_p18._4._4); + } while (false); + return balancedTree(_p18._0)(_p18._1)(_p18._2)(_p18._4._1)(_p18._4._2)(_p18._4._4._1)(_p18._4._4._2)(_p18._3)(_p18._4._3)(_p18._4._4._3)(_p18._4._4._4); + } while (false); + return A5(RBNode_elm_builtin, + Black, + _p18._4._3._1, + _p18._4._3._2, + A5(RBNode_elm_builtin,Black,_p18._1,_p18._2,_p18._3,_p18._4._3._3), + A5(balance,Black,_p18._4._1,_p18._4._2,_p18._4._3._4,redden(_p18._4._4))); + } while (false); + return A5(RBNode_elm_builtin, + Black, + _p18._3._4._1, + _p18._3._4._2, + A5(balance,Black,_p18._3._1,_p18._3._2,redden(_p18._3._3),_p18._3._4._3), + A5(RBNode_elm_builtin,Black,_p18._1,_p18._2,_p18._3._4._4,_p18._4)); + } while (false); + return tree; + }; + var balance = F5(function (c,k,v,l,r) { var tree = A5(RBNode_elm_builtin,c,k,v,l,r);return blackish(tree) ? balanceHelp(tree) : tree;}); + var bubble = F5(function (c,k,v,l,r) { + return isBBlack(l) || isBBlack(r) ? A5(balance,moreBlack(c),k,v,lessBlackTree(l),lessBlackTree(r)) : A5(RBNode_elm_builtin,c,k,v,l,r); + }); + var removeMax = F5(function (c,k,v,l,r) { + var _p19 = r; + if (_p19.ctor === "RBEmpty_elm_builtin") { + return A3(rem,c,l,r); + } else { + return A5(bubble,c,k,v,l,A5(removeMax,_p19._0,_p19._1,_p19._2,_p19._3,_p19._4)); + } + }); + var rem = F3(function (c,l,r) { + var _p20 = {ctor: "_Tuple2",_0: l,_1: r}; + if (_p20._0.ctor === "RBEmpty_elm_builtin") { + if (_p20._1.ctor === "RBEmpty_elm_builtin") { + var _p21 = c; + switch (_p21.ctor) + {case "Red": return RBEmpty_elm_builtin(LBlack); + case "Black": return RBEmpty_elm_builtin(LBBlack); + default: return $Native$Debug.crash("cannot have bblack or nblack nodes at this point");} + } else { + var _p24 = _p20._1._0; + var _p23 = _p20._0._0; + var _p22 = {ctor: "_Tuple3",_0: c,_1: _p23,_2: _p24}; + if (_p22.ctor === "_Tuple3" && _p22._0.ctor === "Black" && _p22._1.ctor === "LBlack" && _p22._2.ctor === "Red") { + return A5(RBNode_elm_builtin,Black,_p20._1._1,_p20._1._2,_p20._1._3,_p20._1._4); + } else { + return A4(reportRemBug,"Black/LBlack/Red",c,$Basics.toString(_p23),$Basics.toString(_p24)); + } + } + } else { + if (_p20._1.ctor === "RBEmpty_elm_builtin") { + var _p27 = _p20._1._0; + var _p26 = _p20._0._0; + var _p25 = {ctor: "_Tuple3",_0: c,_1: _p26,_2: _p27}; + if (_p25.ctor === "_Tuple3" && _p25._0.ctor === "Black" && _p25._1.ctor === "Red" && _p25._2.ctor === "LBlack") { + return A5(RBNode_elm_builtin,Black,_p20._0._1,_p20._0._2,_p20._0._3,_p20._0._4); + } else { + return A4(reportRemBug,"Black/Red/LBlack",c,$Basics.toString(_p26),$Basics.toString(_p27)); + } + } else { + var _p31 = _p20._0._2; + var _p30 = _p20._0._4; + var _p29 = _p20._0._1; + var l$ = A5(removeMax,_p20._0._0,_p29,_p31,_p20._0._3,_p30); + var _p28 = A3(maxWithDefault,_p29,_p31,_p30); + var k = _p28._0; + var v = _p28._1; + return A5(bubble,c,k,v,l$,r); + } + } + }); + var update = F3(function (k,alter,dict) { + var up = function (dict) { + var _p32 = dict; + if (_p32.ctor === "RBEmpty_elm_builtin") { + var _p33 = alter($Maybe.Nothing); + if (_p33.ctor === "Nothing") { + return {ctor: "_Tuple2",_0: Same,_1: empty}; + } else { + return {ctor: "_Tuple2",_0: Insert,_1: A5(RBNode_elm_builtin,Red,k,_p33._0,empty,empty)}; + } + } else { + var _p44 = _p32._2; + var _p43 = _p32._4; + var _p42 = _p32._3; + var _p41 = _p32._1; + var _p40 = _p32._0; + var _p34 = A2($Basics.compare,k,_p41); + switch (_p34.ctor) + {case "EQ": var _p35 = alter($Maybe.Just(_p44)); + if (_p35.ctor === "Nothing") { + return {ctor: "_Tuple2",_0: Remove,_1: A3(rem,_p40,_p42,_p43)}; + } else { + return {ctor: "_Tuple2",_0: Same,_1: A5(RBNode_elm_builtin,_p40,_p41,_p35._0,_p42,_p43)}; + } + case "LT": var _p36 = up(_p42); + var flag = _p36._0; + var newLeft = _p36._1; + var _p37 = flag; + switch (_p37.ctor) + {case "Same": return {ctor: "_Tuple2",_0: Same,_1: A5(RBNode_elm_builtin,_p40,_p41,_p44,newLeft,_p43)}; + case "Insert": return {ctor: "_Tuple2",_0: Insert,_1: A5(balance,_p40,_p41,_p44,newLeft,_p43)}; + default: return {ctor: "_Tuple2",_0: Remove,_1: A5(bubble,_p40,_p41,_p44,newLeft,_p43)};} + default: var _p38 = up(_p43); + var flag = _p38._0; + var newRight = _p38._1; + var _p39 = flag; + switch (_p39.ctor) + {case "Same": return {ctor: "_Tuple2",_0: Same,_1: A5(RBNode_elm_builtin,_p40,_p41,_p44,_p42,newRight)}; + case "Insert": return {ctor: "_Tuple2",_0: Insert,_1: A5(balance,_p40,_p41,_p44,_p42,newRight)}; + default: return {ctor: "_Tuple2",_0: Remove,_1: A5(bubble,_p40,_p41,_p44,_p42,newRight)};}} + } + }; + var _p45 = up(dict); + var flag = _p45._0; + var updatedDict = _p45._1; + var _p46 = flag; + switch (_p46.ctor) + {case "Same": return updatedDict; + case "Insert": return ensureBlackRoot(updatedDict); + default: return blacken(updatedDict);} + }); + var insert = F3(function (key,value,dict) { return A3(update,key,$Basics.always($Maybe.Just(value)),dict);}); + var singleton = F2(function (key,value) { return A3(insert,key,value,empty);}); + var union = F2(function (t1,t2) { return A3(foldl,insert,t2,t1);}); + var fromList = function (assocs) { + return A3($List.foldl,F2(function (_p47,dict) { var _p48 = _p47;return A3(insert,_p48._0,_p48._1,dict);}),empty,assocs); + }; + var filter = F2(function (predicate,dictionary) { + var add = F3(function (key,value,dict) { return A2(predicate,key,value) ? A3(insert,key,value,dict) : dict;}); + return A3(foldl,add,empty,dictionary); + }); + var intersect = F2(function (t1,t2) { return A2(filter,F2(function (k,_p49) { return A2(member,k,t2);}),t1);}); + var partition = F2(function (predicate,dict) { + var add = F3(function (key,value,_p50) { + var _p51 = _p50; + var _p53 = _p51._1; + var _p52 = _p51._0; + return A2(predicate,key,value) ? {ctor: "_Tuple2",_0: A3(insert,key,value,_p52),_1: _p53} : {ctor: "_Tuple2",_0: _p52,_1: A3(insert,key,value,_p53)}; + }); + return A3(foldl,add,{ctor: "_Tuple2",_0: empty,_1: empty},dict); + }); + var remove = F2(function (key,dict) { return A3(update,key,$Basics.always($Maybe.Nothing),dict);}); + var diff = F2(function (t1,t2) { return A3(foldl,F3(function (k,v,t) { return A2(remove,k,t);}),t1,t2);}); + return _elm.Dict.values = {_op: _op + ,empty: empty + ,singleton: singleton + ,insert: insert + ,update: update + ,isEmpty: isEmpty + ,get: get + ,remove: remove + ,member: member + ,size: size + ,filter: filter + ,partition: partition + ,foldl: foldl + ,foldr: foldr + ,map: map + ,union: union + ,intersect: intersect + ,diff: diff + ,keys: keys + ,values: values + ,toList: toList + ,fromList: fromList}; +}; +Elm.Native.Json = {}; + +Elm.Native.Json.make = function(localRuntime) { localRuntime.Native = localRuntime.Native || {}; - localRuntime.Native.String = localRuntime.Native.String || {}; - if (localRuntime.Native.String.values) - { - return localRuntime.Native.String.values; - } - if ('values' in Elm.Native.String) - { - return localRuntime.Native.String.values = Elm.Native.String.values; + localRuntime.Native.Json = localRuntime.Native.Json || {}; + if (localRuntime.Native.Json.values) { + return localRuntime.Native.Json.values; } - - var Char = Elm.Char.make(localRuntime); + var ElmArray = Elm.Native.Array.make(localRuntime); var List = Elm.Native.List.make(localRuntime); var Maybe = Elm.Maybe.make(localRuntime); var Result = Elm.Result.make(localRuntime); var Utils = Elm.Native.Utils.make(localRuntime); - function isEmpty(str) - { - return str.length === 0; - } - function cons(chr,str) - { - return chr + str; - } - function uncons(str) - { - var hd; - return (hd = str[0]) - ? Maybe.Just(Utils.Tuple2(Utils.chr(hd), str.slice(1))) - : Maybe.Nothing; - } - function append(a,b) - { - return a + b; - } - function concat(strs) - { - return List.toArray(strs).join(''); - } - function length(str) - { - return str.length; - } - function map(f,str) - { - var out = str.split(''); - for (var i = out.length; i--; ) - { - out[i] = f(Utils.chr(out[i])); - } - return out.join(''); - } - function filter(pred,str) - { - return str.split('').map(Utils.chr).filter(pred).join(''); - } - function reverse(str) - { - return str.split('').reverse().join(''); - } - function foldl(f,b,str) - { - var len = str.length; - for (var i = 0; i < len; ++i) - { - b = A2(f, Utils.chr(str[i]), b); - } - return b; - } - function foldr(f,b,str) - { - for (var i = str.length; i--; ) - { - b = A2(f, Utils.chr(str[i]), b); - } - return b; - } - - function split(sep, str) - { - return List.fromArray(str.split(sep)); - } - function join(sep, strs) - { - return List.toArray(strs).join(sep); - } - function repeat(n, str) - { - var result = ''; - while (n > 0) - { - if (n & 1) - { - result += str; - } - n >>= 1, str += str; - } - return result; - } - - function slice(start, end, str) - { - return str.slice(start,end); - } - function left(n, str) - { - return n < 1 ? "" : str.slice(0,n); - } - function right(n, str) - { - return n < 1 ? "" : str.slice(-n); - } - function dropLeft(n, str) - { - return n < 1 ? str : str.slice(n); - } - function dropRight(n, str) - { - return n < 1 ? str : str.slice(0,-n); - } - - function pad(n,chr,str) - { - var half = (n - str.length) / 2; - return repeat(Math.ceil(half),chr) + str + repeat(half|0,chr); - } - function padRight(n,chr,str) - { - return str + repeat(n - str.length, chr); - } - function padLeft(n,chr,str) - { - return repeat(n - str.length, chr) + str; - } - function trim(str) - { - return str.trim(); - } - function trimLeft(str) - { - return str.trimLeft(); - } - function trimRight(str) - { - return str.trimRight(); + function crash(expected, actual) { + throw new Error( + 'expecting ' + expected + ' but got ' + JSON.stringify(actual) + ); } - function words(str) - { - return List.fromArray(str.trim().split(/\s+/g)); - } - function lines(str) - { - return List.fromArray(str.split(/\r\n|\r|\n/g)); - } - function toUpper(str) - { - return str.toUpperCase(); - } - function toLower(str) - { - return str.toLowerCase(); - } + // PRIMITIVE VALUES - function any(pred, str) - { - for (var i = str.length; i--; ) - { - if (pred(Utils.chr(str[i]))) - { - return true; - } - } - return false; - } - function all(pred, str) - { - for (var i = str.length; i--; ) - { - if (!pred(Utils.chr(str[i]))) - { - return false; + function decodeNull(successValue) { + return function(value) { + if (value === null) { + return successValue; } - } - return true; - } - - function contains(sub, str) - { - return str.indexOf(sub) > -1; - } - function startsWith(sub, str) - { - return str.indexOf(sub) === 0; - } - function endsWith(sub, str) - { - return str.length >= sub.length && - str.lastIndexOf(sub) === str.length - sub.length; + crash('null', value); + }; } - function indexes(sub, str) - { - var subLen = sub.length; - var i = 0; - var is = []; - while ((i = str.indexOf(sub, i)) > -1) - { - is.push(i); - i = i + subLen; + + + function decodeString(value) { + if (typeof value === 'string' || value instanceof String) { + return value; } - return List.fromArray(is); + crash('a String', value); } - function toInt(s) - { - var len = s.length; - if (len === 0) - { - return Result.Err("could not convert string '" + s + "' to an Int" ); + + function decodeFloat(value) { + if (typeof value === 'number') { + return value; } - var start = 0; - if (s[0] == '-') - { - if (len === 1) - { - return Result.Err("could not convert string '" + s + "' to an Int" ); - } - start = 1; + crash('a Float', value); + } + + + function decodeInt(value) { + if (typeof value !== 'number') { + crash('an Int', value); } - for (var i = start; i < len; ++i) - { - if (!Char.isDigit(s[i])) - { - return Result.Err("could not convert string '" + s + "' to an Int" ); - } + + if (value < 2147483647 && value > -2147483647 && (value | 0) === value) { + return value; } - return Result.Ok(parseInt(s, 10)); - } - function toFloat(s) - { - var len = s.length; - if (len === 0) - { - return Result.Err("could not convert string '" + s + "' to a Float" ); + if (isFinite(value) && !(value % 1)) { + return value; } - var start = 0; - if (s[0] == '-') - { - if (len === 1) - { - return Result.Err("could not convert string '" + s + "' to a Float" ); - } - start = 1; + + crash('an Int', value); + } + + + function decodeBool(value) { + if (typeof value === 'boolean') { + return value; } - var dotCount = 0; - for (var i = start; i < len; ++i) - { - if (Char.isDigit(s[i])) - { - continue; + crash('a Bool', value); + } + + + // ARRAY + + function decodeArray(decoder) { + return function(value) { + if (value instanceof Array) { + var len = value.length; + var array = new Array(len); + for (var i = len; i--; ) { + array[i] = decoder(value[i]); + } + return ElmArray.fromJSArray(array); } - if (s[i] === '.') - { - dotCount += 1; - if (dotCount <= 1) - { - continue; + crash('an Array', value); + }; + } + + + // LIST + + function decodeList(decoder) { + return function(value) { + if (value instanceof Array) { + var len = value.length; + var list = List.Nil; + for (var i = len; i--; ) { + list = List.Cons( decoder(value[i]), list ); } + return list; } - return Result.Err("could not convert string '" + s + "' to a Float" ); - } - return Result.Ok(parseFloat(s)); + crash('a List', value); + }; } - function toList(str) - { - return List.fromArray(str.split('').map(Utils.chr)); + + // MAYBE + + function decodeMaybe(decoder) { + return function(value) { + try { + return Maybe.Just(decoder(value)); + } catch(e) { + return Maybe.Nothing; + } + }; } - function fromList(chars) - { - return List.toArray(chars).join(''); + + + // FIELDS + + function decodeField(field, decoder) { + return function(value) { + var subValue = value[field]; + if (subValue !== undefined) { + return decoder(subValue); + } + crash("an object with field '" + field + "'", value); + }; } - return Elm.Native.String.values = { - isEmpty: isEmpty, - cons: F2(cons), - uncons: uncons, - append: F2(append), - concat: concat, - length: length, - map: F2(map), - filter: F2(filter), - reverse: reverse, - foldl: F3(foldl), - foldr: F3(foldr), - split: F2(split), - join: F2(join), - repeat: F2(repeat), + // OBJECTS - slice: F3(slice), - left: F2(left), - right: F2(right), - dropLeft: F2(dropLeft), - dropRight: F2(dropRight), + function decodeKeyValuePairs(decoder) { + return function(value) { + var isObject = + typeof value === 'object' + && value !== null + && !(value instanceof Array); - pad: F3(pad), - padLeft: F3(padLeft), - padRight: F3(padRight), + if (isObject) { + var keyValuePairs = List.Nil; + for (var key in value) + { + var elmValue = decoder(value[key]); + var pair = Utils.Tuple2(key, elmValue); + keyValuePairs = List.Cons(pair, keyValuePairs); + } + return keyValuePairs; + } - trim: trim, - trimLeft: trimLeft, - trimRight: trimRight, + crash('an object', value); + }; + } - words: words, - lines: lines, + function decodeObject1(f, d1) { + return function(value) { + return f(d1(value)); + }; + } - toUpper: toUpper, - toLower: toLower, + function decodeObject2(f, d1, d2) { + return function(value) { + return A2( f, d1(value), d2(value) ); + }; + } - any: F2(any), - all: F2(all), + function decodeObject3(f, d1, d2, d3) { + return function(value) { + return A3( f, d1(value), d2(value), d3(value) ); + }; + } - contains: F2(contains), - startsWith: F2(startsWith), - endsWith: F2(endsWith), - indexes: F2(indexes), + function decodeObject4(f, d1, d2, d3, d4) { + return function(value) { + return A4( f, d1(value), d2(value), d3(value), d4(value) ); + }; + } - toInt: toInt, - toFloat: toFloat, - toList: toList, - fromList: fromList - }; -}; + function decodeObject5(f, d1, d2, d3, d4, d5) { + return function(value) { + return A5( f, d1(value), d2(value), d3(value), d4(value), d5(value) ); + }; + } -Elm.Native.Task = {}; -Elm.Native.Task.make = function(localRuntime) { + function decodeObject6(f, d1, d2, d3, d4, d5, d6) { + return function(value) { + return A6( f, + d1(value), + d2(value), + d3(value), + d4(value), + d5(value), + d6(value) + ); + }; + } - localRuntime.Native = localRuntime.Native || {}; - localRuntime.Native.Task = localRuntime.Native.Task || {}; - if (localRuntime.Native.Task.values) - { - return localRuntime.Native.Task.values; + function decodeObject7(f, d1, d2, d3, d4, d5, d6, d7) { + return function(value) { + return A7( f, + d1(value), + d2(value), + d3(value), + d4(value), + d5(value), + d6(value), + d7(value) + ); + }; + } + + function decodeObject8(f, d1, d2, d3, d4, d5, d6, d7, d8) { + return function(value) { + return A8( f, + d1(value), + d2(value), + d3(value), + d4(value), + d5(value), + d6(value), + d7(value), + d8(value) + ); + }; } - var Result = Elm.Result.make(localRuntime); - var Signal; - var Utils = Elm.Native.Utils.make(localRuntime); - - // CONSTRUCTORS + // TUPLES - function succeed(value) - { - return { - tag: 'Succeed', - value: value + function decodeTuple1(f, d1) { + return function(value) { + if ( !(value instanceof Array) || value.length !== 1 ) { + crash('a Tuple of length 1', value); + } + return f( d1(value[0]) ); }; } - function fail(error) - { - return { - tag: 'Fail', - value: error + function decodeTuple2(f, d1, d2) { + return function(value) { + if ( !(value instanceof Array) || value.length !== 2 ) { + crash('a Tuple of length 2', value); + } + return A2( f, d1(value[0]), d2(value[1]) ); }; } - function asyncFunction(func) - { - return { - tag: 'Async', - asyncFunction: func + function decodeTuple3(f, d1, d2, d3) { + return function(value) { + if ( !(value instanceof Array) || value.length !== 3 ) { + crash('a Tuple of length 3', value); + } + return A3( f, d1(value[0]), d2(value[1]), d3(value[2]) ); }; } - function andThen(task, callback) - { - return { - tag: 'AndThen', - task: task, - callback: callback + + function decodeTuple4(f, d1, d2, d3, d4) { + return function(value) { + if ( !(value instanceof Array) || value.length !== 4 ) { + crash('a Tuple of length 4', value); + } + return A4( f, d1(value[0]), d2(value[1]), d3(value[2]), d4(value[3]) ); }; } - function catch_(task, callback) - { - return { - tag: 'Catch', - task: task, - callback: callback + + function decodeTuple5(f, d1, d2, d3, d4, d5) { + return function(value) { + if ( !(value instanceof Array) || value.length !== 5 ) { + crash('a Tuple of length 5', value); + } + return A5( f, + d1(value[0]), + d2(value[1]), + d3(value[2]), + d4(value[3]), + d5(value[4]) + ); }; } - // RUNNER - - function perform(task) { - runTask({ task: task }, function() {}); + function decodeTuple6(f, d1, d2, d3, d4, d5, d6) { + return function(value) { + if ( !(value instanceof Array) || value.length !== 6 ) { + crash('a Tuple of length 6', value); + } + return A6( f, + d1(value[0]), + d2(value[1]), + d3(value[2]), + d4(value[3]), + d5(value[4]), + d6(value[5]) + ); + }; } - function performSignal(name, signal) - { - var workQueue = []; - - function onComplete() - { - workQueue.shift(); + function decodeTuple7(f, d1, d2, d3, d4, d5, d6, d7) { + return function(value) { + if ( !(value instanceof Array) || value.length !== 7 ) { + crash('a Tuple of length 7', value); + } + return A7( f, + d1(value[0]), + d2(value[1]), + d3(value[2]), + d4(value[3]), + d5(value[4]), + d6(value[5]), + d7(value[6]) + ); + }; + } - setTimeout(function() { - if (workQueue.length > 0) - { - runTask(workQueue[0], onComplete); - } - }, 0); - } - function register(task) - { - var root = { task: task }; - workQueue.push(root); - if (workQueue.length === 1) - { - runTask(root, onComplete); + function decodeTuple8(f, d1, d2, d3, d4, d5, d6, d7, d8) { + return function(value) { + if ( !(value instanceof Array) || value.length !== 8 ) { + crash('a Tuple of length 8', value); } - } + return A8( f, + d1(value[0]), + d2(value[1]), + d3(value[2]), + d4(value[3]), + d5(value[4]), + d6(value[5]), + d7(value[6]), + d8(value[7]) + ); + }; + } - if (!Signal) - { - Signal = Elm.Native.Signal.make(localRuntime); - } - Signal.output('perform-tasks-' + name, register, signal); - register(signal.value); + // CUSTOM DECODERS - return signal; + function decodeValue(value) { + return value; } - function mark(status, task) - { - return { status: status, task: task }; + function runDecoderValue(decoder, value) { + try { + return Result.Ok(decoder(value)); + } catch(e) { + return Result.Err(e.message); + } } - function runTask(root, onComplete) - { - var result = mark('runnable', root.task); - while (result.status === 'runnable') - { - result = stepTask(onComplete, root, result.task); - } + function customDecoder(decoder, callback) { + return function(value) { + var result = callback(decoder(value)); + if (result.ctor === 'Err') { + throw new Error('custom decoder failed: ' + result._0); + } + return result._0; + }; + } - if (result.status === 'done') - { - root.task = result.task; - onComplete(); - } + function andThen(decode, callback) { + return function(value) { + var result = decode(value); + return callback(result)(value); + }; + } - if (result.status === 'blocked') - { - root.task = result.task; - } + function fail(msg) { + return function(value) { + throw new Error(msg); + }; } - function stepTask(onComplete, root, task) - { - var tag = task.tag; + function succeed(successValue) { + return function(value) { + return successValue; + }; + } - if (tag === 'Succeed' || tag === 'Fail') - { - return mark('done', task); - } - if (tag === 'Async') - { - var placeHolder = {}; - var couldBeSync = true; - var wasSync = false; + // ONE OF MANY - task.asyncFunction(function(result) { - placeHolder.tag = result.tag; - placeHolder.value = result.value; - if (couldBeSync) - { - wasSync = true; - } - else - { - runTask(root, onComplete); + function oneOf(decoders) { + return function(value) { + var errors = []; + var temp = decoders; + while (temp.ctor !== '[]') { + try { + return temp._0(value); + } catch(e) { + errors.push(e.message); } - }); - couldBeSync = false; - return mark(wasSync ? 'done' : 'blocked', placeHolder); + temp = temp._1; + } + throw new Error('expecting one of the following:\n ' + errors.join('\n ')); + }; + } + + function get(decoder, value) { + try { + return Result.Ok(decoder(value)); + } catch(e) { + return Result.Err(e.message); } + } - if (tag === 'AndThen' || tag === 'Catch') - { - var result = mark('runnable', task.task); - while (result.status === 'runnable') - { - result = stepTask(onComplete, root, result.task); - } - - if (result.status === 'done') - { - var activeTask = result.task; - var activeTag = activeTask.tag; - var succeedChain = activeTag === 'Succeed' && tag === 'AndThen'; - var failChain = activeTag === 'Fail' && tag === 'Catch'; + // ENCODE / DECODE - return (succeedChain || failChain) - ? mark('runnable', task.callback(activeTask.value)) - : mark('runnable', activeTask); - } - if (result.status === 'blocked') - { - return mark('blocked', { - tag: tag, - task: result.task, - callback: task.callback - }); - } + function runDecoderString(decoder, string) { + try { + return Result.Ok(decoder(JSON.parse(string))); + } catch(e) { + return Result.Err(e.message); } } + function encode(indentLevel, value) { + return JSON.stringify(value, null, indentLevel); + } - // THREADS - - function sleep(time) { - return asyncFunction(function(callback) { - setTimeout(function() { - callback(succeed(Utils.Tuple0)); - }, time); - }); + function identity(value) { + return value; } - function spawn(task) { - return asyncFunction(function(callback) { - var id = setTimeout(function() { - perform(task); - }, 0); - callback(succeed(id)); - }); + function encodeObject(keyValuePairs) { + var obj = {}; + while (keyValuePairs.ctor !== '[]') { + var pair = keyValuePairs._0; + obj[pair._0] = pair._1; + keyValuePairs = keyValuePairs._1; + } + return obj; } + return localRuntime.Native.Json.values = { + encode: F2(encode), + runDecoderString: F2(runDecoderString), + runDecoderValue: F2(runDecoderValue), - return localRuntime.Native.Task.values = { - succeed: succeed, - fail: fail, - asyncFunction: asyncFunction, - andThen: F2(andThen), - catch_: F2(catch_), - perform: perform, - performSignal: performSignal, - spawn: spawn, - sleep: sleep - }; -}; + get: F2(get), + oneOf: oneOf, -Elm.Native.Text = {}; -Elm.Native.Text.make = function(localRuntime) { - localRuntime.Native = localRuntime.Native || {}; - localRuntime.Native.Text = localRuntime.Native.Text || {}; - if (localRuntime.Native.Text.values) - { - return localRuntime.Native.Text.values; - } + decodeNull: decodeNull, + decodeInt: decodeInt, + decodeFloat: decodeFloat, + decodeString: decodeString, + decodeBool: decodeBool, - var toCss = Elm.Native.Color.make(localRuntime).toCss; - var List = Elm.Native.List.make(localRuntime); + decodeMaybe: decodeMaybe, + decodeList: decodeList, + decodeArray: decodeArray, - // CONSTRUCTORS + decodeField: F2(decodeField), - function fromString(str) - { - return { - ctor: 'Text:Text', - _0: str - }; - } + decodeObject1: F2(decodeObject1), + decodeObject2: F3(decodeObject2), + decodeObject3: F4(decodeObject3), + decodeObject4: F5(decodeObject4), + decodeObject5: F6(decodeObject5), + decodeObject6: F7(decodeObject6), + decodeObject7: F8(decodeObject7), + decodeObject8: F9(decodeObject8), + decodeKeyValuePairs: decodeKeyValuePairs, - function append(a, b) - { - return { - ctor: 'Text:Append', - _0: a, - _1: b - }; - } + decodeTuple1: F2(decodeTuple1), + decodeTuple2: F3(decodeTuple2), + decodeTuple3: F4(decodeTuple3), + decodeTuple4: F5(decodeTuple4), + decodeTuple5: F6(decodeTuple5), + decodeTuple6: F7(decodeTuple6), + decodeTuple7: F8(decodeTuple7), + decodeTuple8: F9(decodeTuple8), - function addMeta(field, value, text) - { - var newProps = {}; - var newText = { - ctor: 'Text:Meta', - _0: newProps, - _1: text - }; + andThen: F2(andThen), + decodeValue: decodeValue, + customDecoder: F2(customDecoder), + fail: fail, + succeed: succeed, - if (text.ctor === 'Text:Meta') - { - newText._1 = text._1; - var props = text._0; - for (var i = metaKeys.length; i--; ) - { - var key = metaKeys[i]; - var val = props[key]; - if (val) - { - newProps[key] = val; - } - } - } - newProps[field] = value; - return newText; + identity: identity, + encodeNull: null, + encodeArray: ElmArray.toJSArray, + encodeList: List.toArray, + encodeObject: encodeObject + + }; +}; + +Elm.Json = Elm.Json || {}; +Elm.Json.Encode = Elm.Json.Encode || {}; +Elm.Json.Encode.make = function (_elm) { + "use strict"; + _elm.Json = _elm.Json || {}; + _elm.Json.Encode = _elm.Json.Encode || {}; + if (_elm.Json.Encode.values) return _elm.Json.Encode.values; + var _U = Elm.Native.Utils.make(_elm),$Array = Elm.Array.make(_elm),$Native$Json = Elm.Native.Json.make(_elm); + var _op = {}; + var list = $Native$Json.encodeList; + var array = $Native$Json.encodeArray; + var object = $Native$Json.encodeObject; + var $null = $Native$Json.encodeNull; + var bool = $Native$Json.identity; + var $float = $Native$Json.identity; + var $int = $Native$Json.identity; + var string = $Native$Json.identity; + var encode = $Native$Json.encode; + var Value = {ctor: "Value"}; + return _elm.Json.Encode.values = {_op: _op + ,encode: encode + ,string: string + ,$int: $int + ,$float: $float + ,bool: bool + ,$null: $null + ,list: list + ,array: array + ,object: object}; +}; +Elm.Json = Elm.Json || {}; +Elm.Json.Decode = Elm.Json.Decode || {}; +Elm.Json.Decode.make = function (_elm) { + "use strict"; + _elm.Json = _elm.Json || {}; + _elm.Json.Decode = _elm.Json.Decode || {}; + if (_elm.Json.Decode.values) return _elm.Json.Decode.values; + var _U = Elm.Native.Utils.make(_elm), + $Array = Elm.Array.make(_elm), + $Dict = Elm.Dict.make(_elm), + $Json$Encode = Elm.Json.Encode.make(_elm), + $List = Elm.List.make(_elm), + $Maybe = Elm.Maybe.make(_elm), + $Native$Json = Elm.Native.Json.make(_elm), + $Result = Elm.Result.make(_elm); + var _op = {}; + var tuple8 = $Native$Json.decodeTuple8; + var tuple7 = $Native$Json.decodeTuple7; + var tuple6 = $Native$Json.decodeTuple6; + var tuple5 = $Native$Json.decodeTuple5; + var tuple4 = $Native$Json.decodeTuple4; + var tuple3 = $Native$Json.decodeTuple3; + var tuple2 = $Native$Json.decodeTuple2; + var tuple1 = $Native$Json.decodeTuple1; + var succeed = $Native$Json.succeed; + var fail = $Native$Json.fail; + var andThen = $Native$Json.andThen; + var customDecoder = $Native$Json.customDecoder; + var decodeValue = $Native$Json.runDecoderValue; + var value = $Native$Json.decodeValue; + var maybe = $Native$Json.decodeMaybe; + var $null = $Native$Json.decodeNull; + var array = $Native$Json.decodeArray; + var list = $Native$Json.decodeList; + var bool = $Native$Json.decodeBool; + var $int = $Native$Json.decodeInt; + var $float = $Native$Json.decodeFloat; + var string = $Native$Json.decodeString; + var oneOf = $Native$Json.oneOf; + var keyValuePairs = $Native$Json.decodeKeyValuePairs; + var object8 = $Native$Json.decodeObject8; + var object7 = $Native$Json.decodeObject7; + var object6 = $Native$Json.decodeObject6; + var object5 = $Native$Json.decodeObject5; + var object4 = $Native$Json.decodeObject4; + var object3 = $Native$Json.decodeObject3; + var object2 = $Native$Json.decodeObject2; + var object1 = $Native$Json.decodeObject1; + _op[":="] = $Native$Json.decodeField; + var at = F2(function (fields,decoder) { return A3($List.foldr,F2(function (x,y) { return A2(_op[":="],x,y);}),decoder,fields);}); + var decodeString = $Native$Json.runDecoderString; + var map = $Native$Json.decodeObject1; + var dict = function (decoder) { return A2(map,$Dict.fromList,keyValuePairs(decoder));}; + var Decoder = {ctor: "Decoder"}; + return _elm.Json.Decode.values = {_op: _op + ,decodeString: decodeString + ,decodeValue: decodeValue + ,string: string + ,$int: $int + ,$float: $float + ,bool: bool + ,$null: $null + ,list: list + ,array: array + ,tuple1: tuple1 + ,tuple2: tuple2 + ,tuple3: tuple3 + ,tuple4: tuple4 + ,tuple5: tuple5 + ,tuple6: tuple6 + ,tuple7: tuple7 + ,tuple8: tuple8 + ,at: at + ,object1: object1 + ,object2: object2 + ,object3: object3 + ,object4: object4 + ,object5: object5 + ,object6: object6 + ,object7: object7 + ,object8: object8 + ,keyValuePairs: keyValuePairs + ,dict: dict + ,maybe: maybe + ,oneOf: oneOf + ,map: map + ,fail: fail + ,succeed: succeed + ,andThen: andThen + ,value: value + ,customDecoder: customDecoder}; +}; +Elm.Native.Effects = {}; +Elm.Native.Effects.make = function(localRuntime) { + + localRuntime.Native = localRuntime.Native || {}; + localRuntime.Native.Effects = localRuntime.Native.Effects || {}; + if (localRuntime.Native.Effects.values) + { + return localRuntime.Native.Effects.values; } - var metaKeys = [ - 'font-size', - 'font-family', - 'font-style', - 'font-weight', - 'href', - 'text-decoration', - 'color' - ]; + var Task = Elm.Native.Task.make(localRuntime); + var Utils = Elm.Native.Utils.make(localRuntime); + var Signal = Elm.Signal.make(localRuntime); + var List = Elm.Native.List.make(localRuntime); - // conversions from Elm values to CSS + // polyfill so things will work even if rAF is not available for some reason + var _requestAnimationFrame = + typeof requestAnimationFrame !== 'undefined' + ? requestAnimationFrame + : function(cb) { setTimeout(cb, 1000 / 60); } + ; - function toTypefaces(list) - { - var typefaces = List.toArray(list); - for (var i = typefaces.length; i--; ) - { - var typeface = typefaces[i]; - if (typeface.indexOf(' ') > -1) - { - typefaces[i] = "'" + typeface + "'"; - } - } - return typefaces.join(','); - } - function toLine(line) - { - var ctor = line.ctor; - return ctor === 'Under' - ? 'underline' - : ctor === 'Over' - ? 'overline' - : 'line-through'; - } + // batchedSending and sendCallback implement a small state machine in order + // to schedule only one send(time) call per animation frame. + // + // Invariants: + // 1. In the NO_REQUEST state, there is never a scheduled sendCallback. + // 2. In the PENDING_REQUEST and EXTRA_REQUEST states, there is always exactly + // one scheduled sendCallback. + var NO_REQUEST = 0; + var PENDING_REQUEST = 1; + var EXTRA_REQUEST = 2; + var state = NO_REQUEST; + var messageArray = []; - // setting styles of Text - function style(style, text) + function batchedSending(address, tickMessages) { - var newText = addMeta('color', toCss(style.color), text); - var props = newText._0; + // insert ticks into the messageArray + var foundAddress = false; - if (style.typeface.ctor !== '[]') - { - props['font-family'] = toTypefaces(style.typeface); - } - if (style.height.ctor !== "Nothing") - { - props['font-size'] = style.height._0 + 'px'; - } - if (style.bold) + for (var i = messageArray.length; i--; ) { - props['font-weight'] = 'bold'; + if (messageArray[i].address === address) + { + foundAddress = true; + messageArray[i].tickMessages = A3(List.foldl, List.cons, messageArray[i].tickMessages, tickMessages); + break; + } } - if (style.italic) + + if (!foundAddress) { - props['font-style'] = 'italic'; + messageArray.push({ address: address, tickMessages: tickMessages }); } - if (style.line.ctor !== 'Nothing') + + // do the appropriate state transition + switch (state) { - props['text-decoration'] = toLine(style.line._0); + case NO_REQUEST: + _requestAnimationFrame(sendCallback); + state = PENDING_REQUEST; + break; + case PENDING_REQUEST: + state = PENDING_REQUEST; + break; + case EXTRA_REQUEST: + state = PENDING_REQUEST; + break; } - return newText; - } - - function height(px, text) - { - return addMeta('font-size', px + 'px', text); - } - - function typeface(names, text) - { - return addMeta('font-family', toTypefaces(names), text); } - function monospace(text) - { - return addMeta('font-family', 'monospace', text); - } - - function italic(text) - { - return addMeta('font-style', 'italic', text); - } - function bold(text) + function sendCallback(time) { - return addMeta('font-weight', 'bold', text); - } + switch (state) + { + case NO_REQUEST: + // This state should not be possible. How can there be no + // request, yet somehow we are actively fulfilling a + // request? + throw new Error( + 'Unexpected send callback.\n' + + 'Please report this to .' + ); - function link(href, text) - { - return addMeta('href', href, text); - } + case PENDING_REQUEST: + // At this point, we do not *know* that another frame is + // needed, but we make an extra request to rAF just in + // case. It's possible to drop a frame if rAF is called + // too late, so we just do it preemptively. + _requestAnimationFrame(sendCallback); + state = EXTRA_REQUEST; - function line(line, text) - { - return addMeta('text-decoration', toLine(line), text); - } + // There's also stuff we definitely need to send. + send(time); + return; - function color(color, text) - { - return addMeta('color', toCss(color), text);; + case EXTRA_REQUEST: + // Turns out the extra request was not needed, so we will + // stop calling rAF. No reason to call it all the time if + // no one needs it. + state = NO_REQUEST; + return; + } } - // RENDER - - function renderHtml(text) + function send(time) { - var tag = text.ctor; - if (tag === 'Text:Append') - { - return renderHtml(text._0) + renderHtml(text._1); - } - if (tag === 'Text:Text') - { - return properEscape(text._0); - } - if (tag === 'Text:Meta') + for (var i = messageArray.length; i--; ) { - return renderMeta(text._0, renderHtml(text._1)); + var messages = A3( + List.foldl, + F2( function(toAction, list) { return List.Cons(toAction(time), list); } ), + List.Nil, + messageArray[i].tickMessages + ); + Task.perform( A2(Signal.send, messageArray[i].address, messages) ); } + messageArray = []; } - function renderMeta(metas, string) - { - var href = metas['href']; - if (href) - { - string = '' + string + ''; - } - var styles = ''; - for (var key in metas) - { - if (key === 'href') - { - continue; - } - styles += key + ':' + metas[key] + ';'; - } - if (styles) - { - string = '' + string + ''; - } - return string; - } - function properEscape(str) + function requestTickSending(address, tickMessages) { - if (str.length == 0) - { - return str; - } - str = str //.replace(/&/g, "&") - .replace(/"/g, '"') - .replace(/'/g, "'") - .replace(//g, ">"); - var arr = str.split('\n'); - for (var i = arr.length; i--; ) - { - arr[i] = makeSpaces(arr[i]); - } - return arr.join('
'); + return Task.asyncFunction(function(callback) { + batchedSending(address, tickMessages); + callback(Task.succeed(Utils.Tuple0)); + }); } - function makeSpaces(s) - { - if (s.length == 0) - { - return s; - } - var arr = s.split(''); - if (arr[0] == ' ') - { - arr[0] = " " - } - for (var i = arr.length; --i; ) - { - if (arr[i][0] == ' ' && arr[i-1] == ' ') - { - arr[i-1] = arr[i-1] + arr[i]; - arr[i] = ''; - } - } - for (var i = arr.length; i--; ) - { - if (arr[i].length > 1 && arr[i][0] == ' ') - { - var spaces = arr[i].split(''); - for (var j = spaces.length - 2; j >= 0; j -= 2) - { - spaces[j] = ' '; - } - arr[i] = spaces.join(''); - } - } - arr = arr.join(''); - if (arr[arr.length-1] === " ") - { - return arr.slice(0,-1) + ' '; - } - return arr; - } + return localRuntime.Native.Effects.values = { + requestTickSending: F2(requestTickSending) + }; + +}; + +Elm.Effects = Elm.Effects || {}; +Elm.Effects.make = function (_elm) { + "use strict"; + _elm.Effects = _elm.Effects || {}; + if (_elm.Effects.values) return _elm.Effects.values; + var _U = Elm.Native.Utils.make(_elm), + $Basics = Elm.Basics.make(_elm), + $Debug = Elm.Debug.make(_elm), + $List = Elm.List.make(_elm), + $Maybe = Elm.Maybe.make(_elm), + $Native$Effects = Elm.Native.Effects.make(_elm), + $Result = Elm.Result.make(_elm), + $Signal = Elm.Signal.make(_elm), + $Task = Elm.Task.make(_elm), + $Time = Elm.Time.make(_elm); + var _op = {}; + var ignore = function (task) { return A2($Task.map,$Basics.always({ctor: "_Tuple0"}),task);}; + var requestTickSending = $Native$Effects.requestTickSending; + var toTaskHelp = F3(function (address,effect,_p0) { + var _p1 = _p0; + var _p5 = _p1._1; + var _p4 = _p1; + var _p3 = _p1._0; + var _p2 = effect; + switch (_p2.ctor) + {case "Task": var reporter = A2($Task.andThen,_p2._0,function (answer) { return A2($Signal.send,address,_U.list([answer]));}); + return {ctor: "_Tuple2",_0: A2($Task.andThen,_p3,$Basics.always(ignore($Task.spawn(reporter)))),_1: _p5}; + case "Tick": return {ctor: "_Tuple2",_0: _p3,_1: A2($List._op["::"],_p2._0,_p5)}; + case "None": return _p4; + default: return A3($List.foldl,toTaskHelp(address),_p4,_p2._0);} + }); + var toTask = F2(function (address,effect) { + var _p6 = A3(toTaskHelp,address,effect,{ctor: "_Tuple2",_0: $Task.succeed({ctor: "_Tuple0"}),_1: _U.list([])}); + var combinedTask = _p6._0; + var tickMessages = _p6._1; + return $List.isEmpty(tickMessages) ? combinedTask : A2($Task.andThen,combinedTask,$Basics.always(A2(requestTickSending,address,tickMessages))); + }); + var Never = function (a) { return {ctor: "Never",_0: a};}; + var Batch = function (a) { return {ctor: "Batch",_0: a};}; + var batch = Batch; + var None = {ctor: "None"}; + var none = None; + var Tick = function (a) { return {ctor: "Tick",_0: a};}; + var tick = Tick; + var Task = function (a) { return {ctor: "Task",_0: a};}; + var task = Task; + var map = F2(function (func,effect) { + var _p7 = effect; + switch (_p7.ctor) + {case "Task": return Task(A2($Task.map,func,_p7._0)); + case "Tick": return Tick(function (_p8) { return func(_p7._0(_p8));}); + case "None": return None; + default: return Batch(A2($List.map,map(func),_p7._0));} + }); + return _elm.Effects.values = {_op: _op,none: none,task: task,tick: tick,map: map,batch: batch,toTask: toTask}; +}; +(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o 0) - { - var front = stack.pop(); - var x = front.x; - var y = front.y; - if (x === y) - { - continue; - } - if (typeof x === "object") - { - var c = 0; - for (var i in x) - { - ++c; - if (i in y) - { - if (i !== 'ctor') - { - stack.push({ 'x': x[i], 'y': y[i] }); - } - } - else - { - return false; - } - } - if ('ctor' in x) - { - stack.push({'x': x.ctor, 'y': y.ctor}); - } - if (c !== Object.keys(y).length) - { - return false; - } - } - else if (typeof x === 'function') - { - throw new Error('Equality error: general function equality is ' + - 'undecidable, and therefore, unsupported'); - } - else - { - return false; - } - } - return true; - } + rootIndex = nextIndex + } + } + } - // code in Generate/JavaScript.hs depends on the particular - // integer values assigned to LT, EQ, and GT - var LT = -1, EQ = 0, GT = 1, ord = ['LT','EQ','GT']; + return nodes +} - function compare(x,y) - { - return { - ctor: ord[cmp(x,y)+1] - }; - } +// Binary search for an index in the interval [left, right] +function indexInRange(indices, left, right) { + if (indices.length === 0) { + return false + } - function cmp(x,y) { - var ord; - if (typeof x !== 'object') - { - return x === y ? EQ : x < y ? LT : GT; - } - else if (x.isChar) - { - var a = x.toString(); - var b = y.toString(); - return a === b - ? EQ - : a < b - ? LT - : GT; - } - else if (x.ctor === "::" || x.ctor === "[]") - { - while (true) - { - if (x.ctor === "[]" && y.ctor === "[]") - { - return EQ; - } - if (x.ctor !== y.ctor) - { - return x.ctor === '[]' ? LT : GT; - } - ord = cmp(x._0, y._0); - if (ord !== EQ) - { - return ord; - } - x = x._1; - y = y._1; - } - } - else if (x.ctor.slice(0,6) === '_Tuple') - { - var n = x.ctor.slice(6) - 0; - var err = 'cannot compare tuples with more than 6 elements.'; - if (n === 0) return EQ; - if (n >= 1) { ord = cmp(x._0, y._0); if (ord !== EQ) return ord; - if (n >= 2) { ord = cmp(x._1, y._1); if (ord !== EQ) return ord; - if (n >= 3) { ord = cmp(x._2, y._2); if (ord !== EQ) return ord; - if (n >= 4) { ord = cmp(x._3, y._3); if (ord !== EQ) return ord; - if (n >= 5) { ord = cmp(x._4, y._4); if (ord !== EQ) return ord; - if (n >= 6) { ord = cmp(x._5, y._5); if (ord !== EQ) return ord; - if (n >= 7) throw new Error('Comparison error: ' + err); } } } } } } - return EQ; - } - else - { - throw new Error('Comparison error: comparison is only defined on ints, ' + - 'floats, times, chars, strings, lists of comparable values, ' + - 'and tuples of comparable values.'); - } - } + var minIndex = 0 + var maxIndex = indices.length - 1 + var currentIndex + var currentItem + + while (minIndex <= maxIndex) { + currentIndex = ((maxIndex + minIndex) / 2) >> 0 + currentItem = indices[currentIndex] + if (minIndex === maxIndex) { + return currentItem >= left && currentItem <= right + } else if (currentItem < left) { + minIndex = currentIndex + 1 + } else if (currentItem > right) { + maxIndex = currentIndex - 1 + } else { + return true + } + } - var Tuple0 = { - ctor: "_Tuple0" - }; + return false; +} - function Tuple2(x,y) - { - return { - ctor: "_Tuple2", - _0: x, - _1: y - }; - } +function ascending(a, b) { + return a > b ? 1 : -1 +} - function chr(c) - { - var x = new String(c); - x.isChar = true; - return x; - } +},{}],8:[function(require,module,exports){ +var applyProperties = require("./apply-properties") - function txt(str) - { - var t = new String(str); - t.text = true; - return t; - } +var isWidget = require("../vnode/is-widget.js") +var VPatch = require("../vnode/vpatch.js") - var count = 0; - function guid(_) - { - return count++ - } +var render = require("./create-element") +var updateWidget = require("./update-widget") - function copy(oldRecord) - { - var newRecord = {}; - for (var key in oldRecord) - { - var value = key === '_' - ? copy(oldRecord._) - : oldRecord[key]; - newRecord[key] = value; - } - return newRecord; - } +module.exports = applyPatch - function remove(key, oldRecord) - { - var record = copy(oldRecord); - if (key in record._) - { - record[key] = record._[key][0]; - record._[key] = record._[key].slice(1); - if (record._[key].length === 0) - { - delete record._[key]; - } - } - else - { - delete record[key]; - } - return record; - } +function applyPatch(vpatch, domNode, renderOptions) { + var type = vpatch.type + var vNode = vpatch.vNode + var patch = vpatch.patch - function replace(keyValuePairs, oldRecord) - { - var record = copy(oldRecord); - for (var i = keyValuePairs.length; i--; ) - { - var pair = keyValuePairs[i]; - record[pair[0]] = pair[1]; - } - return record; - } + switch (type) { + case VPatch.REMOVE: + return removeNode(domNode, vNode) + case VPatch.INSERT: + return insertNode(domNode, patch, renderOptions) + case VPatch.VTEXT: + return stringPatch(domNode, vNode, patch, renderOptions) + case VPatch.WIDGET: + return widgetPatch(domNode, vNode, patch, renderOptions) + case VPatch.VNODE: + return vNodePatch(domNode, vNode, patch, renderOptions) + case VPatch.ORDER: + reorderChildren(domNode, patch) + return domNode + case VPatch.PROPS: + applyProperties(domNode, patch, vNode.properties) + return domNode + case VPatch.THUNK: + return replaceRoot(domNode, + renderOptions.patch(domNode, patch, renderOptions)) + default: + return domNode + } +} - function insert(key, value, oldRecord) - { - var newRecord = copy(oldRecord); - if (key in newRecord) - { - var values = newRecord._[key]; - var copiedValues = values ? values.slice(0) : []; - newRecord._[key] = [newRecord[key]].concat(copiedValues); - } - newRecord[key] = value; - return newRecord; - } +function removeNode(domNode, vNode) { + var parentNode = domNode.parentNode - function getXY(e) - { - var posx = 0; - var posy = 0; - if (e.pageX || e.pageY) - { - posx = e.pageX; - posy = e.pageY; - } - else if (e.clientX || e.clientY) - { - posx = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft; - posy = e.clientY + document.body.scrollTop + document.documentElement.scrollTop; - } + if (parentNode) { + parentNode.removeChild(domNode) + } - if (localRuntime.isEmbed()) - { - var rect = localRuntime.node.getBoundingClientRect(); - var relx = rect.left + document.body.scrollLeft + document.documentElement.scrollLeft; - var rely = rect.top + document.body.scrollTop + document.documentElement.scrollTop; - // TODO: figure out if there is a way to avoid rounding here - posx = posx - Math.round(relx) - localRuntime.node.clientLeft; - posy = posy - Math.round(rely) - localRuntime.node.clientTop; - } - return Tuple2(posx, posy); - } + destroyWidget(domNode, vNode); + return null +} - //// LIST STUFF //// +function insertNode(parentNode, vNode, renderOptions) { + var newNode = render(vNode, renderOptions) - var Nil = { ctor:'[]' }; + if (parentNode) { + parentNode.appendChild(newNode) + } - function Cons(hd,tl) - { - return { - ctor: "::", - _0: hd, - _1: tl - }; - } + return parentNode +} - function append(xs,ys) - { - // append Strings - if (typeof xs === "string") - { - return xs + ys; - } +function stringPatch(domNode, leftVNode, vText, renderOptions) { + var newNode - // append Text - if (xs.ctor.slice(0,5) === 'Text:') - { - return { - ctor: 'Text:Append', - _0: xs, - _1: ys - }; - } + if (domNode.nodeType === 3) { + domNode.replaceData(0, domNode.length, vText.text) + newNode = domNode + } else { + var parentNode = domNode.parentNode + newNode = render(vText, renderOptions) + if (parentNode && newNode !== domNode) { + parentNode.replaceChild(newNode, domNode) + } + } + return newNode +} - // append Lists - if (xs.ctor === '[]') - { - return ys; - } - var root = Cons(xs._0, Nil); - var curr = root; - xs = xs._1; - while (xs.ctor !== '[]') - { - curr._1 = Cons(xs._0, Nil); - xs = xs._1; - curr = curr._1; - } - curr._1 = ys; - return root; - } +function widgetPatch(domNode, leftVNode, widget, renderOptions) { + var updating = updateWidget(leftVNode, widget) + var newNode - //// RUNTIME ERRORS //// + if (updating) { + newNode = widget.update(leftVNode, domNode) || domNode + } else { + newNode = render(widget, renderOptions) + } - function indent(lines) - { - return '\n' + lines.join('\n'); - } + var parentNode = domNode.parentNode - function badCase(moduleName, span) - { - var msg = indent([ - 'Non-exhaustive pattern match in case-expression.', - 'Make sure your patterns cover every case!' - ]); - throw new Error('Runtime error in module ' + moduleName + ' (' + span + ')' + msg); - } + if (parentNode && newNode !== domNode) { + parentNode.replaceChild(newNode, domNode) + } - function badIf(moduleName, span) - { - var msg = indent([ - 'Non-exhaustive pattern match in multi-way-if expression.', - 'It is best to use \'otherwise\' as the last branch of multi-way-if.' - ]); - throw new Error('Runtime error in module ' + moduleName + ' (' + span + ')' + msg); - } + if (!updating) { + destroyWidget(domNode, leftVNode) + } + + return newNode +} +function vNodePatch(domNode, leftVNode, vNode, renderOptions) { + var parentNode = domNode.parentNode + var newNode = render(vNode, renderOptions) - function badPort(expected, received) - { - var msg = indent([ - 'Expecting ' + expected + ' but was given ', - JSON.stringify(received) - ]); - throw new Error('Runtime error when sending values through a port.' + msg); - } + if (parentNode && newNode !== domNode) { + parentNode.replaceChild(newNode, domNode) + } + return newNode +} - return localRuntime.Native.Utils.values = { - eq: eq, - cmp: cmp, - compare: F2(compare), - Tuple0: Tuple0, - Tuple2: Tuple2, - chr: chr, - txt: txt, - copy: copy, - remove: remove, - replace: replace, - insert: insert, - guid: guid, - getXY: getXY, +function destroyWidget(domNode, w) { + if (typeof w.destroy === "function" && isWidget(w)) { + w.destroy(domNode) + } +} - Nil: Nil, - Cons: Cons, - append: F2(append), +function reorderChildren(domNode, moves) { + var childNodes = domNode.childNodes + var keyMap = {} + var node + var remove + var insert - badCase: badCase, - badIf: badIf, - badPort: badPort - }; -}; + for (var i = 0; i < moves.removes.length; i++) { + remove = moves.removes[i] + node = childNodes[remove.from] + if (remove.key) { + keyMap[remove.key] = node + } + domNode.removeChild(node) + } -(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o= length++ ? null : childNodes[insert.to]) + } +} -module.exports = createElement +function replaceRoot(oldRoot, newRoot) { + if (oldRoot && newRoot && oldRoot !== newRoot && oldRoot.parentNode) { + oldRoot.parentNode.replaceChild(newRoot, oldRoot) + } -},{"./vdom/create-element.js":6}],2:[function(require,module,exports){ -(function (global){ -var topLevel = typeof global !== 'undefined' ? global : - typeof window !== 'undefined' ? window : {} -var minDoc = require('min-document'); + return newRoot; +} -if (typeof document !== 'undefined') { - module.exports = document; -} else { - var doccy = topLevel['__GLOBAL_DOCUMENT_CACHE@4']; +},{"../vnode/is-widget.js":16,"../vnode/vpatch.js":19,"./apply-properties":5,"./create-element":6,"./update-widget":10}],9:[function(require,module,exports){ +var document = require("global/document") +var isArray = require("x-is-array") - if (!doccy) { - doccy = topLevel['__GLOBAL_DOCUMENT_CACHE@4'] = minDoc; - } +var domIndex = require("./dom-index") +var patchOp = require("./patch-op") +module.exports = patch - module.exports = doccy; +function patch(rootNode, patches) { + return patchRecursive(rootNode, patches) } -}).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"min-document":24}],3:[function(require,module,exports){ -"use strict"; +function patchRecursive(rootNode, patches, renderOptions) { + var indices = patchIndices(patches) -module.exports = function isObject(x) { - return typeof x === "object" && x !== null; -}; + if (indices.length === 0) { + return rootNode + } -},{}],4:[function(require,module,exports){ -var nativeIsArray = Array.isArray -var toString = Object.prototype.toString + var index = domIndex(rootNode, patches.a, indices) + var ownerDocument = rootNode.ownerDocument -module.exports = nativeIsArray || isArray + if (!renderOptions) { + renderOptions = { patch: patchRecursive } + if (ownerDocument !== document) { + renderOptions.document = ownerDocument + } + } -function isArray(obj) { - return toString.call(obj) === "[object Array]" + for (var i = 0; i < indices.length; i++) { + var nodeIndex = indices[i] + rootNode = applyPatch(rootNode, + index[nodeIndex], + patches[nodeIndex], + renderOptions) + } + + return rootNode } -},{}],5:[function(require,module,exports){ -var isObject = require("is-object") -var isHook = require("../vnode/is-vhook.js") +function applyPatch(rootNode, domNode, patchList, renderOptions) { + if (!domNode) { + return rootNode + } -module.exports = applyProperties + var newNode -function applyProperties(node, props, previous) { - for (var propName in props) { - var propValue = props[propName] + if (isArray(patchList)) { + for (var i = 0; i < patchList.length; i++) { + newNode = patchOp(patchList[i], domNode, renderOptions) - if (propValue === undefined) { - removeProperty(node, propName, propValue, previous); - } else if (isHook(propValue)) { - removeProperty(node, propName, propValue, previous) - if (propValue.hook) { - propValue.hook(node, - propName, - previous ? previous[propName] : undefined) - } - } else { - if (isObject(propValue)) { - patchObject(node, props, previous, propName, propValue); - } else { - node[propName] = propValue + if (domNode === rootNode) { + rootNode = newNode } } + } else { + newNode = patchOp(patchList, domNode, renderOptions) + + if (domNode === rootNode) { + rootNode = newNode + } } + + return rootNode } -function removeProperty(node, propName, propValue, previous) { - if (previous) { - var previousValue = previous[propName] +function patchIndices(patches) { + var indices = [] - if (!isHook(previousValue)) { - if (propName === "attributes") { - for (var attrName in previousValue) { - node.removeAttribute(attrName) - } - } else if (propName === "style") { - for (var i in previousValue) { - node.style[i] = "" - } - } else if (typeof previousValue === "string") { - node[propName] = "" - } else { - node[propName] = null - } - } else if (previousValue.unhook) { - previousValue.unhook(node, propName, propValue) + for (var key in patches) { + if (key !== "a") { + indices.push(Number(key)) } } + + return indices } -function patchObject(node, props, previous, propName, propValue) { - var previousValue = previous ? previous[propName] : undefined +},{"./dom-index":7,"./patch-op":8,"global/document":2,"x-is-array":4}],10:[function(require,module,exports){ +var isWidget = require("../vnode/is-widget.js") - // Set attributes - if (propName === "attributes") { - for (var attrName in propValue) { - var attrValue = propValue[attrName] +module.exports = updateWidget - if (attrValue === undefined) { - node.removeAttribute(attrName) - } else { - node.setAttribute(attrName, attrValue) - } +function updateWidget(a, b) { + if (isWidget(a) && isWidget(b)) { + if ("name" in a && "name" in b) { + return a.id === b.id + } else { + return a.init === b.init } - - return } - if(previousValue && isObject(previousValue) && - getPrototype(previousValue) !== getPrototype(propValue)) { - node[propName] = propValue - return - } + return false +} - if (!isObject(node[propName])) { - node[propName] = {} - } +},{"../vnode/is-widget.js":16}],11:[function(require,module,exports){ +var isVNode = require("./is-vnode") +var isVText = require("./is-vtext") +var isWidget = require("./is-widget") +var isThunk = require("./is-thunk") - var replacer = propName === "style" ? "" : undefined +module.exports = handleThunk - for (var k in propValue) { - var value = propValue[k] - node[propName][k] = (value === undefined) ? replacer : value - } -} +function handleThunk(a, b) { + var renderedA = a + var renderedB = b -function getPrototype(value) { - if (Object.getPrototypeOf) { - return Object.getPrototypeOf(value) - } else if (value.__proto__) { - return value.__proto__ - } else if (value.constructor) { - return value.constructor.prototype + if (isThunk(b)) { + renderedB = renderThunk(b, a) } -} -},{"../vnode/is-vhook.js":13,"is-object":3}],6:[function(require,module,exports){ -var document = require("global/document") + if (isThunk(a)) { + renderedA = renderThunk(a, null) + } -var applyProperties = require("./apply-properties") + return { + a: renderedA, + b: renderedB + } +} -var isVNode = require("../vnode/is-vnode.js") -var isVText = require("../vnode/is-vtext.js") -var isWidget = require("../vnode/is-widget.js") -var handleThunk = require("../vnode/handle-thunk.js") +function renderThunk(thunk, previous) { + var renderedThunk = thunk.vnode -module.exports = createElement + if (!renderedThunk) { + renderedThunk = thunk.vnode = thunk.render(previous) + } -function createElement(vnode, opts) { - var doc = opts ? opts.document || document : document - var warn = opts ? opts.warn : null + if (!(isVNode(renderedThunk) || + isVText(renderedThunk) || + isWidget(renderedThunk))) { + throw new Error("thunk did not return a valid node"); + } - vnode = handleThunk(vnode).a + return renderedThunk +} - if (isWidget(vnode)) { - return vnode.init() - } else if (isVText(vnode)) { - return doc.createTextNode(vnode.text) - } else if (!isVNode(vnode)) { - if (warn) { - warn("Item is not a valid virtual dom node", vnode) - } - return null - } +},{"./is-thunk":12,"./is-vnode":14,"./is-vtext":15,"./is-widget":16}],12:[function(require,module,exports){ +module.exports = isThunk + +function isThunk(t) { + return t && t.type === "Thunk" +} - var node = (vnode.namespace === null) ? - doc.createElement(vnode.tagName) : - doc.createElementNS(vnode.namespace, vnode.tagName) +},{}],13:[function(require,module,exports){ +module.exports = isHook - var props = vnode.properties - applyProperties(node, props) +function isHook(hook) { + return hook && + (typeof hook.hook === "function" && !hook.hasOwnProperty("hook") || + typeof hook.unhook === "function" && !hook.hasOwnProperty("unhook")) +} - var children = vnode.children +},{}],14:[function(require,module,exports){ +var version = require("./version") - for (var i = 0; i < children.length; i++) { - var childNode = createElement(children[i], opts) - if (childNode) { - node.appendChild(childNode) - } - } +module.exports = isVirtualNode - return node +function isVirtualNode(x) { + return x && x.type === "VirtualNode" && x.version === version } -},{"../vnode/handle-thunk.js":11,"../vnode/is-vnode.js":14,"../vnode/is-vtext.js":15,"../vnode/is-widget.js":16,"./apply-properties":5,"global/document":2}],7:[function(require,module,exports){ -// Maps a virtual DOM tree onto a real DOM tree in an efficient manner. -// We don't want to read all of the DOM nodes in the tree so we use -// the in-order tree indexing to eliminate recursion down certain branches. -// We only recurse into a DOM node if we know that it contains a child of -// interest. - -var noChild = {} +},{"./version":17}],15:[function(require,module,exports){ +var version = require("./version") -module.exports = domIndex +module.exports = isVirtualText -function domIndex(rootNode, tree, indices, nodes) { - if (!indices || indices.length === 0) { - return {} - } else { - indices.sort(ascending) - return recurse(rootNode, tree, indices, nodes, 0) - } +function isVirtualText(x) { + return x && x.type === "VirtualText" && x.version === version } -function recurse(rootNode, tree, indices, nodes, rootIndex) { - nodes = nodes || {} +},{"./version":17}],16:[function(require,module,exports){ +module.exports = isWidget +function isWidget(w) { + return w && w.type === "Widget" +} - if (rootNode) { - if (indexInRange(indices, rootIndex, rootIndex)) { - nodes[rootIndex] = rootNode - } +},{}],17:[function(require,module,exports){ +module.exports = "2" - var vChildren = tree.children +},{}],18:[function(require,module,exports){ +var version = require("./version") +var isVNode = require("./is-vnode") +var isWidget = require("./is-widget") +var isThunk = require("./is-thunk") +var isVHook = require("./is-vhook") - if (vChildren) { +module.exports = VirtualNode - var childNodes = rootNode.childNodes +var noProperties = {} +var noChildren = [] - for (var i = 0; i < tree.children.length; i++) { - rootIndex += 1 +function VirtualNode(tagName, properties, children, key, namespace) { + this.tagName = tagName + this.properties = properties || noProperties + this.children = children || noChildren + this.key = key != null ? String(key) : undefined + this.namespace = (typeof namespace === "string") ? namespace : null - var vChild = vChildren[i] || noChild - var nextIndex = rootIndex + (vChild.count || 0) + var count = (children && children.length) || 0 + var descendants = 0 + var hasWidgets = false + var hasThunks = false + var descendantHooks = false + var hooks - // skip recursion down the tree if there are no nodes down here - if (indexInRange(indices, rootIndex, nextIndex)) { - recurse(childNodes[i], vChild, indices, nodes, rootIndex) + for (var propName in properties) { + if (properties.hasOwnProperty(propName)) { + var property = properties[propName] + if (isVHook(property) && property.unhook) { + if (!hooks) { + hooks = {} } - rootIndex = nextIndex + hooks[propName] = property } } } - return nodes -} - -// Binary search for an index in the interval [left, right] -function indexInRange(indices, left, right) { - if (indices.length === 0) { - return false - } + for (var i = 0; i < count; i++) { + var child = children[i] + if (isVNode(child)) { + descendants += child.count || 0 - var minIndex = 0 - var maxIndex = indices.length - 1 - var currentIndex - var currentItem + if (!hasWidgets && child.hasWidgets) { + hasWidgets = true + } - while (minIndex <= maxIndex) { - currentIndex = ((maxIndex + minIndex) / 2) >> 0 - currentItem = indices[currentIndex] + if (!hasThunks && child.hasThunks) { + hasThunks = true + } - if (minIndex === maxIndex) { - return currentItem >= left && currentItem <= right - } else if (currentItem < left) { - minIndex = currentIndex + 1 - } else if (currentItem > right) { - maxIndex = currentIndex - 1 - } else { - return true + if (!descendantHooks && (child.hooks || child.descendantHooks)) { + descendantHooks = true + } + } else if (!hasWidgets && isWidget(child)) { + if (typeof child.destroy === "function") { + hasWidgets = true + } + } else if (!hasThunks && isThunk(child)) { + hasThunks = true; } } - return false; -} - -function ascending(a, b) { - return a > b ? 1 : -1 + this.count = count + descendants + this.hasWidgets = hasWidgets + this.hasThunks = hasThunks + this.hooks = hooks + this.descendantHooks = descendantHooks } -},{}],8:[function(require,module,exports){ -var applyProperties = require("./apply-properties") - -var isWidget = require("../vnode/is-widget.js") -var VPatch = require("../vnode/vpatch.js") +VirtualNode.prototype.version = version +VirtualNode.prototype.type = "VirtualNode" -var render = require("./create-element") -var updateWidget = require("./update-widget") +},{"./is-thunk":12,"./is-vhook":13,"./is-vnode":14,"./is-widget":16,"./version":17}],19:[function(require,module,exports){ +var version = require("./version") -module.exports = applyPatch +VirtualPatch.NONE = 0 +VirtualPatch.VTEXT = 1 +VirtualPatch.VNODE = 2 +VirtualPatch.WIDGET = 3 +VirtualPatch.PROPS = 4 +VirtualPatch.ORDER = 5 +VirtualPatch.INSERT = 6 +VirtualPatch.REMOVE = 7 +VirtualPatch.THUNK = 8 -function applyPatch(vpatch, domNode, renderOptions) { - var type = vpatch.type - var vNode = vpatch.vNode - var patch = vpatch.patch +module.exports = VirtualPatch - switch (type) { - case VPatch.REMOVE: - return removeNode(domNode, vNode) - case VPatch.INSERT: - return insertNode(domNode, patch, renderOptions) - case VPatch.VTEXT: - return stringPatch(domNode, vNode, patch, renderOptions) - case VPatch.WIDGET: - return widgetPatch(domNode, vNode, patch, renderOptions) - case VPatch.VNODE: - return vNodePatch(domNode, vNode, patch, renderOptions) - case VPatch.ORDER: - reorderChildren(domNode, patch) - return domNode - case VPatch.PROPS: - applyProperties(domNode, patch, vNode.properties) - return domNode - case VPatch.THUNK: - return replaceRoot(domNode, - renderOptions.patch(domNode, patch, renderOptions)) - default: - return domNode - } +function VirtualPatch(type, vNode, patch) { + this.type = Number(type) + this.vNode = vNode + this.patch = patch } -function removeNode(domNode, vNode) { - var parentNode = domNode.parentNode +VirtualPatch.prototype.version = version +VirtualPatch.prototype.type = "VirtualPatch" - if (parentNode) { - parentNode.removeChild(domNode) - } +},{"./version":17}],20:[function(require,module,exports){ +var version = require("./version") - destroyWidget(domNode, vNode); +module.exports = VirtualText - return null +function VirtualText(text) { + this.text = String(text) } -function insertNode(parentNode, vNode, renderOptions) { - var newNode = render(vNode, renderOptions) +VirtualText.prototype.version = version +VirtualText.prototype.type = "VirtualText" - if (parentNode) { - parentNode.appendChild(newNode) - } +},{"./version":17}],21:[function(require,module,exports){ +var isObject = require("is-object") +var isHook = require("../vnode/is-vhook") - return parentNode -} +module.exports = diffProps -function stringPatch(domNode, leftVNode, vText, renderOptions) { - var newNode +function diffProps(a, b) { + var diff - if (domNode.nodeType === 3) { - domNode.replaceData(0, domNode.length, vText.text) - newNode = domNode - } else { - var parentNode = domNode.parentNode - newNode = render(vText, renderOptions) + for (var aKey in a) { + if (!(aKey in b)) { + diff = diff || {} + diff[aKey] = undefined + } + + var aValue = a[aKey] + var bValue = b[aKey] + + if (aValue === bValue) { + continue + } else if (isObject(aValue) && isObject(bValue)) { + if (getPrototype(bValue) !== getPrototype(aValue)) { + diff = diff || {} + diff[aKey] = bValue + } else if (isHook(bValue)) { + diff = diff || {} + diff[aKey] = bValue + } else { + var objectDiff = diffProps(aValue, bValue) + if (objectDiff) { + diff = diff || {} + diff[aKey] = objectDiff + } + } + } else { + diff = diff || {} + diff[aKey] = bValue + } + } - if (parentNode && newNode !== domNode) { - parentNode.replaceChild(newNode, domNode) + for (var bKey in b) { + if (!(bKey in a)) { + diff = diff || {} + diff[bKey] = b[bKey] } } - return newNode + return diff } -function widgetPatch(domNode, leftVNode, widget, renderOptions) { - var updating = updateWidget(leftVNode, widget) - var newNode +function getPrototype(value) { + if (Object.getPrototypeOf) { + return Object.getPrototypeOf(value) + } else if (value.__proto__) { + return value.__proto__ + } else if (value.constructor) { + return value.constructor.prototype + } +} - if (updating) { - newNode = widget.update(leftVNode, domNode) || domNode - } else { - newNode = render(widget, renderOptions) - } +},{"../vnode/is-vhook":13,"is-object":3}],22:[function(require,module,exports){ +var isArray = require("x-is-array") - var parentNode = domNode.parentNode +var VPatch = require("../vnode/vpatch") +var isVNode = require("../vnode/is-vnode") +var isVText = require("../vnode/is-vtext") +var isWidget = require("../vnode/is-widget") +var isThunk = require("../vnode/is-thunk") +var handleThunk = require("../vnode/handle-thunk") - if (parentNode && newNode !== domNode) { - parentNode.replaceChild(newNode, domNode) - } +var diffProps = require("./diff-props") - if (!updating) { - destroyWidget(domNode, leftVNode) - } +module.exports = diff - return newNode +function diff(a, b) { + var patch = { a: a } + walk(a, b, patch, 0) + return patch } -function vNodePatch(domNode, leftVNode, vNode, renderOptions) { - var parentNode = domNode.parentNode - var newNode = render(vNode, renderOptions) - - if (parentNode && newNode !== domNode) { - parentNode.replaceChild(newNode, domNode) +function walk(a, b, patch, index) { + if (a === b) { + return } - return newNode -} + var apply = patch[index] + var applyClear = false -function destroyWidget(domNode, w) { - if (typeof w.destroy === "function" && isWidget(w)) { - w.destroy(domNode) - } -} + if (isThunk(a) || isThunk(b)) { + thunks(a, b, patch, index) + } else if (b == null) { -function reorderChildren(domNode, moves) { - var childNodes = domNode.childNodes - var keyMap = {} - var node - var remove - var insert + // If a is a widget we will add a remove patch for it + // Otherwise any child widgets/hooks must be destroyed. + // This prevents adding two remove patches for a widget. + if (!isWidget(a)) { + clearState(a, patch, index) + apply = patch[index] + } - for (var i = 0; i < moves.removes.length; i++) { - remove = moves.removes[i] - node = childNodes[remove.from] - if (remove.key) { - keyMap[remove.key] = node + apply = appendPatch(apply, new VPatch(VPatch.REMOVE, a, b)) + } else if (isVNode(b)) { + if (isVNode(a)) { + if (a.tagName === b.tagName && + a.namespace === b.namespace && + a.key === b.key) { + var propsPatch = diffProps(a.properties, b.properties) + if (propsPatch) { + apply = appendPatch(apply, + new VPatch(VPatch.PROPS, a, propsPatch)) + } + apply = diffChildren(a, b, patch, apply, index) + } else { + apply = appendPatch(apply, new VPatch(VPatch.VNODE, a, b)) + applyClear = true + } + } else { + apply = appendPatch(apply, new VPatch(VPatch.VNODE, a, b)) + applyClear = true + } + } else if (isVText(b)) { + if (!isVText(a)) { + apply = appendPatch(apply, new VPatch(VPatch.VTEXT, a, b)) + applyClear = true + } else if (a.text !== b.text) { + apply = appendPatch(apply, new VPatch(VPatch.VTEXT, a, b)) + } + } else if (isWidget(b)) { + if (!isWidget(a)) { + applyClear = true } - domNode.removeChild(node) - } - var length = childNodes.length - for (var j = 0; j < moves.inserts.length; j++) { - insert = moves.inserts[j] - node = keyMap[insert.key] - // this is the weirdest bug i've ever seen in webkit - domNode.insertBefore(node, insert.to >= length++ ? null : childNodes[insert.to]) + apply = appendPatch(apply, new VPatch(VPatch.WIDGET, a, b)) } -} -function replaceRoot(oldRoot, newRoot) { - if (oldRoot && newRoot && oldRoot !== newRoot && oldRoot.parentNode) { - oldRoot.parentNode.replaceChild(newRoot, oldRoot) + if (apply) { + patch[index] = apply } - return newRoot; + if (applyClear) { + clearState(a, patch, index) + } } -},{"../vnode/is-widget.js":16,"../vnode/vpatch.js":19,"./apply-properties":5,"./create-element":6,"./update-widget":10}],9:[function(require,module,exports){ -var document = require("global/document") -var isArray = require("x-is-array") - -var domIndex = require("./dom-index") -var patchOp = require("./patch-op") -module.exports = patch - -function patch(rootNode, patches) { - return patchRecursive(rootNode, patches) -} +function diffChildren(a, b, patch, apply, index) { + var aChildren = a.children + var orderedSet = reorder(aChildren, b.children) + var bChildren = orderedSet.children -function patchRecursive(rootNode, patches, renderOptions) { - var indices = patchIndices(patches) + var aLen = aChildren.length + var bLen = bChildren.length + var len = aLen > bLen ? aLen : bLen - if (indices.length === 0) { - return rootNode - } + for (var i = 0; i < len; i++) { + var leftNode = aChildren[i] + var rightNode = bChildren[i] + index += 1 - var index = domIndex(rootNode, patches.a, indices) - var ownerDocument = rootNode.ownerDocument + if (!leftNode) { + if (rightNode) { + // Excess nodes in b need to be added + apply = appendPatch(apply, + new VPatch(VPatch.INSERT, null, rightNode)) + } + } else { + walk(leftNode, rightNode, patch, index) + } - if (!renderOptions) { - renderOptions = { patch: patchRecursive } - if (ownerDocument !== document) { - renderOptions.document = ownerDocument + if (isVNode(leftNode) && leftNode.count) { + index += leftNode.count } } - for (var i = 0; i < indices.length; i++) { - var nodeIndex = indices[i] - rootNode = applyPatch(rootNode, - index[nodeIndex], - patches[nodeIndex], - renderOptions) + if (orderedSet.moves) { + // Reorder nodes last + apply = appendPatch(apply, new VPatch( + VPatch.ORDER, + a, + orderedSet.moves + )) } - return rootNode + return apply } -function applyPatch(rootNode, domNode, patchList, renderOptions) { - if (!domNode) { - return rootNode - } +function clearState(vNode, patch, index) { + // TODO: Make this a single walk, not two + unhook(vNode, patch, index) + destroyWidgets(vNode, patch, index) +} - var newNode +// Patch records for all destroyed widgets must be added because we need +// a DOM node reference for the destroy function +function destroyWidgets(vNode, patch, index) { + if (isWidget(vNode)) { + if (typeof vNode.destroy === "function") { + patch[index] = appendPatch( + patch[index], + new VPatch(VPatch.REMOVE, vNode, null) + ) + } + } else if (isVNode(vNode) && (vNode.hasWidgets || vNode.hasThunks)) { + var children = vNode.children + var len = children.length + for (var i = 0; i < len; i++) { + var child = children[i] + index += 1 - if (isArray(patchList)) { - for (var i = 0; i < patchList.length; i++) { - newNode = patchOp(patchList[i], domNode, renderOptions) + destroyWidgets(child, patch, index) - if (domNode === rootNode) { - rootNode = newNode + if (isVNode(child) && child.count) { + index += child.count } } - } else { - newNode = patchOp(patchList, domNode, renderOptions) - - if (domNode === rootNode) { - rootNode = newNode - } + } else if (isThunk(vNode)) { + thunks(vNode, null, patch, index) } - - return rootNode } -function patchIndices(patches) { - var indices = [] - - for (var key in patches) { - if (key !== "a") { - indices.push(Number(key)) - } - } - - return indices +// Create a sub-patch for thunks +function thunks(a, b, patch, index) { + var nodes = handleThunk(a, b) + var thunkPatch = diff(nodes.a, nodes.b) + if (hasPatches(thunkPatch)) { + patch[index] = new VPatch(VPatch.THUNK, null, thunkPatch) + } } -},{"./dom-index":7,"./patch-op":8,"global/document":2,"x-is-array":4}],10:[function(require,module,exports){ -var isWidget = require("../vnode/is-widget.js") - -module.exports = updateWidget - -function updateWidget(a, b) { - if (isWidget(a) && isWidget(b)) { - if ("name" in a && "name" in b) { - return a.id === b.id - } else { - return a.init === b.init +function hasPatches(patch) { + for (var index in patch) { + if (index !== "a") { + return true } } return false } -},{"../vnode/is-widget.js":16}],11:[function(require,module,exports){ -var isVNode = require("./is-vnode") -var isVText = require("./is-vtext") -var isWidget = require("./is-widget") -var isThunk = require("./is-thunk") - -module.exports = handleThunk - -function handleThunk(a, b) { - var renderedA = a - var renderedB = b +// Execute hooks when two nodes are identical +function unhook(vNode, patch, index) { + if (isVNode(vNode)) { + if (vNode.hooks) { + patch[index] = appendPatch( + patch[index], + new VPatch( + VPatch.PROPS, + vNode, + undefinedKeys(vNode.hooks) + ) + ) + } - if (isThunk(b)) { - renderedB = renderThunk(b, a) - } + if (vNode.descendantHooks || vNode.hasThunks) { + var children = vNode.children + var len = children.length + for (var i = 0; i < len; i++) { + var child = children[i] + index += 1 - if (isThunk(a)) { - renderedA = renderThunk(a, null) - } + unhook(child, patch, index) - return { - a: renderedA, - b: renderedB + if (isVNode(child) && child.count) { + index += child.count + } + } + } + } else if (isThunk(vNode)) { + thunks(vNode, null, patch, index) } } -function renderThunk(thunk, previous) { - var renderedThunk = thunk.vnode - - if (!renderedThunk) { - renderedThunk = thunk.vnode = thunk.render(previous) - } +function undefinedKeys(obj) { + var result = {} - if (!(isVNode(renderedThunk) || - isVText(renderedThunk) || - isWidget(renderedThunk))) { - throw new Error("thunk did not return a valid node"); + for (var key in obj) { + result[key] = undefined } - return renderedThunk + return result } -},{"./is-thunk":12,"./is-vnode":14,"./is-vtext":15,"./is-widget":16}],12:[function(require,module,exports){ -module.exports = isThunk - -function isThunk(t) { - return t && t.type === "Thunk" -} +// List diff, naive left to right reordering +function reorder(aChildren, bChildren) { + // O(M) time, O(M) memory + var bChildIndex = keyIndex(bChildren) + var bKeys = bChildIndex.keys + var bFree = bChildIndex.free -},{}],13:[function(require,module,exports){ -module.exports = isHook + if (bFree.length === bChildren.length) { + return { + children: bChildren, + moves: null + } + } -function isHook(hook) { - return hook && - (typeof hook.hook === "function" && !hook.hasOwnProperty("hook") || - typeof hook.unhook === "function" && !hook.hasOwnProperty("unhook")) -} + // O(N) time, O(N) memory + var aChildIndex = keyIndex(aChildren) + var aKeys = aChildIndex.keys + var aFree = aChildIndex.free -},{}],14:[function(require,module,exports){ -var version = require("./version") + if (aFree.length === aChildren.length) { + return { + children: bChildren, + moves: null + } + } -module.exports = isVirtualNode + // O(MAX(N, M)) memory + var newChildren = [] -function isVirtualNode(x) { - return x && x.type === "VirtualNode" && x.version === version -} + var freeIndex = 0 + var freeCount = bFree.length + var deletedItems = 0 -},{"./version":17}],15:[function(require,module,exports){ -var version = require("./version") + // Iterate through a and match a node in b + // O(N) time, + for (var i = 0 ; i < aChildren.length; i++) { + var aItem = aChildren[i] + var itemIndex -module.exports = isVirtualText + if (aItem.key) { + if (bKeys.hasOwnProperty(aItem.key)) { + // Match up the old keys + itemIndex = bKeys[aItem.key] + newChildren.push(bChildren[itemIndex]) -function isVirtualText(x) { - return x && x.type === "VirtualText" && x.version === version -} + } else { + // Remove old keyed items + itemIndex = i - deletedItems++ + newChildren.push(null) + } + } else { + // Match the item in a with the next free item in b + if (freeIndex < freeCount) { + itemIndex = bFree[freeIndex++] + newChildren.push(bChildren[itemIndex]) + } else { + // There are no free items in b to match with + // the free items in a, so the extra free nodes + // are deleted. + itemIndex = i - deletedItems++ + newChildren.push(null) + } + } + } -},{"./version":17}],16:[function(require,module,exports){ -module.exports = isWidget + var lastFreeIndex = freeIndex >= bFree.length ? + bChildren.length : + bFree[freeIndex] -function isWidget(w) { - return w && w.type === "Widget" -} + // Iterate through b and append any new keys + // O(M) time + for (var j = 0; j < bChildren.length; j++) { + var newItem = bChildren[j] -},{}],17:[function(require,module,exports){ -module.exports = "2" + if (newItem.key) { + if (!aKeys.hasOwnProperty(newItem.key)) { + // Add any new keyed items + // We are adding new items to the end and then sorting them + // in place. In future we should insert new items in place. + newChildren.push(newItem) + } + } else if (j >= lastFreeIndex) { + // Add any leftover non-keyed items + newChildren.push(newItem) + } + } -},{}],18:[function(require,module,exports){ -var version = require("./version") -var isVNode = require("./is-vnode") -var isWidget = require("./is-widget") -var isThunk = require("./is-thunk") -var isVHook = require("./is-vhook") + var simulate = newChildren.slice() + var simulateIndex = 0 + var removes = [] + var inserts = [] + var simulateItem -module.exports = VirtualNode + for (var k = 0; k < bChildren.length;) { + var wantedItem = bChildren[k] + simulateItem = simulate[simulateIndex] -var noProperties = {} -var noChildren = [] + // remove items + while (simulateItem === null && simulate.length) { + removes.push(remove(simulate, simulateIndex, null)) + simulateItem = simulate[simulateIndex] + } -function VirtualNode(tagName, properties, children, key, namespace) { - this.tagName = tagName - this.properties = properties || noProperties - this.children = children || noChildren - this.key = key != null ? String(key) : undefined - this.namespace = (typeof namespace === "string") ? namespace : null + if (!simulateItem || simulateItem.key !== wantedItem.key) { + // if we need a key in this position... + if (wantedItem.key) { + if (simulateItem && simulateItem.key) { + // if an insert doesn't put this key in place, it needs to move + if (bKeys[simulateItem.key] !== k + 1) { + removes.push(remove(simulate, simulateIndex, simulateItem.key)) + simulateItem = simulate[simulateIndex] + // if the remove didn't put the wanted item in place, we need to insert it + if (!simulateItem || simulateItem.key !== wantedItem.key) { + inserts.push({key: wantedItem.key, to: k}) + } + // items are matching, so skip ahead + else { + simulateIndex++ + } + } + else { + inserts.push({key: wantedItem.key, to: k}) + } + } + else { + inserts.push({key: wantedItem.key, to: k}) + } + k++ + } + // a key in simulate has no matching wanted key, remove it + else if (simulateItem && simulateItem.key) { + removes.push(remove(simulate, simulateIndex, simulateItem.key)) + } + } + else { + simulateIndex++ + k++ + } + } - var count = (children && children.length) || 0 - var descendants = 0 - var hasWidgets = false - var hasThunks = false - var descendantHooks = false - var hooks + // remove all the remaining nodes from simulate + while(simulateIndex < simulate.length) { + simulateItem = simulate[simulateIndex] + removes.push(remove(simulate, simulateIndex, simulateItem && simulateItem.key)) + } - for (var propName in properties) { - if (properties.hasOwnProperty(propName)) { - var property = properties[propName] - if (isVHook(property) && property.unhook) { - if (!hooks) { - hooks = {} - } + // If the only moves we have are deletes then we can just + // let the delete patch remove these items. + if (removes.length === deletedItems && !inserts.length) { + return { + children: newChildren, + moves: null + } + } - hooks[propName] = property - } + return { + children: newChildren, + moves: { + removes: removes, + inserts: inserts } } +} - for (var i = 0; i < count; i++) { - var child = children[i] - if (isVNode(child)) { - descendants += child.count || 0 +function remove(arr, index, key) { + arr.splice(index, 1) - if (!hasWidgets && child.hasWidgets) { - hasWidgets = true - } + return { + from: index, + key: key + } +} - if (!hasThunks && child.hasThunks) { - hasThunks = true - } +function keyIndex(children) { + var keys = {} + var free = [] + var length = children.length - if (!descendantHooks && (child.hooks || child.descendantHooks)) { - descendantHooks = true - } - } else if (!hasWidgets && isWidget(child)) { - if (typeof child.destroy === "function") { - hasWidgets = true - } - } else if (!hasThunks && isThunk(child)) { - hasThunks = true; + for (var i = 0; i < length; i++) { + var child = children[i] + + if (child.key) { + keys[child.key] = i + } else { + free.push(i) } } - this.count = count + descendants - this.hasWidgets = hasWidgets - this.hasThunks = hasThunks - this.hooks = hooks - this.descendantHooks = descendantHooks + return { + keys: keys, // A hash of key name to index + free: free, // An array of unkeyed item indices + } } -VirtualNode.prototype.version = version -VirtualNode.prototype.type = "VirtualNode" +function appendPatch(apply, patch) { + if (apply) { + if (isArray(apply)) { + apply.push(patch) + } else { + apply = [apply, patch] + } -},{"./is-thunk":12,"./is-vhook":13,"./is-vnode":14,"./is-widget":16,"./version":17}],19:[function(require,module,exports){ -var version = require("./version") + return apply + } else { + return patch + } +} -VirtualPatch.NONE = 0 -VirtualPatch.VTEXT = 1 -VirtualPatch.VNODE = 2 -VirtualPatch.WIDGET = 3 -VirtualPatch.PROPS = 4 -VirtualPatch.ORDER = 5 -VirtualPatch.INSERT = 6 -VirtualPatch.REMOVE = 7 -VirtualPatch.THUNK = 8 +},{"../vnode/handle-thunk":11,"../vnode/is-thunk":12,"../vnode/is-vnode":14,"../vnode/is-vtext":15,"../vnode/is-widget":16,"../vnode/vpatch":19,"./diff-props":21,"x-is-array":4}],23:[function(require,module,exports){ +var VNode = require('virtual-dom/vnode/vnode'); +var VText = require('virtual-dom/vnode/vtext'); +var diff = require('virtual-dom/vtree/diff'); +var patch = require('virtual-dom/vdom/patch'); +var createElement = require('virtual-dom/vdom/create-element'); +var isHook = require("virtual-dom/vnode/is-vhook"); -module.exports = VirtualPatch -function VirtualPatch(type, vNode, patch) { - this.type = Number(type) - this.vNode = vNode - this.patch = patch -} +Elm.Native.VirtualDom = {}; +Elm.Native.VirtualDom.make = function(elm) +{ + elm.Native = elm.Native || {}; + elm.Native.VirtualDom = elm.Native.VirtualDom || {}; + if (elm.Native.VirtualDom.values) + { + return elm.Native.VirtualDom.values; + } -VirtualPatch.prototype.version = version -VirtualPatch.prototype.type = "VirtualPatch" + var Element = Elm.Native.Graphics.Element.make(elm); + var Json = Elm.Native.Json.make(elm); + var List = Elm.Native.List.make(elm); + var Signal = Elm.Native.Signal.make(elm); + var Utils = Elm.Native.Utils.make(elm); -},{"./version":17}],20:[function(require,module,exports){ -var version = require("./version") + var ATTRIBUTE_KEY = 'UniqueNameThatOthersAreVeryUnlikelyToUse'; -module.exports = VirtualText -function VirtualText(text) { - this.text = String(text) -} -VirtualText.prototype.version = version -VirtualText.prototype.type = "VirtualText" + // VIRTUAL DOM NODES -},{"./version":17}],21:[function(require,module,exports){ -var isObject = require("is-object") -var isHook = require("../vnode/is-vhook") -module.exports = diffProps + function text(string) + { + return new VText(string); + } -function diffProps(a, b) { - var diff + function node(name) + { + return F2(function(propertyList, contents) { + return makeNode(name, propertyList, contents); + }); + } - for (var aKey in a) { - if (!(aKey in b)) { - diff = diff || {} - diff[aKey] = undefined - } - var aValue = a[aKey] - var bValue = b[aKey] + // BUILD VIRTUAL DOME NODES - if (aValue === bValue) { - continue - } else if (isObject(aValue) && isObject(bValue)) { - if (getPrototype(bValue) !== getPrototype(aValue)) { - diff = diff || {} - diff[aKey] = bValue - } else if (isHook(bValue)) { - diff = diff || {} - diff[aKey] = bValue - } else { - var objectDiff = diffProps(aValue, bValue) - if (objectDiff) { - diff = diff || {} - diff[aKey] = objectDiff - } - } - } else { - diff = diff || {} - diff[aKey] = bValue - } - } - for (var bKey in b) { - if (!(bKey in a)) { - diff = diff || {} - diff[bKey] = b[bKey] - } - } + function makeNode(name, propertyList, contents) + { + var props = listToProperties(propertyList); - return diff -} + var key, namespace; + // support keys + if (props.key !== undefined) + { + key = props.key; + props.key = undefined; + } -function getPrototype(value) { - if (Object.getPrototypeOf) { - return Object.getPrototypeOf(value) - } else if (value.__proto__) { - return value.__proto__ - } else if (value.constructor) { - return value.constructor.prototype - } -} + // support namespace + if (props.namespace !== undefined) + { + namespace = props.namespace; + props.namespace = undefined; + } -},{"../vnode/is-vhook":13,"is-object":3}],22:[function(require,module,exports){ -var isArray = require("x-is-array") + // ensure that setting text of an input does not move the cursor + var useSoftSet = + (name === 'input' || name === 'textarea') + && props.value !== undefined + && !isHook(props.value); -var VPatch = require("../vnode/vpatch") -var isVNode = require("../vnode/is-vnode") -var isVText = require("../vnode/is-vtext") -var isWidget = require("../vnode/is-widget") -var isThunk = require("../vnode/is-thunk") -var handleThunk = require("../vnode/handle-thunk") + if (useSoftSet) + { + props.value = SoftSetHook(props.value); + } -var diffProps = require("./diff-props") + return new VNode(name, props, List.toArray(contents), key, namespace); + } + + function listToProperties(list) + { + var object = {}; + while (list.ctor !== '[]') + { + var entry = list._0; + if (entry.key === ATTRIBUTE_KEY) + { + object.attributes = object.attributes || {}; + object.attributes[entry.value.attrKey] = entry.value.attrValue; + } + else + { + object[entry.key] = entry.value; + } + list = list._1; + } + return object; + } + + + + // PROPERTIES AND ATTRIBUTES -module.exports = diff -function diff(a, b) { - var patch = { a: a } - walk(a, b, patch, 0) - return patch -} + function property(key, value) + { + return { + key: key, + value: value + }; + } -function walk(a, b, patch, index) { - if (a === b) { - return - } + function attribute(key, value) + { + return { + key: ATTRIBUTE_KEY, + value: { + attrKey: key, + attrValue: value + } + }; + } - var apply = patch[index] - var applyClear = false - if (isThunk(a) || isThunk(b)) { - thunks(a, b, patch, index) - } else if (b == null) { - // If a is a widget we will add a remove patch for it - // Otherwise any child widgets/hooks must be destroyed. - // This prevents adding two remove patches for a widget. - if (!isWidget(a)) { - clearState(a, patch, index) - apply = patch[index] - } + // NAMESPACED ATTRIBUTES - apply = appendPatch(apply, new VPatch(VPatch.REMOVE, a, b)) - } else if (isVNode(b)) { - if (isVNode(a)) { - if (a.tagName === b.tagName && - a.namespace === b.namespace && - a.key === b.key) { - var propsPatch = diffProps(a.properties, b.properties) - if (propsPatch) { - apply = appendPatch(apply, - new VPatch(VPatch.PROPS, a, propsPatch)) - } - apply = diffChildren(a, b, patch, apply, index) - } else { - apply = appendPatch(apply, new VPatch(VPatch.VNODE, a, b)) - applyClear = true - } - } else { - apply = appendPatch(apply, new VPatch(VPatch.VNODE, a, b)) - applyClear = true - } - } else if (isVText(b)) { - if (!isVText(a)) { - apply = appendPatch(apply, new VPatch(VPatch.VTEXT, a, b)) - applyClear = true - } else if (a.text !== b.text) { - apply = appendPatch(apply, new VPatch(VPatch.VTEXT, a, b)) - } - } else if (isWidget(b)) { - if (!isWidget(a)) { - applyClear = true - } - apply = appendPatch(apply, new VPatch(VPatch.WIDGET, a, b)) - } + function attributeNS(namespace, key, value) + { + return { + key: key, + value: new AttributeHook(namespace, key, value) + }; + } - if (apply) { - patch[index] = apply - } + function AttributeHook(namespace, key, value) + { + if (!(this instanceof AttributeHook)) + { + return new AttributeHook(namespace, key, value); + } - if (applyClear) { - clearState(a, patch, index) - } -} + this.namespace = namespace; + this.key = key; + this.value = value; + } -function diffChildren(a, b, patch, apply, index) { - var aChildren = a.children - var orderedSet = reorder(aChildren, b.children) - var bChildren = orderedSet.children + AttributeHook.prototype.hook = function (node, prop, prev) + { + if (prev + && prev.type === 'AttributeHook' + && prev.value === this.value + && prev.namespace === this.namespace) + { + return; + } - var aLen = aChildren.length - var bLen = bChildren.length - var len = aLen > bLen ? aLen : bLen + node.setAttributeNS(this.namespace, prop, this.value); + }; - for (var i = 0; i < len; i++) { - var leftNode = aChildren[i] - var rightNode = bChildren[i] - index += 1 + AttributeHook.prototype.unhook = function (node, prop, next) + { + if (next + && next.type === 'AttributeHook' + && next.namespace === this.namespace) + { + return; + } - if (!leftNode) { - if (rightNode) { - // Excess nodes in b need to be added - apply = appendPatch(apply, - new VPatch(VPatch.INSERT, null, rightNode)) - } - } else { - walk(leftNode, rightNode, patch, index) - } + node.removeAttributeNS(this.namespace, this.key); + }; - if (isVNode(leftNode) && leftNode.count) { - index += leftNode.count - } - } + AttributeHook.prototype.type = 'AttributeHook'; - if (orderedSet.moves) { - // Reorder nodes last - apply = appendPatch(apply, new VPatch( - VPatch.ORDER, - a, - orderedSet.moves - )) - } - return apply -} -function clearState(vNode, patch, index) { - // TODO: Make this a single walk, not two - unhook(vNode, patch, index) - destroyWidgets(vNode, patch, index) -} + // EVENTS -// Patch records for all destroyed widgets must be added because we need -// a DOM node reference for the destroy function -function destroyWidgets(vNode, patch, index) { - if (isWidget(vNode)) { - if (typeof vNode.destroy === "function") { - patch[index] = appendPatch( - patch[index], - new VPatch(VPatch.REMOVE, vNode, null) - ) - } - } else if (isVNode(vNode) && (vNode.hasWidgets || vNode.hasThunks)) { - var children = vNode.children - var len = children.length - for (var i = 0; i < len; i++) { - var child = children[i] - index += 1 - destroyWidgets(child, patch, index) + function on(name, options, decoder, createMessage) + { + function eventHandler(event) + { + var value = A2(Json.runDecoderValue, decoder, event); + if (value.ctor === 'Ok') + { + if (options.stopPropagation) + { + event.stopPropagation(); + } + if (options.preventDefault) + { + event.preventDefault(); + } + Signal.sendMessage(createMessage(value._0)); + } + } + return property('on' + name, eventHandler); + } - if (isVNode(child) && child.count) { - index += child.count - } - } - } else if (isThunk(vNode)) { - thunks(vNode, null, patch, index) - } -} + function SoftSetHook(value) + { + if (!(this instanceof SoftSetHook)) + { + return new SoftSetHook(value); + } -// Create a sub-patch for thunks -function thunks(a, b, patch, index) { - var nodes = handleThunk(a, b) - var thunkPatch = diff(nodes.a, nodes.b) - if (hasPatches(thunkPatch)) { - patch[index] = new VPatch(VPatch.THUNK, null, thunkPatch) - } -} + this.value = value; + } -function hasPatches(patch) { - for (var index in patch) { - if (index !== "a") { - return true - } - } + SoftSetHook.prototype.hook = function (node, propertyName) + { + if (node[propertyName] !== this.value) + { + node[propertyName] = this.value; + } + }; - return false -} -// Execute hooks when two nodes are identical -function unhook(vNode, patch, index) { - if (isVNode(vNode)) { - if (vNode.hooks) { - patch[index] = appendPatch( - patch[index], - new VPatch( - VPatch.PROPS, - vNode, - undefinedKeys(vNode.hooks) - ) - ) - } - if (vNode.descendantHooks || vNode.hasThunks) { - var children = vNode.children - var len = children.length - for (var i = 0; i < len; i++) { - var child = children[i] - index += 1 + // INTEGRATION WITH ELEMENTS - unhook(child, patch, index) - if (isVNode(child) && child.count) { - index += child.count - } - } - } - } else if (isThunk(vNode)) { - thunks(vNode, null, patch, index) - } -} + function ElementWidget(element) + { + this.element = element; + } -function undefinedKeys(obj) { - var result = {} + ElementWidget.prototype.type = "Widget"; - for (var key in obj) { - result[key] = undefined - } + ElementWidget.prototype.init = function init() + { + return Element.render(this.element); + }; - return result -} + ElementWidget.prototype.update = function update(previous, node) + { + return Element.update(node, previous.element, this.element); + }; -// List diff, naive left to right reordering -function reorder(aChildren, bChildren) { - // O(M) time, O(M) memory - var bChildIndex = keyIndex(bChildren) - var bKeys = bChildIndex.keys - var bFree = bChildIndex.free + function fromElement(element) + { + return new ElementWidget(element); + } - if (bFree.length === bChildren.length) { - return { - children: bChildren, - moves: null - } - } + function toElement(width, height, html) + { + return A3(Element.newElement, width, height, { + ctor: 'Custom', + type: 'evancz/elm-html', + render: render, + update: update, + model: html + }); + } - // O(N) time, O(N) memory - var aChildIndex = keyIndex(aChildren) - var aKeys = aChildIndex.keys - var aFree = aChildIndex.free - if (aFree.length === aChildren.length) { - return { - children: bChildren, - moves: null - } - } - // O(MAX(N, M)) memory - var newChildren = [] + // RENDER AND UPDATE - var freeIndex = 0 - var freeCount = bFree.length - var deletedItems = 0 - // Iterate through a and match a node in b - // O(N) time, - for (var i = 0 ; i < aChildren.length; i++) { - var aItem = aChildren[i] - var itemIndex + function render(model) + { + var element = Element.createNode('div'); + element.appendChild(createElement(model)); + return element; + } - if (aItem.key) { - if (bKeys.hasOwnProperty(aItem.key)) { - // Match up the old keys - itemIndex = bKeys[aItem.key] - newChildren.push(bChildren[itemIndex]) + function update(node, oldModel, newModel) + { + updateAndReplace(node.firstChild, oldModel, newModel); + return node; + } - } else { - // Remove old keyed items - itemIndex = i - deletedItems++ - newChildren.push(null) - } - } else { - // Match the item in a with the next free item in b - if (freeIndex < freeCount) { - itemIndex = bFree[freeIndex++] - newChildren.push(bChildren[itemIndex]) - } else { - // There are no free items in b to match with - // the free items in a, so the extra free nodes - // are deleted. - itemIndex = i - deletedItems++ - newChildren.push(null) - } - } - } + function updateAndReplace(node, oldModel, newModel) + { + var patches = diff(oldModel, newModel); + var newNode = patch(node, patches); + return newNode; + } - var lastFreeIndex = freeIndex >= bFree.length ? - bChildren.length : - bFree[freeIndex] - // Iterate through b and append any new keys - // O(M) time - for (var j = 0; j < bChildren.length; j++) { - var newItem = bChildren[j] - if (newItem.key) { - if (!aKeys.hasOwnProperty(newItem.key)) { - // Add any new keyed items - // We are adding new items to the end and then sorting them - // in place. In future we should insert new items in place. - newChildren.push(newItem) - } - } else if (j >= lastFreeIndex) { - // Add any leftover non-keyed items - newChildren.push(newItem) - } - } + // LAZINESS - var simulate = newChildren.slice() - var simulateIndex = 0 - var removes = [] - var inserts = [] - var simulateItem - for (var k = 0; k < bChildren.length;) { - var wantedItem = bChildren[k] - simulateItem = simulate[simulateIndex] + function lazyRef(fn, a) + { + function thunk() + { + return fn(a); + } + return new Thunk(fn, [a], thunk); + } - // remove items - while (simulateItem === null && simulate.length) { - removes.push(remove(simulate, simulateIndex, null)) - simulateItem = simulate[simulateIndex] - } + function lazyRef2(fn, a, b) + { + function thunk() + { + return A2(fn, a, b); + } + return new Thunk(fn, [a,b], thunk); + } - if (!simulateItem || simulateItem.key !== wantedItem.key) { - // if we need a key in this position... - if (wantedItem.key) { - if (simulateItem && simulateItem.key) { - // if an insert doesn't put this key in place, it needs to move - if (bKeys[simulateItem.key] !== k + 1) { - removes.push(remove(simulate, simulateIndex, simulateItem.key)) - simulateItem = simulate[simulateIndex] - // if the remove didn't put the wanted item in place, we need to insert it - if (!simulateItem || simulateItem.key !== wantedItem.key) { - inserts.push({key: wantedItem.key, to: k}) - } - // items are matching, so skip ahead - else { - simulateIndex++ - } - } - else { - inserts.push({key: wantedItem.key, to: k}) - } - } - else { - inserts.push({key: wantedItem.key, to: k}) - } - k++ - } - // a key in simulate has no matching wanted key, remove it - else if (simulateItem && simulateItem.key) { - removes.push(remove(simulate, simulateIndex, simulateItem.key)) - } - } - else { - simulateIndex++ - k++ - } - } + function lazyRef3(fn, a, b, c) + { + function thunk() + { + return A3(fn, a, b, c); + } + return new Thunk(fn, [a,b,c], thunk); + } - // remove all the remaining nodes from simulate - while(simulateIndex < simulate.length) { - simulateItem = simulate[simulateIndex] - removes.push(remove(simulate, simulateIndex, simulateItem && simulateItem.key)) - } + function Thunk(fn, args, thunk) + { + /* public (used by VirtualDom.js) */ + this.vnode = null; + this.key = undefined; - // If the only moves we have are deletes then we can just - // let the delete patch remove these items. - if (removes.length === deletedItems && !inserts.length) { - return { - children: newChildren, - moves: null - } - } + /* private */ + this.fn = fn; + this.args = args; + this.thunk = thunk; + } - return { - children: newChildren, - moves: { - removes: removes, - inserts: inserts - } - } -} + Thunk.prototype.type = "Thunk"; + Thunk.prototype.render = renderThunk; -function remove(arr, index, key) { - arr.splice(index, 1) + function shouldUpdate(current, previous) + { + if (current.fn !== previous.fn) + { + return true; + } - return { - from: index, - key: key - } -} + // if it's the same function, we know the number of args must match + var cargs = current.args; + var pargs = previous.args; -function keyIndex(children) { - var keys = {} - var free = [] - var length = children.length + for (var i = cargs.length; i--; ) + { + if (cargs[i] !== pargs[i]) + { + return true; + } + } - for (var i = 0; i < length; i++) { - var child = children[i] + return false; + } - if (child.key) { - keys[child.key] = i - } else { - free.push(i) - } - } + function renderThunk(previous) + { + if (previous == null || shouldUpdate(this, previous)) + { + return this.thunk(); + } + else + { + return previous.vnode; + } + } - return { - keys: keys, // A hash of key name to index - free: free, // An array of unkeyed item indices - } -} -function appendPatch(apply, patch) { - if (apply) { - if (isArray(apply)) { - apply.push(patch) - } else { - apply = [apply, patch] - } + return elm.Native.VirtualDom.values = Elm.Native.VirtualDom.values = { + node: node, + text: text, + on: F4(on), - return apply - } else { - return patch - } -} + property: F2(property), + attribute: F2(attribute), + attributeNS: F3(attributeNS), -},{"../vnode/handle-thunk":11,"../vnode/is-thunk":12,"../vnode/is-vnode":14,"../vnode/is-vtext":15,"../vnode/is-widget":16,"../vnode/vpatch":19,"./diff-props":21,"x-is-array":4}],23:[function(require,module,exports){ -var VNode = require('virtual-dom/vnode/vnode'); -var VText = require('virtual-dom/vnode/vtext'); -var diff = require('virtual-dom/vtree/diff'); -var patch = require('virtual-dom/vdom/patch'); -var createElement = require('virtual-dom/create-element'); -var isHook = require("virtual-dom/vnode/is-vhook"); + lazy: F2(lazyRef), + lazy2: F3(lazyRef2), + lazy3: F4(lazyRef3), + toElement: F3(toElement), + fromElement: fromElement, -Elm.Native.VirtualDom = {}; -Elm.Native.VirtualDom.make = function(elm) -{ - elm.Native = elm.Native || {}; - elm.Native.VirtualDom = elm.Native.VirtualDom || {}; - if (elm.Native.VirtualDom.values) - { - return elm.Native.VirtualDom.values; - } + render: createElement, + updateAndReplace: updateAndReplace + }; +}; - var Element = Elm.Native.Graphics.Element.make(elm); - var Json = Elm.Native.Json.make(elm); - var List = Elm.Native.List.make(elm); - var Signal = Elm.Native.Signal.make(elm); - var Utils = Elm.Native.Utils.make(elm); +},{"virtual-dom/vdom/create-element":6,"virtual-dom/vdom/patch":9,"virtual-dom/vnode/is-vhook":13,"virtual-dom/vnode/vnode":18,"virtual-dom/vnode/vtext":20,"virtual-dom/vtree/diff":22}]},{},[23]); - var ATTRIBUTE_KEY = 'UniqueNameThatOthersAreVeryUnlikelyToUse'; +Elm.VirtualDom = Elm.VirtualDom || {}; +Elm.VirtualDom.make = function (_elm) { + "use strict"; + _elm.VirtualDom = _elm.VirtualDom || {}; + if (_elm.VirtualDom.values) return _elm.VirtualDom.values; + var _U = Elm.Native.Utils.make(_elm), + $Basics = Elm.Basics.make(_elm), + $Debug = Elm.Debug.make(_elm), + $Graphics$Element = Elm.Graphics.Element.make(_elm), + $Json$Decode = Elm.Json.Decode.make(_elm), + $List = Elm.List.make(_elm), + $Maybe = Elm.Maybe.make(_elm), + $Native$VirtualDom = Elm.Native.VirtualDom.make(_elm), + $Result = Elm.Result.make(_elm), + $Signal = Elm.Signal.make(_elm); + var _op = {}; + var lazy3 = $Native$VirtualDom.lazy3; + var lazy2 = $Native$VirtualDom.lazy2; + var lazy = $Native$VirtualDom.lazy; + var defaultOptions = {stopPropagation: false,preventDefault: false}; + var Options = F2(function (a,b) { return {stopPropagation: a,preventDefault: b};}); + var onWithOptions = $Native$VirtualDom.on; + var on = F3(function (eventName,decoder,toMessage) { return A4($Native$VirtualDom.on,eventName,defaultOptions,decoder,toMessage);}); + var attributeNS = $Native$VirtualDom.attributeNS; + var attribute = $Native$VirtualDom.attribute; + var property = $Native$VirtualDom.property; + var Property = {ctor: "Property"}; + var fromElement = $Native$VirtualDom.fromElement; + var toElement = $Native$VirtualDom.toElement; + var text = $Native$VirtualDom.text; + var node = $Native$VirtualDom.node; + var Node = {ctor: "Node"}; + return _elm.VirtualDom.values = {_op: _op + ,text: text + ,node: node + ,toElement: toElement + ,fromElement: fromElement + ,property: property + ,attribute: attribute + ,attributeNS: attributeNS + ,on: on + ,onWithOptions: onWithOptions + ,defaultOptions: defaultOptions + ,lazy: lazy + ,lazy2: lazy2 + ,lazy3: lazy3 + ,Options: Options}; +}; +Elm.Html = Elm.Html || {}; +Elm.Html.make = function (_elm) { + "use strict"; + _elm.Html = _elm.Html || {}; + if (_elm.Html.values) return _elm.Html.values; + var _U = Elm.Native.Utils.make(_elm), + $Basics = Elm.Basics.make(_elm), + $Debug = Elm.Debug.make(_elm), + $Graphics$Element = Elm.Graphics.Element.make(_elm), + $List = Elm.List.make(_elm), + $Maybe = Elm.Maybe.make(_elm), + $Result = Elm.Result.make(_elm), + $Signal = Elm.Signal.make(_elm), + $VirtualDom = Elm.VirtualDom.make(_elm); + var _op = {}; + var fromElement = $VirtualDom.fromElement; + var toElement = $VirtualDom.toElement; + var text = $VirtualDom.text; + var node = $VirtualDom.node; + var body = node("body"); + var section = node("section"); + var nav = node("nav"); + var article = node("article"); + var aside = node("aside"); + var h1 = node("h1"); + var h2 = node("h2"); + var h3 = node("h3"); + var h4 = node("h4"); + var h5 = node("h5"); + var h6 = node("h6"); + var header = node("header"); + var footer = node("footer"); + var address = node("address"); + var main$ = node("main"); + var p = node("p"); + var hr = node("hr"); + var pre = node("pre"); + var blockquote = node("blockquote"); + var ol = node("ol"); + var ul = node("ul"); + var li = node("li"); + var dl = node("dl"); + var dt = node("dt"); + var dd = node("dd"); + var figure = node("figure"); + var figcaption = node("figcaption"); + var div = node("div"); + var a = node("a"); + var em = node("em"); + var strong = node("strong"); + var small = node("small"); + var s = node("s"); + var cite = node("cite"); + var q = node("q"); + var dfn = node("dfn"); + var abbr = node("abbr"); + var time = node("time"); + var code = node("code"); + var $var = node("var"); + var samp = node("samp"); + var kbd = node("kbd"); + var sub = node("sub"); + var sup = node("sup"); + var i = node("i"); + var b = node("b"); + var u = node("u"); + var mark = node("mark"); + var ruby = node("ruby"); + var rt = node("rt"); + var rp = node("rp"); + var bdi = node("bdi"); + var bdo = node("bdo"); + var span = node("span"); + var br = node("br"); + var wbr = node("wbr"); + var ins = node("ins"); + var del = node("del"); + var img = node("img"); + var iframe = node("iframe"); + var embed = node("embed"); + var object = node("object"); + var param = node("param"); + var video = node("video"); + var audio = node("audio"); + var source = node("source"); + var track = node("track"); + var canvas = node("canvas"); + var svg = node("svg"); + var math = node("math"); + var table = node("table"); + var caption = node("caption"); + var colgroup = node("colgroup"); + var col = node("col"); + var tbody = node("tbody"); + var thead = node("thead"); + var tfoot = node("tfoot"); + var tr = node("tr"); + var td = node("td"); + var th = node("th"); + var form = node("form"); + var fieldset = node("fieldset"); + var legend = node("legend"); + var label = node("label"); + var input = node("input"); + var button = node("button"); + var select = node("select"); + var datalist = node("datalist"); + var optgroup = node("optgroup"); + var option = node("option"); + var textarea = node("textarea"); + var keygen = node("keygen"); + var output = node("output"); + var progress = node("progress"); + var meter = node("meter"); + var details = node("details"); + var summary = node("summary"); + var menuitem = node("menuitem"); + var menu = node("menu"); + return _elm.Html.values = {_op: _op + ,node: node + ,text: text + ,toElement: toElement + ,fromElement: fromElement + ,body: body + ,section: section + ,nav: nav + ,article: article + ,aside: aside + ,h1: h1 + ,h2: h2 + ,h3: h3 + ,h4: h4 + ,h5: h5 + ,h6: h6 + ,header: header + ,footer: footer + ,address: address + ,main$: main$ + ,p: p + ,hr: hr + ,pre: pre + ,blockquote: blockquote + ,ol: ol + ,ul: ul + ,li: li + ,dl: dl + ,dt: dt + ,dd: dd + ,figure: figure + ,figcaption: figcaption + ,div: div + ,a: a + ,em: em + ,strong: strong + ,small: small + ,s: s + ,cite: cite + ,q: q + ,dfn: dfn + ,abbr: abbr + ,time: time + ,code: code + ,$var: $var + ,samp: samp + ,kbd: kbd + ,sub: sub + ,sup: sup + ,i: i + ,b: b + ,u: u + ,mark: mark + ,ruby: ruby + ,rt: rt + ,rp: rp + ,bdi: bdi + ,bdo: bdo + ,span: span + ,br: br + ,wbr: wbr + ,ins: ins + ,del: del + ,img: img + ,iframe: iframe + ,embed: embed + ,object: object + ,param: param + ,video: video + ,audio: audio + ,source: source + ,track: track + ,canvas: canvas + ,svg: svg + ,math: math + ,table: table + ,caption: caption + ,colgroup: colgroup + ,col: col + ,tbody: tbody + ,thead: thead + ,tfoot: tfoot + ,tr: tr + ,td: td + ,th: th + ,form: form + ,fieldset: fieldset + ,legend: legend + ,label: label + ,input: input + ,button: button + ,select: select + ,datalist: datalist + ,optgroup: optgroup + ,option: option + ,textarea: textarea + ,keygen: keygen + ,output: output + ,progress: progress + ,meter: meter + ,details: details + ,summary: summary + ,menuitem: menuitem + ,menu: menu}; +}; +Elm.Html = Elm.Html || {}; +Elm.Html.Attributes = Elm.Html.Attributes || {}; +Elm.Html.Attributes.make = function (_elm) { + "use strict"; + _elm.Html = _elm.Html || {}; + _elm.Html.Attributes = _elm.Html.Attributes || {}; + if (_elm.Html.Attributes.values) return _elm.Html.Attributes.values; + var _U = Elm.Native.Utils.make(_elm), + $Basics = Elm.Basics.make(_elm), + $Debug = Elm.Debug.make(_elm), + $Html = Elm.Html.make(_elm), + $Json$Encode = Elm.Json.Encode.make(_elm), + $List = Elm.List.make(_elm), + $Maybe = Elm.Maybe.make(_elm), + $Result = Elm.Result.make(_elm), + $Signal = Elm.Signal.make(_elm), + $String = Elm.String.make(_elm), + $VirtualDom = Elm.VirtualDom.make(_elm); + var _op = {}; + var attribute = $VirtualDom.attribute; + var contextmenu = function (value) { return A2(attribute,"contextmenu",value);}; + var property = $VirtualDom.property; + var stringProperty = F2(function (name,string) { return A2(property,name,$Json$Encode.string(string));}); + var $class = function (name) { return A2(stringProperty,"className",name);}; + var id = function (name) { return A2(stringProperty,"id",name);}; + var title = function (name) { return A2(stringProperty,"title",name);}; + var accesskey = function ($char) { return A2(stringProperty,"accessKey",$String.fromChar($char));}; + var dir = function (value) { return A2(stringProperty,"dir",value);}; + var draggable = function (value) { return A2(stringProperty,"draggable",value);}; + var dropzone = function (value) { return A2(stringProperty,"dropzone",value);}; + var itemprop = function (value) { return A2(stringProperty,"itemprop",value);}; + var lang = function (value) { return A2(stringProperty,"lang",value);}; + var tabindex = function (n) { return A2(stringProperty,"tabIndex",$Basics.toString(n));}; + var charset = function (value) { return A2(stringProperty,"charset",value);}; + var content = function (value) { return A2(stringProperty,"content",value);}; + var httpEquiv = function (value) { return A2(stringProperty,"httpEquiv",value);}; + var language = function (value) { return A2(stringProperty,"language",value);}; + var src = function (value) { return A2(stringProperty,"src",value);}; + var height = function (value) { return A2(stringProperty,"height",$Basics.toString(value));}; + var width = function (value) { return A2(stringProperty,"width",$Basics.toString(value));}; + var alt = function (value) { return A2(stringProperty,"alt",value);}; + var preload = function (value) { return A2(stringProperty,"preload",value);}; + var poster = function (value) { return A2(stringProperty,"poster",value);}; + var kind = function (value) { return A2(stringProperty,"kind",value);}; + var srclang = function (value) { return A2(stringProperty,"srclang",value);}; + var sandbox = function (value) { return A2(stringProperty,"sandbox",value);}; + var srcdoc = function (value) { return A2(stringProperty,"srcdoc",value);}; + var type$ = function (value) { return A2(stringProperty,"type",value);}; + var value = function (value) { return A2(stringProperty,"value",value);}; + var placeholder = function (value) { return A2(stringProperty,"placeholder",value);}; + var accept = function (value) { return A2(stringProperty,"accept",value);}; + var acceptCharset = function (value) { return A2(stringProperty,"acceptCharset",value);}; + var action = function (value) { return A2(stringProperty,"action",value);}; + var autocomplete = function (bool) { return A2(stringProperty,"autocomplete",bool ? "on" : "off");}; + var autosave = function (value) { return A2(stringProperty,"autosave",value);}; + var enctype = function (value) { return A2(stringProperty,"enctype",value);}; + var formaction = function (value) { return A2(stringProperty,"formAction",value);}; + var list = function (value) { return A2(stringProperty,"list",value);}; + var minlength = function (n) { return A2(stringProperty,"minLength",$Basics.toString(n));}; + var maxlength = function (n) { return A2(stringProperty,"maxLength",$Basics.toString(n));}; + var method = function (value) { return A2(stringProperty,"method",value);}; + var name = function (value) { return A2(stringProperty,"name",value);}; + var pattern = function (value) { return A2(stringProperty,"pattern",value);}; + var size = function (n) { return A2(stringProperty,"size",$Basics.toString(n));}; + var $for = function (value) { return A2(stringProperty,"htmlFor",value);}; + var form = function (value) { return A2(stringProperty,"form",value);}; + var max = function (value) { return A2(stringProperty,"max",value);}; + var min = function (value) { return A2(stringProperty,"min",value);}; + var step = function (n) { return A2(stringProperty,"step",n);}; + var cols = function (n) { return A2(stringProperty,"cols",$Basics.toString(n));}; + var rows = function (n) { return A2(stringProperty,"rows",$Basics.toString(n));}; + var wrap = function (value) { return A2(stringProperty,"wrap",value);}; + var usemap = function (value) { return A2(stringProperty,"useMap",value);}; + var shape = function (value) { return A2(stringProperty,"shape",value);}; + var coords = function (value) { return A2(stringProperty,"coords",value);}; + var challenge = function (value) { return A2(stringProperty,"challenge",value);}; + var keytype = function (value) { return A2(stringProperty,"keytype",value);}; + var align = function (value) { return A2(stringProperty,"align",value);}; + var cite = function (value) { return A2(stringProperty,"cite",value);}; + var href = function (value) { return A2(stringProperty,"href",value);}; + var target = function (value) { return A2(stringProperty,"target",value);}; + var downloadAs = function (value) { return A2(stringProperty,"download",value);}; + var hreflang = function (value) { return A2(stringProperty,"hreflang",value);}; + var media = function (value) { return A2(stringProperty,"media",value);}; + var ping = function (value) { return A2(stringProperty,"ping",value);}; + var rel = function (value) { return A2(stringProperty,"rel",value);}; + var datetime = function (value) { return A2(stringProperty,"datetime",value);}; + var pubdate = function (value) { return A2(stringProperty,"pubdate",value);}; + var start = function (n) { return A2(stringProperty,"start",$Basics.toString(n));}; + var colspan = function (n) { return A2(stringProperty,"colSpan",$Basics.toString(n));}; + var headers = function (value) { return A2(stringProperty,"headers",value);}; + var rowspan = function (n) { return A2(stringProperty,"rowSpan",$Basics.toString(n));}; + var scope = function (value) { return A2(stringProperty,"scope",value);}; + var manifest = function (value) { return A2(stringProperty,"manifest",value);}; + var boolProperty = F2(function (name,bool) { return A2(property,name,$Json$Encode.bool(bool));}); + var hidden = function (bool) { return A2(boolProperty,"hidden",bool);}; + var contenteditable = function (bool) { return A2(boolProperty,"contentEditable",bool);}; + var spellcheck = function (bool) { return A2(boolProperty,"spellcheck",bool);}; + var async = function (bool) { return A2(boolProperty,"async",bool);}; + var defer = function (bool) { return A2(boolProperty,"defer",bool);}; + var scoped = function (bool) { return A2(boolProperty,"scoped",bool);}; + var autoplay = function (bool) { return A2(boolProperty,"autoplay",bool);}; + var controls = function (bool) { return A2(boolProperty,"controls",bool);}; + var loop = function (bool) { return A2(boolProperty,"loop",bool);}; + var $default = function (bool) { return A2(boolProperty,"default",bool);}; + var seamless = function (bool) { return A2(boolProperty,"seamless",bool);}; + var checked = function (bool) { return A2(boolProperty,"checked",bool);}; + var selected = function (bool) { return A2(boolProperty,"selected",bool);}; + var autofocus = function (bool) { return A2(boolProperty,"autofocus",bool);}; + var disabled = function (bool) { return A2(boolProperty,"disabled",bool);}; + var multiple = function (bool) { return A2(boolProperty,"multiple",bool);}; + var novalidate = function (bool) { return A2(boolProperty,"noValidate",bool);}; + var readonly = function (bool) { return A2(boolProperty,"readOnly",bool);}; + var required = function (bool) { return A2(boolProperty,"required",bool);}; + var ismap = function (value) { return A2(boolProperty,"isMap",value);}; + var download = function (bool) { return A2(boolProperty,"download",bool);}; + var reversed = function (bool) { return A2(boolProperty,"reversed",bool);}; + var classList = function (list) { return $class(A2($String.join," ",A2($List.map,$Basics.fst,A2($List.filter,$Basics.snd,list))));}; + var style = function (props) { + return A2(property, + "style", + $Json$Encode.object(A2($List.map,function (_p0) { var _p1 = _p0;return {ctor: "_Tuple2",_0: _p1._0,_1: $Json$Encode.string(_p1._1)};},props))); + }; + var key = function (k) { return A2(stringProperty,"key",k);}; + return _elm.Html.Attributes.values = {_op: _op + ,key: key + ,style: style + ,$class: $class + ,classList: classList + ,id: id + ,title: title + ,hidden: hidden + ,type$: type$ + ,value: value + ,checked: checked + ,placeholder: placeholder + ,selected: selected + ,accept: accept + ,acceptCharset: acceptCharset + ,action: action + ,autocomplete: autocomplete + ,autofocus: autofocus + ,autosave: autosave + ,disabled: disabled + ,enctype: enctype + ,formaction: formaction + ,list: list + ,maxlength: maxlength + ,minlength: minlength + ,method: method + ,multiple: multiple + ,name: name + ,novalidate: novalidate + ,pattern: pattern + ,readonly: readonly + ,required: required + ,size: size + ,$for: $for + ,form: form + ,max: max + ,min: min + ,step: step + ,cols: cols + ,rows: rows + ,wrap: wrap + ,href: href + ,target: target + ,download: download + ,downloadAs: downloadAs + ,hreflang: hreflang + ,media: media + ,ping: ping + ,rel: rel + ,ismap: ismap + ,usemap: usemap + ,shape: shape + ,coords: coords + ,src: src + ,height: height + ,width: width + ,alt: alt + ,autoplay: autoplay + ,controls: controls + ,loop: loop + ,preload: preload + ,poster: poster + ,$default: $default + ,kind: kind + ,srclang: srclang + ,sandbox: sandbox + ,seamless: seamless + ,srcdoc: srcdoc + ,reversed: reversed + ,start: start + ,align: align + ,colspan: colspan + ,rowspan: rowspan + ,headers: headers + ,scope: scope + ,async: async + ,charset: charset + ,content: content + ,defer: defer + ,httpEquiv: httpEquiv + ,language: language + ,scoped: scoped + ,accesskey: accesskey + ,contenteditable: contenteditable + ,contextmenu: contextmenu + ,dir: dir + ,draggable: draggable + ,dropzone: dropzone + ,itemprop: itemprop + ,lang: lang + ,spellcheck: spellcheck + ,tabindex: tabindex + ,challenge: challenge + ,keytype: keytype + ,cite: cite + ,datetime: datetime + ,pubdate: pubdate + ,manifest: manifest + ,property: property + ,attribute: attribute}; +}; +Elm.Html = Elm.Html || {}; +Elm.Html.Events = Elm.Html.Events || {}; +Elm.Html.Events.make = function (_elm) { + "use strict"; + _elm.Html = _elm.Html || {}; + _elm.Html.Events = _elm.Html.Events || {}; + if (_elm.Html.Events.values) return _elm.Html.Events.values; + var _U = Elm.Native.Utils.make(_elm), + $Basics = Elm.Basics.make(_elm), + $Debug = Elm.Debug.make(_elm), + $Html = Elm.Html.make(_elm), + $Json$Decode = Elm.Json.Decode.make(_elm), + $List = Elm.List.make(_elm), + $Maybe = Elm.Maybe.make(_elm), + $Result = Elm.Result.make(_elm), + $Signal = Elm.Signal.make(_elm), + $VirtualDom = Elm.VirtualDom.make(_elm); + var _op = {}; + var keyCode = A2($Json$Decode._op[":="],"keyCode",$Json$Decode.$int); + var targetChecked = A2($Json$Decode.at,_U.list(["target","checked"]),$Json$Decode.bool); + var targetValue = A2($Json$Decode.at,_U.list(["target","value"]),$Json$Decode.string); + var defaultOptions = $VirtualDom.defaultOptions; + var Options = F2(function (a,b) { return {stopPropagation: a,preventDefault: b};}); + var onWithOptions = $VirtualDom.onWithOptions; + var on = $VirtualDom.on; + var messageOn = F3(function (name,addr,msg) { return A3(on,name,$Json$Decode.value,function (_p0) { return A2($Signal.message,addr,msg);});}); + var onClick = messageOn("click"); + var onDoubleClick = messageOn("dblclick"); + var onMouseMove = messageOn("mousemove"); + var onMouseDown = messageOn("mousedown"); + var onMouseUp = messageOn("mouseup"); + var onMouseEnter = messageOn("mouseenter"); + var onMouseLeave = messageOn("mouseleave"); + var onMouseOver = messageOn("mouseover"); + var onMouseOut = messageOn("mouseout"); + var onBlur = messageOn("blur"); + var onFocus = messageOn("focus"); + var onSubmit = messageOn("submit"); + var onKey = F3(function (name,addr,handler) { return A3(on,name,keyCode,function (code) { return A2($Signal.message,addr,handler(code));});}); + var onKeyUp = onKey("keyup"); + var onKeyDown = onKey("keydown"); + var onKeyPress = onKey("keypress"); + return _elm.Html.Events.values = {_op: _op + ,onBlur: onBlur + ,onFocus: onFocus + ,onSubmit: onSubmit + ,onKeyUp: onKeyUp + ,onKeyDown: onKeyDown + ,onKeyPress: onKeyPress + ,onClick: onClick + ,onDoubleClick: onDoubleClick + ,onMouseMove: onMouseMove + ,onMouseDown: onMouseDown + ,onMouseUp: onMouseUp + ,onMouseEnter: onMouseEnter + ,onMouseLeave: onMouseLeave + ,onMouseOver: onMouseOver + ,onMouseOut: onMouseOut + ,on: on + ,onWithOptions: onWithOptions + ,defaultOptions: defaultOptions + ,targetValue: targetValue + ,targetChecked: targetChecked + ,keyCode: keyCode + ,Options: Options}; +}; +Elm.StartApp = Elm.StartApp || {}; +Elm.StartApp.make = function (_elm) { + "use strict"; + _elm.StartApp = _elm.StartApp || {}; + if (_elm.StartApp.values) return _elm.StartApp.values; + var _U = Elm.Native.Utils.make(_elm), + $Basics = Elm.Basics.make(_elm), + $Debug = Elm.Debug.make(_elm), + $Effects = Elm.Effects.make(_elm), + $Html = Elm.Html.make(_elm), + $List = Elm.List.make(_elm), + $Maybe = Elm.Maybe.make(_elm), + $Result = Elm.Result.make(_elm), + $Signal = Elm.Signal.make(_elm), + $Task = Elm.Task.make(_elm); + var _op = {}; + var start = function (config) { + var updateStep = F2(function (action,_p0) { + var _p1 = _p0; + var _p2 = A2(config.update,action,_p1._0); + var newModel = _p2._0; + var additionalEffects = _p2._1; + return {ctor: "_Tuple2",_0: newModel,_1: $Effects.batch(_U.list([_p1._1,additionalEffects]))}; + }); + var update = F2(function (actions,_p3) { var _p4 = _p3;return A3($List.foldl,updateStep,{ctor: "_Tuple2",_0: _p4._0,_1: $Effects.none},actions);}); + var messages = $Signal.mailbox(_U.list([])); + var singleton = function (action) { return _U.list([action]);}; + var address = A2($Signal.forwardTo,messages.address,singleton); + var inputs = $Signal.mergeMany(A2($List._op["::"],messages.signal,A2($List.map,$Signal.map(singleton),config.inputs))); + var effectsAndModel = A3($Signal.foldp,update,config.init,inputs); + var model = A2($Signal.map,$Basics.fst,effectsAndModel); + return {html: A2($Signal.map,config.view(address),model) + ,model: model + ,tasks: A2($Signal.map,function (_p5) { return A2($Effects.toTask,messages.address,$Basics.snd(_p5));},effectsAndModel)}; + }; + var App = F3(function (a,b,c) { return {html: a,model: b,tasks: c};}); + var Config = F4(function (a,b,c,d) { return {init: a,update: b,view: c,inputs: d};}); + return _elm.StartApp.values = {_op: _op,start: start,Config: Config,App: App}; +}; +Elm.Native.Http = {}; +Elm.Native.Http.make = function(localRuntime) { - function listToProperties(list) + localRuntime.Native = localRuntime.Native || {}; + localRuntime.Native.Http = localRuntime.Native.Http || {}; + if (localRuntime.Native.Http.values) { - var object = {}; - while (list.ctor !== '[]') - { - var entry = list._0; - if (entry.key === ATTRIBUTE_KEY) - { - object.attributes = object.attributes || {}; - object.attributes[entry.value.attrKey] = entry.value.attrValue; - } - else - { - object[entry.key] = entry.value; - } - list = list._1; - } - return object; + return localRuntime.Native.Http.values; } - function node(name) - { - return F2(function(propertyList, contents) { - return makeNode(name, propertyList, contents); - }); - } + var Dict = Elm.Dict.make(localRuntime); + var List = Elm.List.make(localRuntime); + var Maybe = Elm.Maybe.make(localRuntime); + var Task = Elm.Native.Task.make(localRuntime); + var Utils = Elm.Native.Utils.make(localRuntime); - function makeNode(name, propertyList, contents) + function send(settings, request) { - var props = listToProperties(propertyList); - - var key, namespace; - // support keys - if (props.key !== undefined) - { - key = props.key; - props.key = undefined; - } - - // support namespace - if (props.namespace !== undefined) - { - namespace = props.namespace; - props.namespace = undefined; - } - - // ensure that setting text of an input does not move the cursor - var useSoftSet = - name === 'input' - && props.value !== undefined - && !isHook(props.value); - - if (useSoftSet) - { - props.value = SoftSetHook(props.value); - } + var req = new XMLHttpRequest(); - return new VNode(name, props, List.toArray(contents), key, namespace); - } + var abortTask = Task.asyncFunction(function(callback) { + req.abort(); + return callback(Task.succeed(Utils.Tuple0)); + }); - function property(key, value) - { - return { - key: key, - value: value - }; - } + var sendTask = Task.asyncFunction(function(callback) { - function attribute(key, value) - { - return { - key: ATTRIBUTE_KEY, - value: { - attrKey: key, - attrValue: value + // start + if (settings.onStart.ctor === 'Just') + { + req.addEventListener('loadStart', function() { + var task = settings.onStart._0; + Task.spawn(task); + }); } - }; - } - function on(name, options, decoder, createMessage) - { - function eventHandler(event) - { - var value = A2(Json.runDecoderValue, decoder, event); - if (value.ctor === 'Ok') + // progress + if (settings.onProgress.ctor === 'Just') { - if (options.stopPropagation) - { - event.stopPropagation(); - } - if (options.preventDefault) - { - event.preventDefault(); - } - Signal.sendMessage(createMessage(value._0)); + req.addEventListener('progress', function(event) { + var progress = !event.lengthComputable + ? Maybe.Nothing + : Maybe.Just({ + _: {}, + loaded: event.loaded, + total: event.total + }); + var task = settings.onProgress._0(progress); + Task.spawn(task); + }); } - } - return property('on' + name, eventHandler); - } - - function SoftSetHook(value) - { - if (!(this instanceof SoftSetHook)) - { - return new SoftSetHook(value); - } - - this.value = value; - } - - SoftSetHook.prototype.hook = function (node, propertyName) - { - if (node[propertyName] !== this.value) - { - node[propertyName] = this.value; - } - }; - - function text(string) - { - return new VText(string); - } - - function ElementWidget(element) - { - this.element = element; - } - - ElementWidget.prototype.type = "Widget"; - ElementWidget.prototype.init = function init() - { - return Element.render(this.element); - }; + // end + req.addEventListener('error', function() { + return callback(Task.fail({ ctor: 'RawNetworkError' })); + }); - ElementWidget.prototype.update = function update(previous, node) - { - return Element.update(node, previous.element, this.element); - }; + req.addEventListener('timeout', function() { + return callback(Task.fail({ ctor: 'RawTimeout' })); + }); - function fromElement(element) - { - return new ElementWidget(element); - } + req.addEventListener('load', function() { + return callback(Task.succeed(toResponse(req))); + }); - function toElement(width, height, html) - { - return A3(Element.newElement, width, height, { - ctor: 'Custom', - type: 'evancz/elm-html', - render: render, - update: update, - model: html - }); - } + req.open(request.verb, request.url, true); - function render(model) - { - var element = Element.createNode('div'); - element.appendChild(createElement(model)); - return element; - } + // set all the headers + function setHeader(pair) { + req.setRequestHeader(pair._0, pair._1); + } + A2(List.map, setHeader, request.headers); - function update(node, oldModel, newModel) - { - updateAndReplace(node.firstChild, oldModel, newModel); - return node; - } + // set the timeout + req.timeout = settings.timeout; - function updateAndReplace(node, oldModel, newModel) - { - var patches = diff(oldModel, newModel); - var newNode = patch(node, patches); - return newNode; - } + // enable this withCredentials thing + req.withCredentials = settings.withCredentials; - function lazyRef(fn, a) - { - function thunk() - { - return fn(a); - } - return new Thunk(fn, [a], thunk); - } + // ask for a specific MIME type for the response + if (settings.desiredResponseType.ctor === 'Just') + { + req.overrideMimeType(settings.desiredResponseType._0); + } - function lazyRef2(fn, a, b) - { - function thunk() - { - return A2(fn, a, b); - } - return new Thunk(fn, [a,b], thunk); - } + // actuall send the request + if(request.body.ctor === "BodyFormData") + { + req.send(request.body.formData) + } + else + { + req.send(request.body._0); + } + }); - function lazyRef3(fn, a, b, c) - { - function thunk() - { - return A3(fn, a, b, c); - } - return new Thunk(fn, [a,b,c], thunk); + return {ctor: "_Tuple2" + ,_0: sendTask + ,_1: abortTask}; } - function Thunk(fn, args, thunk) + + // deal with responses + + function toResponse(req) { - this.fn = fn; - this.args = args; - this.vnode = null; - this.key = undefined; - this.thunk = thunk; + var tag = req.responseType === 'blob' ? 'Blob' : 'Text' + var response = tag === 'Blob' ? req.response : req.responseText; + return { + _: {}, + status: req.status, + statusText: req.statusText, + headers: parseHeaders(req.getAllResponseHeaders()), + url: req.responseURL, + value: { ctor: tag, _0: response } + }; } - Thunk.prototype.type = "Thunk"; - Thunk.prototype.update = updateThunk; - Thunk.prototype.render = renderThunk; - function shouldUpdate(current, previous) + function parseHeaders(rawHeaders) { - if (current.fn !== previous.fn) + var headers = Dict.empty; + + if (!rawHeaders) { - return true; + return headers; } - // if it's the same function, we know the number of args must match - var cargs = current.args; - var pargs = previous.args; - - for (var i = cargs.length; i--; ) + var headerPairs = rawHeaders.split('\u000d\u000a'); + for (var i = headerPairs.length; i--; ) { - if (cargs[i] !== pargs[i]) + var headerPair = headerPairs[i]; + var index = headerPair.indexOf('\u003a\u0020'); + if (index > 0) { - return true; + var key = headerPair.substring(0, index); + var value = headerPair.substring(index + 2); + + headers = A3(Dict.update, key, function(oldValue) { + if (oldValue.ctor === 'Just') + { + return Maybe.Just(value + ', ' + oldValue._0); + } + return Maybe.Just(value); + }, headers); } } - return false; + return headers; } - function updateThunk(previous, domNode) + + function multipart(dataList) { - if (!shouldUpdate(this, previous)) - { - this.vnode = previous.vnode; - return; - } + var formData = new FormData(); - if (!this.vnode) + while (dataList.ctor !== '[]') { - this.vnode = this.thunk(); + var data = dataList._0; + if (data.ctor === 'StringData') + { + formData.append(data._0, data._1); + } + else + { + var fileName = data._1.ctor === 'Nothing' + ? undefined + : data._1._0; + formData.append(data._0, data._2, fileName); + } + dataList = dataList._1; } - var patches = diff(previous.vnode, this.vnode); - patch(domNode, patches); + return { ctor: 'BodyFormData', formData: formData }; } - function renderThunk() + + function uriEncode(string) { - return this.thunk(); + return encodeURIComponent(string); } - return Elm.Native.VirtualDom.values = { - node: node, - text: text, - on: F4(on), - - property: F2(property), - attribute: F2(attribute), - - lazy: F2(lazyRef), - lazy2: F3(lazyRef2), - lazy3: F4(lazyRef3), - - toElement: F3(toElement), - fromElement: fromElement, + function uriDecode(string) + { + return decodeURIComponent(string); + } - render: createElement, - updateAndReplace: updateAndReplace + return localRuntime.Native.Http.values = { + send: F2(send), + multipart: multipart, + uriEncode: uriEncode, + uriDecode: uriDecode }; -}; - -},{"virtual-dom/create-element":1,"virtual-dom/vdom/patch":9,"virtual-dom/vnode/is-vhook":13,"virtual-dom/vnode/vnode":18,"virtual-dom/vnode/vtext":20,"virtual-dom/vtree/diff":22}],24:[function(require,module,exports){ - -},{}]},{},[23]); - -Elm.Result = Elm.Result || {}; -Elm.Result.make = function (_elm) { - "use strict"; - _elm.Result = _elm.Result || {}; - if (_elm.Result.values) - return _elm.Result.values; - var _op = {}, - _N = Elm.Native, - _U = _N.Utils.make(_elm), - _L = _N.List.make(_elm), - $moduleName = "Result", - $Maybe = Elm.Maybe.make(_elm); - var toMaybe = function (result) { - return function () { - switch (result.ctor) - {case "Err": - return $Maybe.Nothing; - case "Ok": - return $Maybe.Just(result._0);} - _U.badCase($moduleName, - "between lines 164 and 166"); - }(); - }; - var Err = function (a) { - return {ctor: "Err",_0: a}; - }; - var andThen = F2(function (result, - callback) { - return function () { - switch (result.ctor) - {case "Err": - return Err(result._0); - case "Ok": - return callback(result._0);} - _U.badCase($moduleName, - "between lines 126 and 128"); - }(); - }); - var Ok = function (a) { - return {ctor: "Ok",_0: a}; - }; - var map = F2(function (func, - ra) { - return function () { - switch (ra.ctor) - {case "Err": return Err(ra._0); - case "Ok": - return Ok(func(ra._0));} - _U.badCase($moduleName, - "between lines 41 and 43"); - }(); - }); - var map2 = F3(function (func, - ra, - rb) { - return function () { - var _v9 = {ctor: "_Tuple2" - ,_0: ra - ,_1: rb}; - switch (_v9.ctor) - {case "_Tuple2": - switch (_v9._0.ctor) - {case "Err": - return Err(_v9._0._0); - case "Ok": switch (_v9._1.ctor) - {case "Ok": return Ok(A2(func, - _v9._0._0, - _v9._1._0));} - break;} - switch (_v9._1.ctor) - {case "Err": - return Err(_v9._1._0);} - break;} - _U.badCase($moduleName, - "between lines 55 and 58"); - }(); - }); - var map3 = F4(function (func, - ra, - rb, - rc) { - return function () { - var _v16 = {ctor: "_Tuple3" - ,_0: ra - ,_1: rb - ,_2: rc}; - switch (_v16.ctor) - {case "_Tuple3": - switch (_v16._0.ctor) - {case "Err": - return Err(_v16._0._0); - case "Ok": switch (_v16._1.ctor) - {case "Ok": - switch (_v16._2.ctor) - {case "Ok": return Ok(A3(func, - _v16._0._0, - _v16._1._0, - _v16._2._0));} - break;} - break;} - switch (_v16._1.ctor) - {case "Err": - return Err(_v16._1._0);} - switch (_v16._2.ctor) - {case "Err": - return Err(_v16._2._0);} - break;} - _U.badCase($moduleName, - "between lines 63 and 67"); - }(); - }); - var map4 = F5(function (func, - ra, - rb, - rc, - rd) { - return function () { - var _v26 = {ctor: "_Tuple4" - ,_0: ra - ,_1: rb - ,_2: rc - ,_3: rd}; - switch (_v26.ctor) - {case "_Tuple4": - switch (_v26._0.ctor) - {case "Err": - return Err(_v26._0._0); - case "Ok": switch (_v26._1.ctor) - {case "Ok": - switch (_v26._2.ctor) - {case "Ok": - switch (_v26._3.ctor) - {case "Ok": return Ok(A4(func, - _v26._0._0, - _v26._1._0, - _v26._2._0, - _v26._3._0));} - break;} - break;} - break;} - switch (_v26._1.ctor) - {case "Err": - return Err(_v26._1._0);} - switch (_v26._2.ctor) - {case "Err": - return Err(_v26._2._0);} - switch (_v26._3.ctor) - {case "Err": - return Err(_v26._3._0);} - break;} - _U.badCase($moduleName, - "between lines 72 and 77"); - }(); - }); - var map5 = F6(function (func, - ra, - rb, - rc, - rd, - re) { - return function () { - var _v39 = {ctor: "_Tuple5" - ,_0: ra - ,_1: rb - ,_2: rc - ,_3: rd - ,_4: re}; - switch (_v39.ctor) - {case "_Tuple5": - switch (_v39._0.ctor) - {case "Err": - return Err(_v39._0._0); - case "Ok": switch (_v39._1.ctor) - {case "Ok": - switch (_v39._2.ctor) - {case "Ok": - switch (_v39._3.ctor) - {case "Ok": - switch (_v39._4.ctor) - {case "Ok": return Ok(A5(func, - _v39._0._0, - _v39._1._0, - _v39._2._0, - _v39._3._0, - _v39._4._0));} - break;} - break;} - break;} - break;} - switch (_v39._1.ctor) - {case "Err": - return Err(_v39._1._0);} - switch (_v39._2.ctor) - {case "Err": - return Err(_v39._2._0);} - switch (_v39._3.ctor) - {case "Err": - return Err(_v39._3._0);} - switch (_v39._4.ctor) - {case "Err": - return Err(_v39._4._0);} - break;} - _U.badCase($moduleName, - "between lines 82 and 88"); - }(); - }); - var formatError = F2(function (f, - result) { - return function () { - switch (result.ctor) - {case "Err": - return Err(f(result._0)); - case "Ok": - return Ok(result._0);} - _U.badCase($moduleName, - "between lines 148 and 150"); - }(); - }); - var fromMaybe = F2(function (err, - maybe) { - return function () { - switch (maybe.ctor) - {case "Just": - return Ok(maybe._0); - case "Nothing": - return Err(err);} - _U.badCase($moduleName, - "between lines 180 and 182"); - }(); - }); - _elm.Result.values = {_op: _op - ,map: map - ,map2: map2 - ,map3: map3 - ,map4: map4 - ,map5: map5 - ,andThen: andThen - ,toMaybe: toMaybe - ,fromMaybe: fromMaybe - ,formatError: formatError - ,Ok: Ok - ,Err: Err}; - return _elm.Result.values; -}; -Elm.Signal = Elm.Signal || {}; -Elm.Signal.make = function (_elm) { - "use strict"; - _elm.Signal = _elm.Signal || {}; - if (_elm.Signal.values) - return _elm.Signal.values; - var _op = {}, - _N = Elm.Native, - _U = _N.Utils.make(_elm), - _L = _N.List.make(_elm), - $moduleName = "Signal", - $Basics = Elm.Basics.make(_elm), - $Debug = Elm.Debug.make(_elm), - $List = Elm.List.make(_elm), - $Maybe = Elm.Maybe.make(_elm), - $Native$Signal = Elm.Native.Signal.make(_elm), - $Task = Elm.Task.make(_elm); - var send = F2(function (_v0, - value) { - return function () { - switch (_v0.ctor) - {case "Address": - return A2($Task.onError, - _v0._0(value), - function (_v3) { - return function () { - return $Task.succeed({ctor: "_Tuple0"}); - }(); - });} - _U.badCase($moduleName, - "between lines 370 and 371"); - }(); - }); - var Message = function (a) { - return {ctor: "Message" - ,_0: a}; - }; - var message = F2(function (_v5, - value) { - return function () { - switch (_v5.ctor) - {case "Address": - return Message(_v5._0(value));} - _U.badCase($moduleName, - "on line 352, column 5 to 24"); - }(); - }); - var mailbox = $Native$Signal.mailbox; - var Address = function (a) { - return {ctor: "Address" - ,_0: a}; - }; - var forwardTo = F2(function (_v8, - f) { - return function () { - switch (_v8.ctor) - {case "Address": - return Address(function (x) { - return _v8._0(f(x)); - });} - _U.badCase($moduleName, - "on line 339, column 5 to 29"); - }(); - }); - var Mailbox = F2(function (a, - b) { - return {_: {} - ,address: a - ,signal: b}; - }); - var sampleOn = $Native$Signal.sampleOn; - var dropRepeats = $Native$Signal.dropRepeats; - var filterMap = $Native$Signal.filterMap; - var filter = F3(function (isOk, - base, - signal) { - return A3(filterMap, - function (value) { - return isOk(value) ? $Maybe.Just(value) : $Maybe.Nothing; - }, - base, - signal); - }); - var merge = F2(function (left, - right) { - return A3($Native$Signal.genericMerge, - $Basics.always, - left, - right); - }); - var mergeMany = function (signalList) { - return function () { - var _v11 = $List.reverse(signalList); - switch (_v11.ctor) - {case "::": - return A3($List.foldl, - merge, - _v11._0, - _v11._1); - case "[]": - return $Debug.crash("mergeMany was given an empty list!");} - _U.badCase($moduleName, - "between lines 177 and 182"); - }(); - }; - var foldp = $Native$Signal.foldp; - var map5 = $Native$Signal.map5; - var map4 = $Native$Signal.map4; - var map3 = $Native$Signal.map3; - var map2 = $Native$Signal.map2; - _op["~"] = F2(function (funcs, - args) { - return A3(map2, - F2(function (f,v) { - return f(v); - }), - funcs, - args); - }); - var map = $Native$Signal.map; - _op["<~"] = map; - var constant = $Native$Signal.constant; - var Signal = {ctor: "Signal"}; - _elm.Signal.values = {_op: _op - ,merge: merge - ,mergeMany: mergeMany - ,map: map - ,map2: map2 - ,map3: map3 - ,map4: map4 - ,map5: map5 - ,constant: constant - ,dropRepeats: dropRepeats - ,filter: filter - ,filterMap: filterMap - ,sampleOn: sampleOn - ,foldp: foldp - ,mailbox: mailbox - ,send: send - ,message: message - ,forwardTo: forwardTo - ,Mailbox: Mailbox}; - return _elm.Signal.values; -}; -Elm.StartApp = Elm.StartApp || {}; -Elm.StartApp.make = function (_elm) { - "use strict"; - _elm.StartApp = _elm.StartApp || {}; - if (_elm.StartApp.values) - return _elm.StartApp.values; - var _op = {}, - _N = Elm.Native, - _U = _N.Utils.make(_elm), - _L = _N.List.make(_elm), - $moduleName = "StartApp", - $Basics = Elm.Basics.make(_elm), - $Effects = Elm.Effects.make(_elm), - $Html = Elm.Html.make(_elm), - $List = Elm.List.make(_elm), - $Maybe = Elm.Maybe.make(_elm), - $Result = Elm.Result.make(_elm), - $Signal = Elm.Signal.make(_elm), - $Task = Elm.Task.make(_elm); - var start = function (config) { - return function () { - var updateStep = F2(function (action, - _v0) { - return function () { - switch (_v0.ctor) - {case "_Tuple2": - return function () { - var $ = A2(config.update, - action, - _v0._0), - newModel = $._0, - additionalEffects = $._1; - return {ctor: "_Tuple2" - ,_0: newModel - ,_1: $Effects.batch(_L.fromArray([_v0._1 - ,additionalEffects]))}; - }();} - _U.badCase($moduleName, - "between lines 94 and 97"); - }(); - }); - var update = F2(function (actions, - _v4) { - return function () { - switch (_v4.ctor) - {case "_Tuple2": - return A3($List.foldl, - updateStep, - {ctor: "_Tuple2" - ,_0: _v4._0 - ,_1: $Effects.none}, - actions);} - _U.badCase($moduleName, - "on line 101, column 13 to 64"); - }(); - }); - var messages = $Signal.mailbox(_L.fromArray([])); - var singleton = function (action) { - return _L.fromArray([action]); - }; - var address = A2($Signal.forwardTo, - messages.address, - singleton); - var inputs = $Signal.mergeMany(A2($List._op["::"], - messages.signal, - A2($List.map, - $Signal.map(singleton), - config.inputs))); - var effectsAndModel = A3($Signal.foldp, - update, - config.init, - inputs); - var model = A2($Signal.map, - $Basics.fst, - effectsAndModel); - return {_: {} - ,html: A2($Signal.map, - config.view(address), - model) - ,model: model - ,tasks: A2($Signal.map, - function ($) { - return $Effects.toTask(messages.address)($Basics.snd($)); - }, - effectsAndModel)}; - }(); - }; - var App = F3(function (a,b,c) { - return {_: {} - ,html: a - ,model: b - ,tasks: c}; - }); - var Config = F4(function (a, - b, - c, - d) { - return {_: {} - ,init: a - ,inputs: d - ,update: b - ,view: c}; - }); - _elm.StartApp.values = {_op: _op - ,start: start - ,Config: Config - ,App: App}; - return _elm.StartApp.values; -}; -Elm.String = Elm.String || {}; -Elm.String.make = function (_elm) { - "use strict"; - _elm.String = _elm.String || {}; - if (_elm.String.values) - return _elm.String.values; - var _op = {}, - _N = Elm.Native, - _U = _N.Utils.make(_elm), - _L = _N.List.make(_elm), - $moduleName = "String", - $Maybe = Elm.Maybe.make(_elm), - $Native$String = Elm.Native.String.make(_elm), - $Result = Elm.Result.make(_elm); - var fromList = $Native$String.fromList; - var toList = $Native$String.toList; - var toFloat = $Native$String.toFloat; - var toInt = $Native$String.toInt; - var indices = $Native$String.indexes; - var indexes = $Native$String.indexes; - var endsWith = $Native$String.endsWith; - var startsWith = $Native$String.startsWith; - var contains = $Native$String.contains; - var all = $Native$String.all; - var any = $Native$String.any; - var toLower = $Native$String.toLower; - var toUpper = $Native$String.toUpper; - var lines = $Native$String.lines; - var words = $Native$String.words; - var trimRight = $Native$String.trimRight; - var trimLeft = $Native$String.trimLeft; - var trim = $Native$String.trim; - var padRight = $Native$String.padRight; - var padLeft = $Native$String.padLeft; - var pad = $Native$String.pad; - var dropRight = $Native$String.dropRight; - var dropLeft = $Native$String.dropLeft; - var right = $Native$String.right; - var left = $Native$String.left; - var slice = $Native$String.slice; - var repeat = $Native$String.repeat; - var join = $Native$String.join; - var split = $Native$String.split; - var foldr = $Native$String.foldr; - var foldl = $Native$String.foldl; - var reverse = $Native$String.reverse; - var filter = $Native$String.filter; - var map = $Native$String.map; - var length = $Native$String.length; - var concat = $Native$String.concat; - var append = $Native$String.append; - var uncons = $Native$String.uncons; - var cons = $Native$String.cons; - var fromChar = function ($char) { - return A2(cons,$char,""); - }; - var isEmpty = $Native$String.isEmpty; - _elm.String.values = {_op: _op - ,isEmpty: isEmpty - ,length: length - ,reverse: reverse - ,repeat: repeat - ,cons: cons - ,uncons: uncons - ,fromChar: fromChar - ,append: append - ,concat: concat - ,split: split - ,join: join - ,words: words - ,lines: lines - ,slice: slice - ,left: left - ,right: right - ,dropLeft: dropLeft - ,dropRight: dropRight - ,contains: contains - ,startsWith: startsWith - ,endsWith: endsWith - ,indexes: indexes - ,indices: indices - ,toInt: toInt - ,toFloat: toFloat - ,toList: toList - ,fromList: fromList - ,toUpper: toUpper - ,toLower: toLower - ,pad: pad - ,padLeft: padLeft - ,padRight: padRight - ,trim: trim - ,trimLeft: trimLeft - ,trimRight: trimRight - ,map: map - ,filter: filter - ,foldl: foldl - ,foldr: foldr - ,any: any - ,all: all}; - return _elm.String.values; -}; -Elm.Task = Elm.Task || {}; -Elm.Task.make = function (_elm) { +}; + +Elm.Http = Elm.Http || {}; +Elm.Http.make = function (_elm) { "use strict"; - _elm.Task = _elm.Task || {}; - if (_elm.Task.values) - return _elm.Task.values; - var _op = {}, - _N = Elm.Native, - _U = _N.Utils.make(_elm), - _L = _N.List.make(_elm), - $moduleName = "Task", + _elm.Http = _elm.Http || {}; + if (_elm.Http.values) return _elm.Http.values; + var _U = Elm.Native.Utils.make(_elm), + $Basics = Elm.Basics.make(_elm), + $Debug = Elm.Debug.make(_elm), + $Dict = Elm.Dict.make(_elm), + $Json$Decode = Elm.Json.Decode.make(_elm), $List = Elm.List.make(_elm), $Maybe = Elm.Maybe.make(_elm), - $Native$Task = Elm.Native.Task.make(_elm), - $Result = Elm.Result.make(_elm); - var sleep = $Native$Task.sleep; - var spawn = $Native$Task.spawn; - var ThreadID = function (a) { - return {ctor: "ThreadID" - ,_0: a}; - }; - var onError = $Native$Task.catch_; - var andThen = $Native$Task.andThen; - var fail = $Native$Task.fail; - var mapError = F2(function (f, - promise) { - return A2(onError, - promise, - function (err) { - return fail(f(err)); - }); - }); - var succeed = $Native$Task.succeed; - var map = F2(function (func, - promiseA) { - return A2(andThen, - promiseA, - function (a) { - return succeed(func(a)); - }); - }); - var map2 = F3(function (func, - promiseA, - promiseB) { - return A2(andThen, - promiseA, - function (a) { - return A2(andThen, - promiseB, - function (b) { - return succeed(A2(func,a,b)); - }); - }); - }); - var map3 = F4(function (func, - promiseA, - promiseB, - promiseC) { - return A2(andThen, - promiseA, - function (a) { - return A2(andThen, - promiseB, - function (b) { - return A2(andThen, - promiseC, - function (c) { - return succeed(A3(func, - a, - b, - c)); - }); - }); - }); - }); - var map4 = F5(function (func, - promiseA, - promiseB, - promiseC, - promiseD) { - return A2(andThen, - promiseA, - function (a) { - return A2(andThen, - promiseB, - function (b) { - return A2(andThen, - promiseC, - function (c) { - return A2(andThen, - promiseD, - function (d) { - return succeed(A4(func, - a, - b, - c, - d)); - }); - }); - }); - }); - }); - var map5 = F6(function (func, - promiseA, - promiseB, - promiseC, - promiseD, - promiseE) { - return A2(andThen, - promiseA, - function (a) { - return A2(andThen, - promiseB, - function (b) { - return A2(andThen, - promiseC, - function (c) { - return A2(andThen, - promiseD, - function (d) { - return A2(andThen, - promiseE, - function (e) { - return succeed(A5(func, - a, - b, - c, - d, - e)); - }); - }); - }); - }); - }); + $Native$Http = Elm.Native.Http.make(_elm), + $Result = Elm.Result.make(_elm), + $Signal = Elm.Signal.make(_elm), + $String = Elm.String.make(_elm), + $Task = Elm.Task.make(_elm), + $Time = Elm.Time.make(_elm); + var _op = {}; + var sendWithAbort = $Native$Http.send; + var send = F2(function (settings,request) { return $Basics.fst(A2(sendWithAbort,settings,request));}); + var BadResponse = F2(function (a,b) { return {ctor: "BadResponse",_0: a,_1: b};}); + var UnexpectedPayload = function (a) { return {ctor: "UnexpectedPayload",_0: a};}; + var handleResponse = F2(function (handle,response) { + if (_U.cmp(200,response.status) < 1 && _U.cmp(response.status,300) < 0) { + var _p0 = response.value; + if (_p0.ctor === "Text") { + return handle(_p0._0); + } else { + return $Task.fail(UnexpectedPayload("Response body is a blob, expecting a string.")); + } + } else return $Task.fail(A2(BadResponse,response.status,response.statusText)); }); - var andMap = F2(function (promiseFunc, - promiseValue) { - return A2(andThen, - promiseFunc, - function (func) { - return A2(andThen, - promiseValue, - function (value) { - return succeed(func(value)); - }); - }); + var NetworkError = {ctor: "NetworkError"}; + var Timeout = {ctor: "Timeout"}; + var promoteError = function (rawError) { var _p1 = rawError;if (_p1.ctor === "RawTimeout") { return Timeout;} else { return NetworkError;}}; + var fromJson = F2(function (decoder,response) { + var decode = function (str) { + var _p2 = A2($Json$Decode.decodeString,decoder,str); + if (_p2.ctor === "Ok") { + return $Task.succeed(_p2._0); + } else { + return $Task.fail(UnexpectedPayload(_p2._0)); + } + }; + return A2($Task.andThen,A2($Task.mapError,promoteError,response),handleResponse(decode)); }); - var sequence = function (promises) { - return function () { - switch (promises.ctor) - {case "::": return A3(map2, - F2(function (x,y) { - return A2($List._op["::"], - x, - y); - }), - promises._0, - sequence(promises._1)); - case "[]": - return succeed(_L.fromArray([]));} - _U.badCase($moduleName, - "between lines 101 and 106"); - }(); - }; - var toMaybe = function (task) { - return A2(onError, - A2(map,$Maybe.Just,task), - function (_v3) { - return function () { - return succeed($Maybe.Nothing); - }(); - }); - }; - var fromMaybe = F2(function ($default, - maybe) { - return function () { - switch (maybe.ctor) - {case "Just": - return succeed(maybe._0); - case "Nothing": - return fail($default);} - _U.badCase($moduleName, - "between lines 139 and 141"); - }(); + var RawNetworkError = {ctor: "RawNetworkError"}; + var RawTimeout = {ctor: "RawTimeout"}; + var Blob = function (a) { return {ctor: "Blob",_0: a};}; + var Text = function (a) { return {ctor: "Text",_0: a};}; + var Response = F5(function (a,b,c,d,e) { return {status: a,statusText: b,headers: c,url: d,value: e};}); + var defaultSettings = {timeout: 0,onStart: $Maybe.Nothing,onProgress: $Maybe.Nothing,desiredResponseType: $Maybe.Nothing,withCredentials: false}; + var post = F3(function (decoder,url,body) { + var request = {verb: "POST",headers: _U.list([]),url: url,body: body}; + return A2(fromJson,decoder,A2(send,defaultSettings,request)); + }); + var Settings = F5(function (a,b,c,d,e) { return {timeout: a,onStart: b,onProgress: c,desiredResponseType: d,withCredentials: e};}); + var multipart = $Native$Http.multipart; + var FileData = F3(function (a,b,c) { return {ctor: "FileData",_0: a,_1: b,_2: c};}); + var BlobData = F3(function (a,b,c) { return {ctor: "BlobData",_0: a,_1: b,_2: c};}); + var blobData = BlobData; + var StringData = F2(function (a,b) { return {ctor: "StringData",_0: a,_1: b};}); + var stringData = StringData; + var BodyBlob = function (a) { return {ctor: "BodyBlob",_0: a};}; + var BodyFormData = {ctor: "BodyFormData"}; + var ArrayBuffer = {ctor: "ArrayBuffer"}; + var BodyString = function (a) { return {ctor: "BodyString",_0: a};}; + var string = BodyString; + var Empty = {ctor: "Empty"}; + var empty = Empty; + var getString = function (url) { + var request = {verb: "GET",headers: _U.list([]),url: url,body: empty}; + return A2($Task.andThen,A2($Task.mapError,promoteError,A2(send,defaultSettings,request)),handleResponse($Task.succeed)); + }; + var getWithAbort = F2(function (decoder,url) { + var request = {verb: "GET",headers: _U.list([]),url: url,body: empty}; + var _p3 = A2(sendWithAbort,defaultSettings,request); + var sendTask = _p3._0; + var abortTask = _p3._1; + return {ctor: "_Tuple2",_0: A2(fromJson,decoder,sendTask),_1: abortTask}; + }); + var get = F2(function (decoder,url) { return $Basics.fst(A2(getWithAbort,decoder,url));}); + var Request = F4(function (a,b,c,d) { return {verb: a,headers: b,url: c,body: d};}); + var uriDecode = $Native$Http.uriDecode; + var uriEncode = $Native$Http.uriEncode; + var queryEscape = function (string) { return A2($String.join,"+",A2($String.split,"%20",uriEncode(string)));}; + var queryPair = function (_p4) { var _p5 = _p4;return A2($Basics._op["++"],queryEscape(_p5._0),A2($Basics._op["++"],"=",queryEscape(_p5._1)));}; + var url = F2(function (baseUrl,args) { + var _p6 = args; + if (_p6.ctor === "[]") { + return baseUrl; + } else { + return A2($Basics._op["++"],baseUrl,A2($Basics._op["++"],"?",A2($String.join,"&",A2($List.map,queryPair,args)))); + } }); - var toResult = function (task) { - return A2(onError, - A2(map,$Result.Ok,task), - function (msg) { - return succeed($Result.Err(msg)); - }); - }; - var fromResult = function (result) { - return function () { - switch (result.ctor) - {case "Err": - return fail(result._0); - case "Ok": - return succeed(result._0);} - _U.badCase($moduleName, - "between lines 151 and 153"); - }(); - }; - var Task = {ctor: "Task"}; - _elm.Task.values = {_op: _op - ,succeed: succeed - ,fail: fail - ,map: map - ,map2: map2 - ,map3: map3 - ,map4: map4 - ,map5: map5 - ,andMap: andMap - ,sequence: sequence - ,andThen: andThen - ,onError: onError - ,mapError: mapError - ,toMaybe: toMaybe - ,fromMaybe: fromMaybe - ,toResult: toResult - ,fromResult: fromResult - ,spawn: spawn - ,sleep: sleep}; - return _elm.Task.values; + var TODO_implement_file_in_another_library = {ctor: "TODO_implement_file_in_another_library"}; + var TODO_implement_blob_in_another_library = {ctor: "TODO_implement_blob_in_another_library"}; + return _elm.Http.values = {_op: _op + ,getString: getString + ,get: get + ,post: post + ,send: send + ,getWithAbort: getWithAbort + ,sendWithAbort: sendWithAbort + ,url: url + ,uriEncode: uriEncode + ,uriDecode: uriDecode + ,empty: empty + ,string: string + ,multipart: multipart + ,stringData: stringData + ,defaultSettings: defaultSettings + ,fromJson: fromJson + ,Request: Request + ,Settings: Settings + ,Response: Response + ,Text: Text + ,Blob: Blob + ,Timeout: Timeout + ,NetworkError: NetworkError + ,UnexpectedPayload: UnexpectedPayload + ,BadResponse: BadResponse + ,RawTimeout: RawTimeout + ,RawNetworkError: RawNetworkError}; }; -Elm.Text = Elm.Text || {}; -Elm.Text.make = function (_elm) { +Elm.Main = Elm.Main || {}; +Elm.Main.make = function (_elm) { "use strict"; - _elm.Text = _elm.Text || {}; - if (_elm.Text.values) - return _elm.Text.values; - var _op = {}, - _N = Elm.Native, - _U = _N.Utils.make(_elm), - _L = _N.List.make(_elm), - $moduleName = "Text", - $Color = Elm.Color.make(_elm), + _elm.Main = _elm.Main || {}; + if (_elm.Main.values) return _elm.Main.values; + var _U = Elm.Native.Utils.make(_elm), + $Array = Elm.Array.make(_elm), + $Basics = Elm.Basics.make(_elm), + $Debug = Elm.Debug.make(_elm), + $Effects = Elm.Effects.make(_elm), + $Html = Elm.Html.make(_elm), + $Html$Attributes = Elm.Html.Attributes.make(_elm), + $Html$Events = Elm.Html.Events.make(_elm), + $Http = Elm.Http.make(_elm), + $Json$Decode = Elm.Json.Decode.make(_elm), $List = Elm.List.make(_elm), $Maybe = Elm.Maybe.make(_elm), - $Native$Text = Elm.Native.Text.make(_elm); - var line = $Native$Text.line; - var italic = $Native$Text.italic; - var bold = $Native$Text.bold; - var color = $Native$Text.color; - var height = $Native$Text.height; - var link = $Native$Text.link; - var monospace = $Native$Text.monospace; - var typeface = $Native$Text.typeface; - var style = $Native$Text.style; - var append = $Native$Text.append; - var fromString = $Native$Text.fromString; - var empty = fromString(""); - var concat = function (texts) { - return A3($List.foldr, - append, - empty, - texts); + $Result = Elm.Result.make(_elm), + $Signal = Elm.Signal.make(_elm), + $StartApp = Elm.StartApp.make(_elm), + $Task = Elm.Task.make(_elm); + var _op = {}; + var aLast = function (arr) { return A2($Array.get,$Array.length(arr) - 1,arr);}; + var aFirst = $Array.get(0); + _op[">>="] = F2(function (_p0,f) { + var _p1 = _p0; + var _p2 = f(_p1._0); + var model$ = _p2._0; + var effects$ = _p2._1; + return {ctor: "_Tuple2",_0: model$,_1: $Effects.batch(_U.list([_p1._1,effects$]))}; + }); + var bindAll = F2(function (modelEffects,fs) { return A3($List.foldl,$Basics.flip(F2(function (x,y) { return A2(_op[">>="],x,y);})),modelEffects,fs);}); + var pure = function (model) { return {ctor: "_Tuple2",_0: model,_1: $Effects.none};}; + var andThenAndThen = F2(function (mmValue,f) { return A2($Maybe.andThen,mmValue,A2($Basics.flip,$Maybe.andThen,f));}); + var mMap2 = F3(function (func,ma,mb) { + var _p3 = {ctor: "_Tuple2",_0: ma,_1: mb}; + if (_p3.ctor === "_Tuple2" && _p3._0.ctor === "Just" && _p3._1.ctor === "Just") { + return $Maybe.Just(A2(func,_p3._0._0,_p3._1._0)); + } else { + return $Maybe.Nothing; + } + }); + var any = F2(function (pred,array) { return _U.cmp($Array.length(A2($Array.filter,pred,array)),0) > 0;}); + var notNothing = function (maybe) { var _p4 = maybe;if (_p4.ctor === "Nothing") { return false;} else { return true;}}; + var isNothing = function (_p5) { return $Basics.not(notNothing(_p5));}; + var inBounds = F2(function (pos,slots) { return _U.cmp(pos,0) > -1 && _U.cmp(pos,$Array.length(slots)) < 0;}); + var viewPlanetMonitor = function (mWorld) { + return A2($Html.h1, + _U.list([$Html$Attributes.$class("css-planet-monitor")]), + _U.list([$Html.text(A2($Basics._op["++"], + "Obi-Wan currently ", + function () { + var _p6 = mWorld; + if (_p6.ctor === "Just") { + return A2($Basics._op["++"],"on ",_p6._0.name); + } else { + return "in transit"; + } + }()))])); }; - var join = F2(function (seperator, - texts) { - return concat(A2($List.intersperse, - seperator, - texts)); + var onWorld = F2(function (mJedi,mWorld) { + var _p7 = A3(mMap2,F2(function (v0,v1) { return {ctor: "_Tuple2",_0: v0,_1: v1};}),mWorld,mJedi); + if (_p7.ctor === "Just") { + return _U.eq(_p7._0._1.homeworld.id,_p7._0._0.id); + } else { + return false; + } }); - var defaultStyle = {_: {} - ,bold: false - ,color: $Color.black - ,height: $Maybe.Nothing - ,italic: false - ,line: $Maybe.Nothing - ,typeface: _L.fromArray([])}; - var Style = F6(function (a, - b, - c, - d, - e, - f) { - return {_: {} - ,bold: d - ,color: c - ,height: b - ,italic: e - ,line: f - ,typeface: a}; + var viewJedi = F2(function (mWorld,mJedi) { + return A2($Html.li, + _U.list([$Html$Attributes.$class("css-slot") + ,$Html$Attributes.style(A2(onWorld,mJedi,mWorld) ? _U.list([{ctor: "_Tuple2",_0: "color",_1: "red"}]) : _U.list([]))]), + function () { + var _p8 = mJedi; + if (_p8.ctor === "Nothing") { + return _U.list([]); + } else { + var _p9 = _p8._0; + return _U.list([A2($Html.h3,_U.list([]),_U.list([$Html.text(_p9.name)])),A2($Html.h6,_U.list([]),_U.list([$Html.text(_p9.homeworld.name)]))]); + } + }()); }); - var Through = {ctor: "Through"}; - var Over = {ctor: "Over"}; - var Under = {ctor: "Under"}; - var Text = {ctor: "Text"}; - _elm.Text.values = {_op: _op - ,fromString: fromString - ,empty: empty - ,append: append - ,concat: concat - ,join: join - ,link: link - ,style: style - ,defaultStyle: defaultStyle - ,typeface: typeface - ,monospace: monospace - ,height: height - ,color: color - ,bold: bold - ,italic: italic - ,line: line - ,Style: Style - ,Under: Under - ,Over: Over - ,Through: Through}; - return _elm.Text.values; -}; -Elm.Time = Elm.Time || {}; -Elm.Time.make = function (_elm) { - "use strict"; - _elm.Time = _elm.Time || {}; - if (_elm.Time.values) - return _elm.Time.values; - var _op = {}, - _N = Elm.Native, - _U = _N.Utils.make(_elm), - _L = _N.List.make(_elm), - $moduleName = "Time", - $Basics = Elm.Basics.make(_elm), - $Native$Signal = Elm.Native.Signal.make(_elm), - $Native$Time = Elm.Native.Time.make(_elm), - $Signal = Elm.Signal.make(_elm); - var delay = $Native$Signal.delay; - var since = F2(function (time, - signal) { - return function () { - var stop = A2($Signal.map, - $Basics.always(-1), - A2(delay,time,signal)); - var start = A2($Signal.map, - $Basics.always(1), - signal); - var delaydiff = A3($Signal.foldp, - F2(function (x,y) { - return x + y; - }), - 0, - A2($Signal.merge,start,stop)); - return A2($Signal.map, - F2(function (x,y) { - return !_U.eq(x,y); - })(0), - delaydiff); + var canScroll = F3(function (upOrDown,scrollSpeed,jediSlots) { + var _p10 = function () { + var _p11 = upOrDown; + if (_p11.ctor === "Up") { + return {ctor: "_Tuple4",_0: aFirst,_1: function (_) { return _.master;},_2: 0,_3: 0 - scrollSpeed}; + } else { + return {ctor: "_Tuple4",_0: aLast,_1: function (_) { return _.apprentice;},_2: scrollSpeed,_3: $Array.length(jediSlots)}; + } }(); - }); - var timestamp = $Native$Signal.timestamp; - var every = $Native$Time.every; - var fpsWhen = $Native$Time.fpsWhen; - var fps = function (targetFrames) { - return A2(fpsWhen, - targetFrames, - $Signal.constant(true)); - }; - var inMilliseconds = function (t) { - return t; - }; - var millisecond = 1; - var second = 1000 * millisecond; - var minute = 60 * second; - var hour = 60 * minute; - var inHours = function (t) { - return t / hour; - }; - var inMinutes = function (t) { - return t / minute; + var getFirstOrLast = _p10._0; + var apprenticeOrMaster = _p10._1; + var scrollStart = _p10._2; + var scrollEnd = _p10._3; + var jediInView = A2(any,notNothing,A3($Array.slice,scrollStart,scrollEnd,jediSlots)); + var loadedJedis = A2($Array.filter,notNothing,jediSlots); + var next = A2(andThenAndThen,getFirstOrLast(loadedJedis),apprenticeOrMaster); + return notNothing(next) && jediInView; + }); + var haveJediAt = F2(function (pos,_p12) { var _p13 = _p12;return !_U.eq(A2($Array.get,pos,_p13.jediSlots),$Maybe.Just($Maybe.Nothing));}); + var needJediAt = F2(function (pos,model) { return A2(inBounds,pos,model.jediSlots) && $Basics.not(A2(haveJediAt,pos,model));}); + var removeRequest = F2(function (request,requests) { return A2($List.filter,function (r) { return !_U.eq(r.id,request.id);},requests);}); + var adjustPos = F3(function (pos,oldScrollPos,newScrollPos) { var offset = oldScrollPos - newScrollPos;return pos + offset;}); + var abortAndSaveAllRequests = function (model) { + return {ctor: "_Tuple2" + ,_0: _U.update(model,{jediRequests: _U.list([]),requestsToResume: A2($List.append,model.requestsToResume,model.jediRequests)}) + ,_1: $Effects.batch(A2($List.map,function (_) { return _.abort;},model.jediRequests))}; }; - var inSeconds = function (t) { - return t / second; + var abortRequests = function (model) { + var _p14 = A2($List.partition, + function (request) { + return A2(inBounds,A3(adjustPos,request.insertPos,request.scrollPos,model.scrollPos),model.jediSlots); + }, + model.jediRequests); + var newRequests = _p14._0; + var requestsToAbort = _p14._1; + var aborts = A2($List.map,function (_) { return _.abort;},requestsToAbort); + return {ctor: "_Tuple2",_0: _U.update(model,{jediRequests: newRequests}),_1: $Effects.batch(aborts)}; }; - _elm.Time.values = {_op: _op - ,millisecond: millisecond - ,second: second - ,minute: minute - ,hour: hour - ,inMilliseconds: inMilliseconds - ,inSeconds: inSeconds - ,inMinutes: inMinutes - ,inHours: inHours - ,fps: fps - ,fpsWhen: fpsWhen - ,every: every - ,timestamp: timestamp - ,delay: delay - ,since: since}; - return _elm.Time.values; -}; -Elm.Transform2D = Elm.Transform2D || {}; -Elm.Transform2D.make = function (_elm) { - "use strict"; - _elm.Transform2D = _elm.Transform2D || {}; - if (_elm.Transform2D.values) - return _elm.Transform2D.values; - var _op = {}, - _N = Elm.Native, - _U = _N.Utils.make(_elm), - _L = _N.List.make(_elm), - $moduleName = "Transform2D", - $Native$Transform2D = Elm.Native.Transform2D.make(_elm); - var multiply = $Native$Transform2D.multiply; - var rotation = $Native$Transform2D.rotation; - var matrix = $Native$Transform2D.matrix; - var translation = F2(function (x, - y) { - return A6(matrix, - 1, - 0, - 0, - 1, - x, - y); + var NoAction = {ctor: "NoAction"}; + var Scroll = F2(function (a,b) { return {ctor: "Scroll",_0: a,_1: b};}); + var viewScrollButton = F5(function (address,scrollDisabled,jediSlots,scrollSpeed,dir) { + var clickHandler = A2($Html$Events.onClick,address,A2(Scroll,dir,scrollSpeed)); + var enabled = $Basics.not(scrollDisabled) && A3(canScroll,dir,scrollSpeed,jediSlots); + var className = function () { var _p15 = dir;if (_p15.ctor === "Up") { return "css-button-up";} else { return "css-button-down";}}(); + var classes = $Html$Attributes.classList(_U.list([{ctor: "_Tuple2",_0: className,_1: true} + ,{ctor: "_Tuple2",_0: "css-button-disabled",_1: $Basics.not(enabled)}])); + return A2($Html.button,enabled ? _U.list([classes,clickHandler]) : _U.list([classes]),_U.list([])); + }); + var SetJedi = F2(function (a,b) { return {ctor: "SetJedi",_0: a,_1: b};}); + var SetWorld = function (a) { return {ctor: "SetWorld",_0: a};}; + var initModel = F2(function (nbSlots,scrollSpeed) { + return {world: $Maybe.Nothing + ,jediSlots: A2($Array.repeat,nbSlots,$Maybe.Nothing) + ,scrollPos: 0 + ,scrollSpeed: scrollSpeed + ,jediRequests: _U.list([]) + ,requestsToResume: _U.list([]) + ,nextRequestId: 0}; }); - var scale = function (s) { - return A6(matrix, - s, - 0, - 0, - s, - 0, - 0); - }; - var scaleX = function (x) { - return A6(matrix, - x, - 0, - 0, - 1, - 0, - 0); - }; - var scaleY = function (y) { - return A6(matrix, - 1, - 0, - 0, - y, - 0, - 0); - }; - var identity = $Native$Transform2D.identity; - var Transform2D = {ctor: "Transform2D"}; - _elm.Transform2D.values = {_op: _op - ,identity: identity - ,matrix: matrix - ,multiply: multiply - ,rotation: rotation - ,translation: translation - ,scale: scale - ,scaleX: scaleX - ,scaleY: scaleY}; - return _elm.Transform2D.values; -}; -Elm.VirtualDom = Elm.VirtualDom || {}; -Elm.VirtualDom.make = function (_elm) { - "use strict"; - _elm.VirtualDom = _elm.VirtualDom || {}; - if (_elm.VirtualDom.values) - return _elm.VirtualDom.values; - var _op = {}, - _N = Elm.Native, - _U = _N.Utils.make(_elm), - _L = _N.List.make(_elm), - $moduleName = "VirtualDom", - $Basics = Elm.Basics.make(_elm), - $Graphics$Element = Elm.Graphics.Element.make(_elm), - $Json$Decode = Elm.Json.Decode.make(_elm), - $List = Elm.List.make(_elm), - $Maybe = Elm.Maybe.make(_elm), - $Native$VirtualDom = Elm.Native.VirtualDom.make(_elm), - $Result = Elm.Result.make(_elm), - $Signal = Elm.Signal.make(_elm); - var lazy3 = $Native$VirtualDom.lazy3; - var lazy2 = $Native$VirtualDom.lazy2; - var lazy = $Native$VirtualDom.lazy; - var defaultOptions = {_: {} - ,preventDefault: false - ,stopPropagation: false}; - var Options = F2(function (a, - b) { - return {_: {} - ,preventDefault: b - ,stopPropagation: a}; + var mkJediUrl = function (id) { return {id: id,url: A2($Basics._op["++"],"http://localhost:3000/dark-jedis/",$Basics.toString(id))};}; + var darthSidious = mkJediUrl(3616); + var Down = {ctor: "Down"}; + var Up = {ctor: "Up"}; + var viewScrollButtons = F2(function (address,model) { + var scrollDisabled = A2(any,A2($Basics.flip,onWorld,model.world),model.jediSlots); + return A2($Html.div, + _U.list([$Html$Attributes.$class("css-scroll-buttons")]), + A2($List.map,A4(viewScrollButton,address,scrollDisabled,model.jediSlots,model.scrollSpeed),_U.list([Up,Down]))); }); - var onWithOptions = $Native$VirtualDom.on; - var on = F3(function (eventName, - decoder, - toMessage) { - return A4($Native$VirtualDom.on, - eventName, - defaultOptions, - decoder, - toMessage); + var viewJediList = F2(function (address,model) { + return A2($Html.div, + _U.list([$Html$Attributes.$class("css-scrollable-list")]), + _U.list([A2($Html.ul,_U.list([$Html$Attributes.$class("css-slots")]),A2($List.map,viewJedi(model.world),$Array.toList(model.jediSlots))) + ,A2(viewScrollButtons,address,model)])); }); - var attribute = $Native$VirtualDom.attribute; - var property = $Native$VirtualDom.property; - var Property = {ctor: "Property"}; - var fromElement = $Native$VirtualDom.fromElement; - var toElement = $Native$VirtualDom.toElement; - var text = $Native$VirtualDom.text; - var node = $Native$VirtualDom.node; - var Node = {ctor: "Node"}; - _elm.VirtualDom.values = {_op: _op - ,text: text - ,node: node - ,toElement: toElement - ,fromElement: fromElement - ,property: property - ,attribute: attribute - ,on: on - ,onWithOptions: onWithOptions - ,defaultOptions: defaultOptions - ,lazy: lazy - ,lazy2: lazy2 - ,lazy3: lazy3 - ,Options: Options}; - return _elm.VirtualDom.values; + var view = F2(function (address,model) { + return A2($Html.div,_U.list([$Html$Attributes.$class("css-root")]),_U.list([viewPlanetMonitor(model.world),A2(viewJediList,address,model)])); + }); + var JediRequest = F5(function (a,b,c,d,e) { return {id: a,jediUrl: b,insertPos: c,scrollPos: d,abort: e};}); + var JediUrl = F2(function (a,b) { return {id: a,url: b};}); + var decodeJediUrl = A2($Json$Decode.andThen, + A2($Json$Decode._op[":="],"id",$Json$Decode.oneOf(_U.list([A2($Json$Decode.map,$Maybe.Just,$Json$Decode.$int),$Json$Decode.$null($Maybe.Nothing)]))), + function (mId) { + var _p16 = mId; + if (_p16.ctor === "Just") { + return A2($Json$Decode.object1, + function (url) { + return $Maybe.Just(A2(JediUrl,_p16._0,url)); + }, + A2($Json$Decode._op[":="],"url",$Json$Decode.string)); + } else { + return $Json$Decode.succeed($Maybe.Nothing); + } + }); + var Jedi = F5(function (a,b,c,d,e) { return {id: a,name: b,homeworld: c,master: d,apprentice: e};}); + var World = F2(function (a,b) { return {id: a,name: b};}); + var decodeWorld = A3($Json$Decode.object2,World,A2($Json$Decode._op[":="],"id",$Json$Decode.$int),A2($Json$Decode._op[":="],"name",$Json$Decode.string)); + var decodeJedi = A6($Json$Decode.object5, + Jedi, + A2($Json$Decode._op[":="],"id",$Json$Decode.$int), + A2($Json$Decode._op[":="],"name",$Json$Decode.string), + A2($Json$Decode._op[":="],"homeworld",decodeWorld), + A2($Json$Decode._op[":="],"master",decodeJediUrl), + A2($Json$Decode._op[":="],"apprentice",decodeJediUrl)); + var fetchJedi = F4(function (sleepMillis,insertPos,jediUrl,model) { + var _p17 = A2($Http.getWithAbort,decodeJedi,jediUrl.url); + var sendTask = _p17._0; + var abortTask = _p17._1; + var abortEffect = $Effects.task(A2($Task.map,function (_p18) { return NoAction;},$Task.toMaybe(abortTask))); + var request = {id: model.nextRequestId,jediUrl: jediUrl,insertPos: insertPos,scrollPos: model.scrollPos,abort: abortEffect}; + var sendEffect = $Effects.task(A2($Task.map, + SetJedi(request), + $Task.toResult(A2($Task.andThen,$Task.sleep(sleepMillis),function (_p19) { return sendTask;})))); + return {ctor: "_Tuple2" + ,_0: _U.update(model,{jediRequests: A2($List._op["::"],request,model.jediRequests),nextRequestId: model.nextRequestId + 1}) + ,_1: sendEffect}; + }); + var init = F3(function (nbSlots,scrollSpeed,jediUrl) { return A4(fetchJedi,0,nbSlots / 2 | 0,jediUrl,A2(initModel,nbSlots,scrollSpeed));}); + var retryRequest = F3(function (sleepMillis,request,model) { + var model$ = _U.update(model,{jediRequests: A2(removeRequest,request,model.jediRequests)}); + var newInsertPos = A3(adjustPos,request.insertPos,request.scrollPos,model$.scrollPos); + return A4(fetchJedi,sleepMillis,newInsertPos,request.jediUrl,model$); + }); + var resumeAllRequests = function (model) { + var model$ = _U.update(model,{requestsToResume: _U.list([])}); + return A2(bindAll,pure(model$),A2($List.map,retryRequest(0),model.requestsToResume)); + }; + var setWorld = F2(function (mWorld,model) { + var model$ = _U.update(model,{world: mWorld}); + return A2(any,A2($Basics.flip,onWorld,mWorld),model$.jediSlots) ? abortAndSaveAllRequests(model$) : resumeAllRequests(model$); + }); + var maybeFetchJedi = F4(function (pos,nextPos,getNextUrl,model) { + var mNext = A2(needJediAt,nextPos,model) ? A2(andThenAndThen,A2($Array.get,pos,model.jediSlots),getNextUrl) : $Maybe.Nothing; + var _p20 = mNext; + if (_p20.ctor === "Just") { + return A4(fetchJedi,0,nextPos,_p20._0,model); + } else { + return pure(model); + } + }); + var maybeFetchJedisAround = F2(function (pos,model) { + return A2(_op[">>="], + A2(_op[">>="],pure(model),A3(maybeFetchJedi,pos,pos - 1,function (_) { return _.master;})), + A3(maybeFetchJedi,pos,pos + 1,function (_) { return _.apprentice;})); + }); + var setJedi = F3(function (request,newJediResult,model) { + var maybeRetry = function () { + var _p21 = newJediResult; + if (_p21.ctor === "Err") { + return A2(retryRequest,1000,request); + } else { + return pure; + } + }(); + var adjustedPos = A3(adjustPos,request.insertPos,request.scrollPos,model.scrollPos); + var newMJedi = $Result.toMaybe(newJediResult); + var newJediSlots = A2(inBounds,adjustedPos,model.jediSlots) ? A3($Array.set,adjustedPos,newMJedi,model.jediSlots) : model.jediSlots; + var model$ = _U.update(model,{jediRequests: A2(removeRequest,request,model.jediRequests),jediSlots: newJediSlots}); + var maybeAbortAll = A2(onWorld,newMJedi,model.world) ? abortAndSaveAllRequests : pure; + return A2(_op[">>="],A2(_op[">>="],A2(maybeFetchJedisAround,adjustedPos,model$),maybeRetry),maybeAbortAll); + }); + var doScroll = F3(function (model,dir,scrollSpeed) { + if ($Basics.not(A3(canScroll,dir,scrollSpeed,model.jediSlots))) return pure(model); else { + var emptySlots = A2($Array.repeat,scrollSpeed,$Maybe.Nothing); + var slotsLength = $Array.length(model.jediSlots); + var _p22 = function () { + var _p23 = dir; + if (_p23.ctor === "Up") { + return {ctor: "_Tuple3" + ,_0: A2($Array.append,emptySlots,A3($Array.slice,0,slotsLength - scrollSpeed,model.jediSlots)) + ,_1: model.scrollPos - scrollSpeed + ,_2: scrollSpeed}; + } else { + return {ctor: "_Tuple3" + ,_0: A2($Array.append,A3($Array.slice,scrollSpeed,slotsLength,model.jediSlots),emptySlots) + ,_1: model.scrollPos + scrollSpeed + ,_2: slotsLength - scrollSpeed - 1}; + } + }(); + var newJedis = _p22._0; + var newScrollPos = _p22._1; + var endJediPos = _p22._2; + return A2(_op[">>="], + A2(_op[">>="],pure(_U.update(model,{jediSlots: newJedis,scrollPos: newScrollPos})),abortRequests), + maybeFetchJedisAround(endJediPos)); + } + }); + var update = F2(function (action,model) { + var _p24 = action; + switch (_p24.ctor) + {case "SetJedi": return A3(setJedi,_p24._0,_p24._1,model); + case "SetWorld": return A2(setWorld,_p24._0,model); + case "Scroll": return A3(doScroll,model,_p24._0,_p24._1); + default: return pure(model);} + }); + var Model = F7(function (a,b,c,d,e,f,g) { + return {world: a,jediSlots: b,scrollPos: c,scrollSpeed: d,jediRequests: e,requestsToResume: f,nextRequestId: g}; + }); + var currentWorld = Elm.Native.Port.make(_elm).inboundSignal("currentWorld", + "Maybe.Maybe Main.World", + function (v) { + return v === null ? Elm.Maybe.make(_elm).Nothing : Elm.Maybe.make(_elm).Just(typeof v === "object" && "id" in v && "name" in v ? {_: {} + ,id: typeof v.id === "number" && isFinite(v.id) && Math.floor(v.id) === v.id ? v.id : _U.badPort("an integer", + v.id) + ,name: typeof v.name === "string" || typeof v.name === "object" && v.name instanceof String ? v.name : _U.badPort("a string", + v.name)} : _U.badPort("an object with fields `id`, `name`", + v)); + }); + var app = $StartApp.start({init: A3(init,5,2,darthSidious),update: update,view: view,inputs: _U.list([A2($Signal.map,SetWorld,currentWorld)])}); + var main = app.html; + var tasks = Elm.Native.Task.make(_elm).performSignal("tasks",app.tasks); + return _elm.Main.values = {_op: _op + ,app: app + ,main: main + ,Model: Model + ,World: World + ,Jedi: Jedi + ,JediUrl: JediUrl + ,JediRequest: JediRequest + ,Up: Up + ,Down: Down + ,mkJediUrl: mkJediUrl + ,darthSidious: darthSidious + ,init: init + ,initModel: initModel + ,SetWorld: SetWorld + ,SetJedi: SetJedi + ,Scroll: Scroll + ,NoAction: NoAction + ,update: update + ,setWorld: setWorld + ,setJedi: setJedi + ,abortRequests: abortRequests + ,abortAndSaveAllRequests: abortAndSaveAllRequests + ,resumeAllRequests: resumeAllRequests + ,doScroll: doScroll + ,fetchJedi: fetchJedi + ,retryRequest: retryRequest + ,maybeFetchJedisAround: maybeFetchJedisAround + ,maybeFetchJedi: maybeFetchJedi + ,adjustPos: adjustPos + ,removeRequest: removeRequest + ,haveJediAt: haveJediAt + ,needJediAt: needJediAt + ,canScroll: canScroll + ,onWorld: onWorld + ,view: view + ,viewPlanetMonitor: viewPlanetMonitor + ,viewJediList: viewJediList + ,viewJedi: viewJedi + ,viewScrollButtons: viewScrollButtons + ,viewScrollButton: viewScrollButton + ,decodeJedi: decodeJedi + ,decodeWorld: decodeWorld + ,decodeJediUrl: decodeJediUrl + ,inBounds: inBounds + ,notNothing: notNothing + ,isNothing: isNothing + ,any: any + ,mMap2: mMap2 + ,andThenAndThen: andThenAndThen + ,pure: pure + ,bindAll: bindAll + ,aFirst: aFirst + ,aLast: aLast}; }; diff --git a/submissions/mattjbray/elm-package.json b/submissions/mattjbray/elm-package.json index b228875..1393713 100644 --- a/submissions/mattjbray/elm-package.json +++ b/submissions/mattjbray/elm-package.json @@ -1,7 +1,7 @@ { "version": "1.0.0", - "summary": "helpful summary of your project, less than 80 characters", - "repository": "https://github.com/USER/PROJECT.git", + "summary": "Database reader of Sith lords", + "repository": "https://github.com/staltz/flux-challenge.git", "license": "BSD3", "source-directories": [ "src", @@ -10,10 +10,10 @@ "exposed-modules": [], "native-modules": true, "dependencies": { - "elm-lang/core": "2.1.0 <= v < 3.0.0", + "elm-lang/core": "3.0.0 <= v < 4.0.0", "evancz/elm-effects": "2.0.0 <= v < 3.0.0", "evancz/elm-html": "4.0.1 <= v < 5.0.0", "evancz/start-app": "2.0.1 <= v < 3.0.0" }, - "elm-version": "0.15.1 <= v < 0.16.0" + "elm-version": "0.16.0 <= v < 0.17.0" } diff --git a/submissions/mattjbray/src/Main.elm b/submissions/mattjbray/src/Main.elm index eac7288..77d4bc7 100644 --- a/submissions/mattjbray/src/Main.elm +++ b/submissions/mattjbray/src/Main.elm @@ -174,7 +174,7 @@ jedi requests. -} setWorld : Maybe World -> Model -> (Model, Effects Action) setWorld mWorld model = - let model' = { model | world <- mWorld } + let model' = { model | world = mWorld } in if any (flip onWorld mWorld) model'.jediSlots then abortAndSaveAllRequests model' @@ -201,8 +201,8 @@ setJedi request newJediResult model = -- Don't update the model if this jedi has been scrolled off-screen. else model.jediSlots - model' = { model | jediRequests <- removeRequest request model.jediRequests - , jediSlots <- newJediSlots } + model' = { model | jediRequests = removeRequest request model.jediRequests + , jediSlots = newJediSlots } maybeRetry = case newJediResult of @@ -237,7 +237,7 @@ abortRequests model = model.jediRequests aborts = List.map .abort requestsToAbort in - ( { model | jediRequests <- newRequests } + ( { model | jediRequests = newRequests } , Effects.batch aborts ) @@ -245,8 +245,8 @@ abortRequests model = -} abortAndSaveAllRequests : Model -> (Model, Effects Action) abortAndSaveAllRequests model = - ( { model | jediRequests <- [] - , requestsToResume <- List.append model.requestsToResume model.jediRequests } + ( { model | jediRequests = [] + , requestsToResume = List.append model.requestsToResume model.jediRequests } , Effects.batch (List.map .abort model.jediRequests) ) @@ -255,7 +255,7 @@ abortAndSaveAllRequests model = resumeAllRequests : Model -> (Model, Effects Action) resumeAllRequests model = let model' = - { model | requestsToResume <- [] } + { model | requestsToResume = [] } in pure model' `bindAll` List.map (retryRequest 0) model.requestsToResume @@ -293,8 +293,8 @@ doScroll model dir scrollSpeed = ) in - pure { model | jediSlots <- newJedis - , scrollPos <- newScrollPos } + pure { model | jediSlots = newJedis + , scrollPos = newScrollPos } >>= abortRequests >>= maybeFetchJedisAround endJediPos @@ -325,8 +325,8 @@ fetchJedi sleepMillis insertPos jediUrl model = |> Effects.task in - ( { model | jediRequests <- request :: model.jediRequests - , nextRequestId <- model.nextRequestId + 1 } + ( { model | jediRequests = request :: model.jediRequests + , nextRequestId = model.nextRequestId + 1 } , sendEffect ) @@ -334,7 +334,7 @@ fetchJedi sleepMillis insertPos jediUrl model = -} retryRequest : Float -> JediRequest -> Model -> (Model, Effects Action) retryRequest sleepMillis request model = - let model' = { model | jediRequests <- removeRequest request model.jediRequests } + let model' = { model | jediRequests = removeRequest request model.jediRequests } newInsertPos = adjustPos request.insertPos request.scrollPos @@ -613,7 +613,7 @@ pure model = (model, Effects.none) {-| Monadic bind: compose effectful computations. -} (>>=) : (a, Effects b) -> (a -> (c, Effects b)) -> (c, Effects b) -(model, effects) >>= f = +(>>=) (model, effects) f = let (model', effects') = f model in (model', Effects.batch [effects, effects'])