diff options
| author | LLLL Colonq <llll@colonq> | 2024-03-01 18:39:11 -0500 |
|---|---|---|
| committer | LLLL Colonq <llll@colonq> | 2024-03-01 18:39:11 -0500 |
| commit | 88e2726fc1fc6cec2b9e63526ce4c0a1a04a2e98 (patch) | |
| tree | 94fd56c8c02e422a54d69aa7dec798b7a55d6a2d | |
| parent | 4a23754fc6515c947e0bbac38cd0e558b701fe2f (diff) | |
Add new frontend
30 files changed, 3158 insertions, 1095 deletions
@@ -3,4 +3,5 @@ dist-newstyle node_modules fig-monitor-*.toml fig-frontend.toml -fig-frontend-assets
\ No newline at end of file +fig-frontend-assets +fig-frontend-client/output/*
\ No newline at end of file diff --git a/fig-frontend-client/.psc-ide-port b/fig-frontend-client/.psc-ide-port new file mode 100644 index 0000000..48a9dfe --- /dev/null +++ b/fig-frontend-client/.psc-ide-port @@ -0,0 +1 @@ +15776
\ No newline at end of file diff --git a/fig-frontend-client/assets/iosevka-comfy-regular.ttf b/fig-frontend-client/assets/iosevka-comfy-regular.ttf Binary files differnew file mode 100644 index 0000000..b474adc --- /dev/null +++ b/fig-frontend-client/assets/iosevka-comfy-regular.ttf diff --git a/fig-frontend-client/assets/mrgreen.png b/fig-frontend-client/assets/mrgreen.png Binary files differnew file mode 100644 index 0000000..1f1edca --- /dev/null +++ b/fig-frontend-client/assets/mrgreen.png diff --git a/fig-frontend-client/deploy.sh b/fig-frontend-client/deploy.sh new file mode 100755 index 0000000..f68b833 --- /dev/null +++ b/fig-frontend-client/deploy.sh @@ -0,0 +1,3 @@ +#!/bin/sh +purs-nix bundle +scp -r main.css main.js index.html assets/ pub.colonq.computer:~/public_html diff --git a/fig-frontend-client/index.html b/fig-frontend-client/index.html new file mode 100644 index 0000000..ef70156 --- /dev/null +++ b/fig-frontend-client/index.html @@ -0,0 +1,18 @@ +<!DOCTYPE html> +<html lang="en"> + <head> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> + <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"> + <title>LCOLONQ</title> + <link rel="icon" href="./assets/mrgreen.png"> + <link rel="stylesheet" type="text/css" href="./main.css"> + <script type="module" src="./main.js"></script> + </head> + <body> + <div id="lcolonq-title"> + LCOLONQ + <div id="lcolonq-subtitle">hi</div> + </div> + <canvas id="lcolonq-canvas"></canvas> + </body> +</html> diff --git a/fig-frontend-client/main.css b/fig-frontend-client/main.css new file mode 100644 index 0000000..a4b49a3 --- /dev/null +++ b/fig-frontend-client/main.css @@ -0,0 +1,49 @@ +@font-face { + font-family: "Iosevka Comfy"; + src: url("assets/iosevka-comfy-regular.ttf") format("truetype"); +} + +html, body { + overflow: hidden; + margin: 0 !important; + padding: 0 !important; + height: 100%; + width: 100%; +} + +body { + font-family: "Iosevka Comfy"; + font-weight: bold; + background-color: #050505; + color: white; + user-select: none; + image-rendering: pixelated; +} + +#lcolonq-title { + position: absolute; + top: 0px; + bottom: 0px; + left: 0px; + right: 0px; + text-align: center; + font-size: 20vw; +} + +#lcolonq-subtitle { + font-size: 5vw; +} + +#lcolonq-canvas { + position: absolute; + top: 0px; + bottom: 0px; + left: 0px; + right: 0px; + width: 100%; + height: 100%; +} + +button { + color: red; +} diff --git a/fig-frontend-client/main.js b/fig-frontend-client/main.js new file mode 100644 index 0000000..5cf9335 --- /dev/null +++ b/fig-frontend-client/main.js @@ -0,0 +1,2493 @@ +// output/Control.Semigroupoid/index.js +var semigroupoidFn = { + compose: function(f) { + return function(g) { + return function(x) { + return f(g(x)); + }; + }; + } +}; + +// output/Control.Category/index.js +var identity = function(dict) { + return dict.identity; +}; +var categoryFn = { + identity: function(x) { + return x; + }, + Semigroupoid0: function() { + return semigroupoidFn; + } +}; + +// output/Data.Boolean/index.js +var otherwise = true; + +// output/Data.Function/index.js +var flip = function(f) { + return function(b) { + return function(a) { + return f(a)(b); + }; + }; +}; +var $$const = function(a) { + return function(v) { + return a; + }; +}; + +// output/Data.Functor/foreign.js +var arrayMap = function(f) { + return function(arr) { + var l = arr.length; + var result = new Array(l); + for (var i = 0; i < l; i++) { + result[i] = f(arr[i]); + } + return result; + }; +}; + +// output/Data.Unit/foreign.js +var unit = void 0; + +// output/Type.Proxy/index.js +var $$Proxy = /* @__PURE__ */ function() { + function $$Proxy2() { + } + ; + $$Proxy2.value = new $$Proxy2(); + return $$Proxy2; +}(); + +// output/Data.Functor/index.js +var map = function(dict) { + return dict.map; +}; +var $$void = function(dictFunctor) { + return map(dictFunctor)($$const(unit)); +}; +var functorArray = { + map: arrayMap +}; + +// output/Control.Apply/index.js +var identity2 = /* @__PURE__ */ identity(categoryFn); +var apply = function(dict) { + return dict.apply; +}; +var applySecond = function(dictApply) { + var apply1 = apply(dictApply); + var map4 = map(dictApply.Functor0()); + return function(a) { + return function(b) { + return apply1(map4($$const(identity2))(a))(b); + }; + }; +}; + +// output/Control.Applicative/index.js +var pure = function(dict) { + return dict.pure; +}; +var when = function(dictApplicative) { + var pure12 = pure(dictApplicative); + return function(v) { + return function(v1) { + if (v) { + return v1; + } + ; + if (!v) { + return pure12(unit); + } + ; + throw new Error("Failed pattern match at Control.Applicative (line 63, column 1 - line 63, column 63): " + [v.constructor.name, v1.constructor.name]); + }; + }; +}; +var liftA1 = function(dictApplicative) { + var apply2 = apply(dictApplicative.Apply0()); + var pure12 = pure(dictApplicative); + return function(f) { + return function(a) { + return apply2(pure12(f))(a); + }; + }; +}; + +// output/Control.Bind/index.js +var discard = function(dict) { + return dict.discard; +}; +var bind = function(dict) { + return dict.bind; +}; +var discardUnit = { + discard: function(dictBind) { + return bind(dictBind); + } +}; + +// output/Data.Bounded/foreign.js +var topInt = 2147483647; +var bottomInt = -2147483648; +var topChar = String.fromCharCode(65535); +var bottomChar = String.fromCharCode(0); +var topNumber = Number.POSITIVE_INFINITY; +var bottomNumber = Number.NEGATIVE_INFINITY; + +// output/Data.Ord/foreign.js +var unsafeCompareImpl = function(lt) { + return function(eq3) { + return function(gt) { + return function(x) { + return function(y) { + return x < y ? lt : x === y ? eq3 : gt; + }; + }; + }; + }; +}; +var ordIntImpl = unsafeCompareImpl; + +// output/Data.Eq/foreign.js +var refEq = function(r1) { + return function(r2) { + return r1 === r2; + }; +}; +var eqBooleanImpl = refEq; +var eqIntImpl = refEq; + +// output/Data.Symbol/index.js +var reflectSymbol = function(dict) { + return dict.reflectSymbol; +}; + +// output/Record.Unsafe/foreign.js +var unsafeGet = function(label4) { + return function(rec) { + return rec[label4]; + }; +}; + +// output/Data.Eq/index.js +var eqRowNil = { + eqRecord: function(v) { + return function(v1) { + return function(v2) { + return true; + }; + }; + } +}; +var eqRecord = function(dict) { + return dict.eqRecord; +}; +var eqRec = function() { + return function(dictEqRecord) { + return { + eq: eqRecord(dictEqRecord)($$Proxy.value) + }; + }; +}; +var eqInt = { + eq: eqIntImpl +}; +var eqBoolean = { + eq: eqBooleanImpl +}; +var eq = function(dict) { + return dict.eq; +}; +var eq2 = /* @__PURE__ */ eq(eqBoolean); +var eqRowCons = function(dictEqRecord) { + var eqRecord1 = eqRecord(dictEqRecord); + return function() { + return function(dictIsSymbol) { + var reflectSymbol2 = reflectSymbol(dictIsSymbol); + return function(dictEq) { + var eq3 = eq(dictEq); + return { + eqRecord: function(v) { + return function(ra) { + return function(rb) { + var tail = eqRecord1($$Proxy.value)(ra)(rb); + var key = reflectSymbol2($$Proxy.value); + var get2 = unsafeGet(key); + return eq3(get2(ra))(get2(rb)) && tail; + }; + }; + } + }; + }; + }; + }; +}; +var notEq = function(dictEq) { + var eq3 = eq(dictEq); + return function(x) { + return function(y) { + return eq2(eq3(x)(y))(false); + }; + }; +}; + +// output/Data.Ordering/index.js +var LT = /* @__PURE__ */ function() { + function LT2() { + } + ; + LT2.value = new LT2(); + return LT2; +}(); +var GT = /* @__PURE__ */ function() { + function GT2() { + } + ; + GT2.value = new GT2(); + return GT2; +}(); +var EQ = /* @__PURE__ */ function() { + function EQ2() { + } + ; + EQ2.value = new EQ2(); + return EQ2; +}(); +var eqOrdering = { + eq: function(v) { + return function(v1) { + if (v instanceof LT && v1 instanceof LT) { + return true; + } + ; + if (v instanceof GT && v1 instanceof GT) { + return true; + } + ; + if (v instanceof EQ && v1 instanceof EQ) { + return true; + } + ; + return false; + }; + } +}; + +// output/Data.Ord/index.js +var eqRec2 = /* @__PURE__ */ eqRec(); +var notEq2 = /* @__PURE__ */ notEq(eqOrdering); +var ordRecordNil = { + compareRecord: function(v) { + return function(v1) { + return function(v2) { + return EQ.value; + }; + }; + }, + EqRecord0: function() { + return eqRowNil; + } +}; +var ordInt = /* @__PURE__ */ function() { + return { + compare: ordIntImpl(LT.value)(EQ.value)(GT.value), + Eq0: function() { + return eqInt; + } + }; +}(); +var compareRecord = function(dict) { + return dict.compareRecord; +}; +var ordRecord = function() { + return function(dictOrdRecord) { + var eqRec1 = eqRec2(dictOrdRecord.EqRecord0()); + return { + compare: compareRecord(dictOrdRecord)($$Proxy.value), + Eq0: function() { + return eqRec1; + } + }; + }; +}; +var compare = function(dict) { + return dict.compare; +}; +var ordRecordCons = function(dictOrdRecord) { + var compareRecord1 = compareRecord(dictOrdRecord); + var eqRowCons2 = eqRowCons(dictOrdRecord.EqRecord0())(); + return function() { + return function(dictIsSymbol) { + var reflectSymbol2 = reflectSymbol(dictIsSymbol); + var eqRowCons1 = eqRowCons2(dictIsSymbol); + return function(dictOrd) { + var compare3 = compare(dictOrd); + var eqRowCons22 = eqRowCons1(dictOrd.Eq0()); + return { + compareRecord: function(v) { + return function(ra) { + return function(rb) { + var key = reflectSymbol2($$Proxy.value); + var left = compare3(unsafeGet(key)(ra))(unsafeGet(key)(rb)); + var $95 = notEq2(left)(EQ.value); + if ($95) { + return left; + } + ; + return compareRecord1($$Proxy.value)(ra)(rb); + }; + }; + }, + EqRecord0: function() { + return eqRowCons22; + } + }; + }; + }; + }; +}; + +// output/Data.Bounded/index.js +var top = function(dict) { + return dict.top; +}; +var boundedInt = { + top: topInt, + bottom: bottomInt, + Ord0: function() { + return ordInt; + } +}; +var bottom = function(dict) { + return dict.bottom; +}; + +// output/Data.Semigroup/foreign.js +var concatArray = function(xs) { + return function(ys) { + if (xs.length === 0) + return ys; + if (ys.length === 0) + return xs; + return xs.concat(ys); + }; +}; + +// output/Data.Semigroup/index.js +var semigroupArray = { + append: concatArray +}; +var append = function(dict) { + return dict.append; +}; + +// output/Data.Monoid/index.js +var mempty = function(dict) { + return dict.mempty; +}; + +// output/Data.Tuple/index.js +var Tuple = /* @__PURE__ */ function() { + function Tuple2(value0, value1) { + this.value0 = value0; + this.value1 = value1; + } + ; + Tuple2.create = function(value0) { + return function(value1) { + return new Tuple2(value0, value1); + }; + }; + return Tuple2; +}(); +var snd = function(v) { + return v.value1; +}; +var fst = function(v) { + return v.value0; +}; + +// output/Control.Monad.State.Class/index.js +var state = function(dict) { + return dict.state; +}; +var put = function(dictMonadState) { + var state1 = state(dictMonadState); + return function(s) { + return state1(function(v) { + return new Tuple(unit, s); + }); + }; +}; +var modify_ = function(dictMonadState) { + var state1 = state(dictMonadState); + return function(f) { + return state1(function(s) { + return new Tuple(unit, f(s)); + }); + }; +}; +var get = function(dictMonadState) { + return state(dictMonadState)(function(s) { + return new Tuple(s, s); + }); +}; + +// output/Control.Monad/index.js +var ap = function(dictMonad) { + var bind2 = bind(dictMonad.Bind1()); + var pure3 = pure(dictMonad.Applicative0()); + return function(f) { + return function(a) { + return bind2(f)(function(f$prime) { + return bind2(a)(function(a$prime) { + return pure3(f$prime(a$prime)); + }); + }); + }; + }; +}; + +// output/Data.Maybe/index.js +var identity3 = /* @__PURE__ */ identity(categoryFn); +var Nothing = /* @__PURE__ */ function() { + function Nothing2() { + } + ; + Nothing2.value = new Nothing2(); + return Nothing2; +}(); +var Just = /* @__PURE__ */ function() { + function Just2(value0) { + this.value0 = value0; + } + ; + Just2.create = function(value0) { + return new Just2(value0); + }; + return Just2; +}(); +var maybe = function(v) { + return function(v1) { + return function(v2) { + if (v2 instanceof Nothing) { + return v; + } + ; + if (v2 instanceof Just) { + return v1(v2.value0); + } + ; + throw new Error("Failed pattern match at Data.Maybe (line 237, column 1 - line 237, column 51): " + [v.constructor.name, v1.constructor.name, v2.constructor.name]); + }; + }; +}; +var isNothing = /* @__PURE__ */ maybe(true)(/* @__PURE__ */ $$const(false)); +var fromMaybe = function(a) { + return maybe(a)(identity3); +}; +var fromJust = function() { + return function(v) { + if (v instanceof Just) { + return v.value0; + } + ; + throw new Error("Failed pattern match at Data.Maybe (line 288, column 1 - line 288, column 46): " + [v.constructor.name]); + }; +}; + +// output/Effect/foreign.js +var pureE = function(a) { + return function() { + return a; + }; +}; +var bindE = function(a) { + return function(f) { + return function() { + return f(a())(); + }; + }; +}; + +// output/Effect/index.js +var $runtime_lazy = function(name15, moduleName, init) { + var state3 = 0; + var val; + return function(lineNumber) { + if (state3 === 2) + return val; + if (state3 === 1) + throw new ReferenceError(name15 + " was needed before it finished initializing (module " + moduleName + ", line " + lineNumber + ")", moduleName, lineNumber); + state3 = 1; + val = init(); + state3 = 2; + return val; + }; +}; +var monadEffect = { + Applicative0: function() { + return applicativeEffect; + }, + Bind1: function() { + return bindEffect; + } +}; +var bindEffect = { + bind: bindE, + Apply0: function() { + return $lazy_applyEffect(0); + } +}; +var applicativeEffect = { + pure: pureE, + Apply0: function() { + return $lazy_applyEffect(0); + } +}; +var $lazy_functorEffect = /* @__PURE__ */ $runtime_lazy("functorEffect", "Effect", function() { + return { + map: liftA1(applicativeEffect) + }; +}); +var $lazy_applyEffect = /* @__PURE__ */ $runtime_lazy("applyEffect", "Effect", function() { + return { + apply: ap(monadEffect), + Functor0: function() { + return $lazy_functorEffect(0); + } + }; +}); +var functorEffect = /* @__PURE__ */ $lazy_functorEffect(20); +var applyEffect = /* @__PURE__ */ $lazy_applyEffect(23); + +// output/Effect.Ref/foreign.js +var _new = function(val) { + return function() { + return { value: val }; + }; +}; +var read = function(ref) { + return function() { + return ref.value; + }; +}; +var write = function(val) { + return function(ref) { + return function() { + ref.value = val; + }; + }; +}; + +// output/Effect.Ref/index.js +var $$new = _new; + +// output/Control.Monad.Trans.Class/index.js +var lift = function(dict) { + return dict.lift; +}; + +// output/Effect.Class/index.js +var monadEffectEffect = { + liftEffect: /* @__PURE__ */ identity(categoryFn), + Monad0: function() { + return monadEffect; + } +}; +var liftEffect = function(dict) { + return dict.liftEffect; +}; + +// output/Control.Monad.State.Trans/index.js +var runStateT = function(v) { + return v; +}; +var monadTransStateT = { + lift: function(dictMonad) { + var bind2 = bind(dictMonad.Bind1()); + var pure3 = pure(dictMonad.Applicative0()); + return function(m) { + return function(s) { + return bind2(m)(function(x) { + return pure3(new Tuple(x, s)); + }); + }; + }; + } +}; +var lift3 = /* @__PURE__ */ lift(monadTransStateT); +var functorStateT = function(dictFunctor) { + var map4 = map(dictFunctor); + return { + map: function(f) { + return function(v) { + return function(s) { + return map4(function(v1) { + return new Tuple(f(v1.value0), v1.value1); + })(v(s)); + }; + }; + } + }; +}; +var monadStateT = function(dictMonad) { + return { + Applicative0: function() { + return applicativeStateT(dictMonad); + }, + Bind1: function() { + return bindStateT(dictMonad); + } + }; +}; +var bindStateT = function(dictMonad) { + var bind2 = bind(dictMonad.Bind1()); + return { + bind: function(v) { + return function(f) { + return function(s) { + return bind2(v(s))(function(v1) { + var v3 = f(v1.value0); + return v3(v1.value1); + }); + }; + }; + }, + Apply0: function() { + return applyStateT(dictMonad); + } + }; +}; +var applyStateT = function(dictMonad) { + var functorStateT1 = functorStateT(dictMonad.Bind1().Apply0().Functor0()); + return { + apply: ap(monadStateT(dictMonad)), + Functor0: function() { + return functorStateT1; + } + }; +}; +var applicativeStateT = function(dictMonad) { + var pure3 = pure(dictMonad.Applicative0()); + return { + pure: function(a) { + return function(s) { + return pure3(new Tuple(a, s)); + }; + }, + Apply0: function() { + return applyStateT(dictMonad); + } + }; +}; +var monadEffectState = function(dictMonadEffect) { + var Monad0 = dictMonadEffect.Monad0(); + var monadStateT1 = monadStateT(Monad0); + return { + liftEffect: function() { + var $197 = lift3(Monad0); + var $198 = liftEffect(dictMonadEffect); + return function($199) { + return $197($198($199)); + }; + }(), + Monad0: function() { + return monadStateT1; + } + }; +}; +var monadStateStateT = function(dictMonad) { + var pure3 = pure(dictMonad.Applicative0()); + var monadStateT1 = monadStateT(dictMonad); + return { + state: function(f) { + return function($200) { + return pure3(f($200)); + }; + }, + Monad0: function() { + return monadStateT1; + } + }; +}; + +// output/Data.Array/foreign.js +var rangeImpl = function(start2, end) { + var step2 = start2 > end ? -1 : 1; + var result = new Array(step2 * (end - start2) + 1); + var i = start2, n = 0; + while (i !== end) { + result[n++] = i; + i += step2; + } + result[n] = i; + return result; +}; +var replicateFill = function(count, value12) { + if (count < 1) { + return []; + } + var result = new Array(count); + return result.fill(value12); +}; +var replicatePolyfill = function(count, value12) { + var result = []; + var n = 0; + for (var i = 0; i < count; i++) { + result[n++] = value12; + } + return result; +}; +var replicateImpl = typeof Array.prototype.fill === "function" ? replicateFill : replicatePolyfill; +var length = function(xs) { + return xs.length; +}; +var unconsImpl = function(empty3, next, xs) { + return xs.length === 0 ? empty3({}) : next(xs[0])(xs.slice(1)); +}; +var indexImpl = function(just, nothing, xs, i) { + return i < 0 || i >= xs.length ? nothing : just(xs[i]); +}; +var concat = function(xss) { + if (xss.length <= 1e4) { + return Array.prototype.concat.apply([], xss); + } + var result = []; + for (var i = 0, l = xss.length; i < l; i++) { + var xs = xss[i]; + for (var j = 0, m = xs.length; j < m; j++) { + result.push(xs[j]); + } + } + return result; +}; + +// output/Data.Foldable/foreign.js +var foldrArray = function(f) { + return function(init) { + return function(xs) { + var acc = init; + var len = xs.length; + for (var i = len - 1; i >= 0; i--) { + acc = f(xs[i])(acc); + } + return acc; + }; + }; +}; +var foldlArray = function(f) { + return function(init) { + return function(xs) { + var acc = init; + var len = xs.length; + for (var i = 0; i < len; i++) { + acc = f(acc)(xs[i]); + } + return acc; + }; + }; +}; + +// output/Unsafe.Coerce/foreign.js +var unsafeCoerce2 = function(x) { + return x; +}; + +// output/Data.Foldable/index.js +var foldr = function(dict) { + return dict.foldr; +}; +var foldl = function(dict) { + return dict.foldl; +}; +var foldMapDefaultR = function(dictFoldable) { + var foldr2 = foldr(dictFoldable); + return function(dictMonoid) { + var append4 = append(dictMonoid.Semigroup0()); + var mempty2 = mempty(dictMonoid); + return function(f) { + return foldr2(function(x) { + return function(acc) { + return append4(f(x))(acc); + }; + })(mempty2); + }; + }; +}; +var foldableArray = { + foldr: foldrArray, + foldl: foldlArray, + foldMap: function(dictMonoid) { + return foldMapDefaultR(foldableArray)(dictMonoid); + } +}; + +// output/Data.Function.Uncurried/foreign.js +var runFn2 = function(fn) { + return function(a) { + return function(b) { + return fn(a, b); + }; + }; +}; +var runFn3 = function(fn) { + return function(a) { + return function(b) { + return function(c) { + return fn(a, b, c); + }; + }; + }; +}; +var runFn4 = function(fn) { + return function(a) { + return function(b) { + return function(c) { + return function(d) { + return fn(a, b, c, d); + }; + }; + }; + }; +}; + +// output/Data.FunctorWithIndex/foreign.js +var mapWithIndexArray = function(f) { + return function(xs) { + var l = xs.length; + var result = Array(l); + for (var i = 0; i < l; i++) { + result[i] = f(i)(xs[i]); + } + return result; + }; +}; + +// output/Data.FunctorWithIndex/index.js +var mapWithIndex = function(dict) { + return dict.mapWithIndex; +}; +var functorWithIndexArray = { + mapWithIndex: mapWithIndexArray, + Functor0: function() { + return functorArray; + } +}; + +// output/Data.Traversable/foreign.js +var traverseArrayImpl = /* @__PURE__ */ function() { + function array1(a) { + return [a]; + } + function array2(a) { + return function(b) { + return [a, b]; + }; + } + function array3(a) { + return function(b) { + return function(c) { + return [a, b, c]; + }; + }; + } + function concat2(xs) { + return function(ys) { + return xs.concat(ys); + }; + } + return function(apply2) { + return function(map4) { + return function(pure3) { + return function(f) { + return function(array) { + function go2(bot, top3) { + switch (top3 - bot) { + case 0: + return pure3([]); + case 1: + return map4(array1)(f(array[bot])); + case 2: + return apply2(map4(array2)(f(array[bot])))(f(array[bot + 1])); + case 3: + return apply2(apply2(map4(array3)(f(array[bot])))(f(array[bot + 1])))(f(array[bot + 2])); + default: + var pivot = bot + Math.floor((top3 - bot) / 4) * 2; + return apply2(map4(concat2)(go2(bot, pivot)))(go2(pivot, top3)); + } + } + return go2(0, array.length); + }; + }; + }; + }; + }; +}(); + +// output/Data.Traversable/index.js +var identity4 = /* @__PURE__ */ identity(categoryFn); +var traverse = function(dict) { + return dict.traverse; +}; +var sequenceDefault = function(dictTraversable) { + var traverse2 = traverse(dictTraversable); + return function(dictApplicative) { + return traverse2(dictApplicative)(identity4); + }; +}; +var traversableArray = { + traverse: function(dictApplicative) { + var Apply0 = dictApplicative.Apply0(); + return traverseArrayImpl(apply(Apply0))(map(Apply0.Functor0()))(pure(dictApplicative)); + }, + sequence: function(dictApplicative) { + return sequenceDefault(traversableArray)(dictApplicative); + }, + Functor0: function() { + return functorArray; + }, + Foldable1: function() { + return foldableArray; + } +}; +var $$for = function(dictApplicative) { + return function(dictTraversable) { + var traverse2 = traverse(dictTraversable)(dictApplicative); + return function(x) { + return function(f) { + return traverse2(f)(x); + }; + }; + }; +}; + +// output/Data.Unfoldable/foreign.js +var unfoldrArrayImpl = function(isNothing2) { + return function(fromJust4) { + return function(fst2) { + return function(snd2) { + return function(f) { + return function(b) { + var result = []; + var value12 = b; + while (true) { + var maybe2 = f(value12); + if (isNothing2(maybe2)) + return result; + var tuple = fromJust4(maybe2); + result.push(fst2(tuple)); + value12 = snd2(tuple); + } + }; + }; + }; + }; + }; +}; + +// output/Data.Unfoldable1/foreign.js +var unfoldr1ArrayImpl = function(isNothing2) { + return function(fromJust4) { + return function(fst2) { + return function(snd2) { + return function(f) { + return function(b) { + var result = []; + var value12 = b; + while (true) { + var tuple = f(value12); + result.push(fst2(tuple)); + var maybe2 = snd2(tuple); + if (isNothing2(maybe2)) + return result; + value12 = fromJust4(maybe2); + } + }; + }; + }; + }; + }; +}; + +// output/Data.Unfoldable1/index.js +var fromJust2 = /* @__PURE__ */ fromJust(); +var unfoldable1Array = { + unfoldr1: /* @__PURE__ */ unfoldr1ArrayImpl(isNothing)(fromJust2)(fst)(snd) +}; + +// output/Data.Unfoldable/index.js +var fromJust3 = /* @__PURE__ */ fromJust(); +var unfoldr = function(dict) { + return dict.unfoldr; +}; +var unfoldableArray = { + unfoldr: /* @__PURE__ */ unfoldrArrayImpl(isNothing)(fromJust3)(fst)(snd), + Unfoldable10: function() { + return unfoldable1Array; + } +}; + +// output/Data.Array/index.js +var append2 = /* @__PURE__ */ append(semigroupArray); +var uncons = /* @__PURE__ */ function() { + return runFn3(unconsImpl)($$const(Nothing.value))(function(x) { + return function(xs) { + return new Just({ + head: x, + tail: xs + }); + }; + }); +}(); +var range2 = /* @__PURE__ */ runFn2(rangeImpl); +var mapWithIndex2 = /* @__PURE__ */ mapWithIndex(functorWithIndexArray); +var index = /* @__PURE__ */ function() { + return runFn4(indexImpl)(Just.create)(Nothing.value); +}(); +var head = function(xs) { + return index(xs)(0); +}; +var cons = function(x) { + return function(xs) { + return append2([x])(xs); + }; +}; + +// output/Data.Int/foreign.js +var fromNumberImpl = function(just) { + return function(nothing) { + return function(n) { + return (n | 0) === n ? just(n) : nothing; + }; + }; +}; +var toNumber = function(n) { + return n; +}; +var rem = function(x) { + return function(y) { + return x % y; + }; +}; + +// output/Data.Number/foreign.js +var isFiniteImpl = isFinite; +var ceil = Math.ceil; +var floor = Math.floor; + +// output/Data.Int/index.js +var top2 = /* @__PURE__ */ top(boundedInt); +var bottom2 = /* @__PURE__ */ bottom(boundedInt); +var fromNumber = /* @__PURE__ */ function() { + return fromNumberImpl(Just.create)(Nothing.value); +}(); +var unsafeClamp = function(x) { + if (!isFiniteImpl(x)) { + return 0; + } + ; + if (x >= toNumber(top2)) { + return top2; + } + ; + if (x <= toNumber(bottom2)) { + return bottom2; + } + ; + if (otherwise) { + return fromMaybe(0)(fromNumber(x)); + } + ; + throw new Error("Failed pattern match at Data.Int (line 72, column 1 - line 72, column 29): " + [x.constructor.name]); +}; +var floor2 = function($39) { + return unsafeClamp(floor($39)); +}; +var ceil2 = function($40) { + return unsafeClamp(ceil($40)); +}; + +// output/Data.Map.Internal/index.js +var $runtime_lazy2 = function(name15, moduleName, init) { + var state3 = 0; + var val; + return function(lineNumber) { + if (state3 === 2) + return val; + if (state3 === 1) + throw new ReferenceError(name15 + " was needed before it finished initializing (module " + moduleName + ", line " + lineNumber + ")", moduleName, lineNumber); + state3 = 1; + val = init(); + state3 = 2; + return val; + }; +}; +var Leaf = /* @__PURE__ */ function() { + function Leaf2() { + } + ; + Leaf2.value = new Leaf2(); + return Leaf2; +}(); +var Node = /* @__PURE__ */ function() { + function Node2(value0, value1, value22, value32, value42, value52) { + this.value0 = value0; + this.value1 = value1; + this.value2 = value22; + this.value3 = value32; + this.value4 = value42; + this.value5 = value52; + } + ; + Node2.create = function(value0) { + return function(value1) { + return function(value22) { + return function(value32) { + return function(value42) { + return function(value52) { + return new Node2(value0, value1, value22, value32, value42, value52); + }; + }; + }; + }; + }; + }; + return Node2; +}(); +var IterLeaf = /* @__PURE__ */ function() { + function IterLeaf2() { + } + ; + IterLeaf2.value = new IterLeaf2(); + return IterLeaf2; +}(); +var IterEmit = /* @__PURE__ */ function() { + function IterEmit2(value0, value1, value22) { + this.value0 = value0; + this.value1 = value1; + this.value2 = value22; + } + ; + IterEmit2.create = function(value0) { + return function(value1) { + return function(value22) { + return new IterEmit2(value0, value1, value22); + }; + }; + }; + return IterEmit2; +}(); +var IterNode = /* @__PURE__ */ function() { + function IterNode2(value0, value1) { + this.value0 = value0; + this.value1 = value1; + } + ; + IterNode2.create = function(value0) { + return function(value1) { + return new IterNode2(value0, value1); + }; + }; + return IterNode2; +}(); +var Split = /* @__PURE__ */ function() { + function Split2(value0, value1, value22) { + this.value0 = value0; + this.value1 = value1; + this.value2 = value22; + } + ; + Split2.create = function(value0) { + return function(value1) { + return function(value22) { + return new Split2(value0, value1, value22); + }; + }; + }; + return Split2; +}(); +var SplitLast = /* @__PURE__ */ function() { + function SplitLast2(value0, value1, value22) { + this.value0 = value0; + this.value1 = value1; + this.value2 = value22; + } + ; + SplitLast2.create = function(value0) { + return function(value1) { + return function(value22) { + return new SplitLast2(value0, value1, value22); + }; + }; + }; + return SplitLast2; +}(); +var unsafeNode = function(k, v, l, r) { + if (l instanceof Leaf) { + if (r instanceof Leaf) { + return new Node(1, 1, k, v, l, r); + } + ; + if (r instanceof Node) { + return new Node(1 + r.value0 | 0, 1 + r.value1 | 0, k, v, l, r); + } + ; + throw new Error("Failed pattern match at Data.Map.Internal (line 680, column 5 - line 684, column 39): " + [r.constructor.name]); + } + ; + if (l instanceof Node) { + if (r instanceof Leaf) { + return new Node(1 + l.value0 | 0, 1 + l.value1 | 0, k, v, l, r); + } + ; + if (r instanceof Node) { + return new Node(1 + function() { + var $277 = l.value0 > r.value0; + if ($277) { + return l.value0; + } + ; + return r.value0; + }() | 0, (1 + l.value1 | 0) + r.value1 | 0, k, v, l, r); + } + ; + throw new Error("Failed pattern match at Data.Map.Internal (line 686, column 5 - line 690, column 68): " + [r.constructor.name]); + } + ; + throw new Error("Failed pattern match at Data.Map.Internal (line 678, column 32 - line 690, column 68): " + [l.constructor.name]); +}; +var toMapIter = /* @__PURE__ */ function() { + return flip(IterNode.create)(IterLeaf.value); +}(); +var stepWith = function(f) { + return function(next) { + return function(done) { + var go2 = function($copy_v) { + var $tco_done = false; + var $tco_result; + function $tco_loop(v) { + if (v instanceof IterLeaf) { + $tco_done = true; + return done(unit); + } + ; + if (v instanceof IterEmit) { + $tco_done = true; + return next(v.value0, v.value1, v.value2); + } + ; + if (v instanceof IterNode) { + $copy_v = f(v.value1)(v.value0); + return; + } + ; + throw new Error("Failed pattern match at Data.Map.Internal (line 918, column 8 - line 924, column 20): " + [v.constructor.name]); + } + ; + while (!$tco_done) { + $tco_result = $tco_loop($copy_v); + } + ; + return $tco_result; + }; + return go2; + }; + }; +}; +var singleton3 = function(k) { + return function(v) { + return new Node(1, 1, k, v, Leaf.value, Leaf.value); + }; +}; +var unsafeBalancedNode = /* @__PURE__ */ function() { + var height8 = function(v) { + if (v instanceof Leaf) { + return 0; + } + ; + if (v instanceof Node) { + return v.value0; + } + ; + throw new Error("Failed pattern match at Data.Map.Internal (line 735, column 12 - line 737, column 26): " + [v.constructor.name]); + }; + var rotateLeft = function(k, v, l, rk, rv, rl, rr) { + if (rl instanceof Node && rl.value0 > height8(rr)) { + return unsafeNode(rl.value2, rl.value3, unsafeNode(k, v, l, rl.value4), unsafeNode(rk, rv, rl.value5, rr)); + } + ; + return unsafeNode(rk, rv, unsafeNode(k, v, l, rl), rr); + }; + var rotateRight = function(k, v, lk, lv, ll, lr, r) { + if (lr instanceof Node && height8(ll) <= lr.value0) { + return unsafeNode(lr.value2, lr.value3, unsafeNode(lk, lv, ll, lr.value4), unsafeNode(k, v, lr.value5, r)); + } + ; + return unsafeNode(lk, lv, ll, unsafeNode(k, v, lr, r)); + }; + return function(k, v, l, r) { + if (l instanceof Leaf) { + if (r instanceof Leaf) { + return singleton3(k)(v); + } + ; + if (r instanceof Node && r.value0 > 1) { + return rotateLeft(k, v, l, r.value2, r.value3, r.value4, r.value5); + } + ; + return unsafeNode(k, v, l, r); + } + ; + if (l instanceof Node) { + if (r instanceof Node) { + if (r.value0 > (l.value0 + 1 | 0)) { + return rotateLeft(k, v, l, r.value2, r.value3, r.value4, r.value5); + } + ; + if (l.value0 > (r.value0 + 1 | 0)) { + return rotateRight(k, v, l.value2, l.value3, l.value4, l.value5, r); + } + ; + } + ; + if (r instanceof Leaf && l.value0 > 1) { + return rotateRight(k, v, l.value2, l.value3, l.value4, l.value5, r); + } + ; + return unsafeNode(k, v, l, r); + } + ; + throw new Error("Failed pattern match at Data.Map.Internal (line 695, column 40 - line 716, column 34): " + [l.constructor.name]); + }; +}(); +var $lazy_unsafeSplit = /* @__PURE__ */ $runtime_lazy2("unsafeSplit", "Data.Map.Internal", function() { + return function(comp, k, m) { + if (m instanceof Leaf) { + return new Split(Nothing.value, Leaf.value, Leaf.value); + } + ; + if (m instanceof Node) { + var v = comp(k)(m.value2); + if (v instanceof LT) { + var v1 = $lazy_unsafeSplit(771)(comp, k, m.value4); + return new Split(v1.value0, v1.value1, unsafeBalancedNode(m.value2, m.value3, v1.value2, m.value5)); + } + ; + if (v instanceof GT) { + var v1 = $lazy_unsafeSplit(774)(comp, k, m.value5); + return new Split(v1.value0, unsafeBalancedNode(m.value2, m.value3, m.value4, v1.value1), v1.value2); + } + ; + if (v instanceof EQ) { + return new Split(new Just(m.value3), m.value4, m.value5); + } + ; + throw new Error("Failed pattern match at Data.Map.Internal (line 769, column 5 - line 777, column 30): " + [v.constructor.name]); + } + ; + throw new Error("Failed pattern match at Data.Map.Internal (line 765, column 34 - line 777, column 30): " + [m.constructor.name]); + }; +}); +var unsafeSplit = /* @__PURE__ */ $lazy_unsafeSplit(764); +var $lazy_unsafeSplitLast = /* @__PURE__ */ $runtime_lazy2("unsafeSplitLast", "Data.Map.Internal", function() { + return function(k, v, l, r) { + if (r instanceof Leaf) { + return new SplitLast(k, v, l); + } + ; + if (r instanceof Node) { + var v1 = $lazy_unsafeSplitLast(757)(r.value2, r.value3, r.value4, r.value5); + return new SplitLast(v1.value0, v1.value1, unsafeBalancedNode(k, v, l, v1.value2)); + } + ; + throw new Error("Failed pattern match at Data.Map.Internal (line 754, column 37 - line 758, column 57): " + [r.constructor.name]); + }; +}); +var unsafeSplitLast = /* @__PURE__ */ $lazy_unsafeSplitLast(753); +var unsafeJoinNodes = function(v, v1) { + if (v instanceof Leaf) { + return v1; + } + ; + if (v instanceof Node) { + var v2 = unsafeSplitLast(v.value2, v.value3, v.value4, v.value5); + return unsafeBalancedNode(v2.value0, v2.value1, v2.value2, v1); + } + ; + throw new Error("Failed pattern match at Data.Map.Internal (line 742, column 25 - line 746, column 38): " + [v.constructor.name, v1.constructor.name]); +}; +var $lazy_unsafeUnionWith = /* @__PURE__ */ $runtime_lazy2("unsafeUnionWith", "Data.Map.Internal", function() { + return function(comp, app, l, r) { + if (l instanceof Leaf) { + return r; + } + ; + if (r instanceof Leaf) { + return l; + } + ; + if (r instanceof Node) { + var v = unsafeSplit(comp, r.value2, l); + var l$prime = $lazy_unsafeUnionWith(787)(comp, app, v.value1, r.value4); + var r$prime = $lazy_unsafeUnionWith(788)(comp, app, v.value2, r.value5); + if (v.value0 instanceof Just) { + return unsafeBalancedNode(r.value2, app(v.value0.value0)(r.value3), l$prime, r$prime); + } + ; + if (v.value0 instanceof Nothing) { + return unsafeBalancedNode(r.value2, r.value3, l$prime, r$prime); + } + ; + throw new Error("Failed pattern match at Data.Map.Internal (line 789, column 5 - line 793, column 46): " + [v.value0.constructor.name]); + } + ; + throw new Error("Failed pattern match at Data.Map.Internal (line 782, column 42 - line 793, column 46): " + [l.constructor.name, r.constructor.name]); + }; +}); +var unsafeUnionWith = /* @__PURE__ */ $lazy_unsafeUnionWith(781); +var unionWith = function(dictOrd) { + var compare2 = compare(dictOrd); + return function(app) { + return function(m1) { + return function(m2) { + return unsafeUnionWith(compare2, app, m1, m2); + }; + }; + }; +}; +var union = function(dictOrd) { + return unionWith(dictOrd)($$const); +}; +var member = function(dictOrd) { + var compare2 = compare(dictOrd); + return function(k) { + var go2 = function($copy_v) { + var $tco_done = false; + var $tco_result; + function $tco_loop(v) { + if (v instanceof Leaf) { + $tco_done = true; + return false; + } + ; + if (v instanceof Node) { + var v1 = compare2(k)(v.value2); + if (v1 instanceof LT) { + $copy_v = v.value4; + return; + } + ; + if (v1 instanceof GT) { + $copy_v = v.value5; + return; + } + ; + if (v1 instanceof EQ) { + $tco_done = true; + return true; + } + ; + throw new Error("Failed pattern match at Data.Map.Internal (line 457, column 7 - line 460, column 19): " + [v1.constructor.name]); + } + ; + throw new Error("Failed pattern match at Data.Map.Internal (line 454, column 8 - line 460, column 19): " + [v.constructor.name]); + } + ; + while (!$tco_done) { + $tco_result = $tco_loop($copy_v); + } + ; + return $tco_result; + }; + return go2; + }; +}; +var lookup = function(dictOrd) { + var compare2 = compare(dictOrd); + return function(k) { + var go2 = function($copy_v) { + var $tco_done = false; + var $tco_result; + function $tco_loop(v) { + if (v instanceof Leaf) { + $tco_done = true; + return Nothing.value; + } + ; + if (v instanceof Node) { + var v1 = compare2(k)(v.value2); + if (v1 instanceof LT) { + $copy_v = v.value4; + return; + } + ; + if (v1 instanceof GT) { + $copy_v = v.value5; + return; + } + ; + if (v1 instanceof EQ) { + $tco_done = true; + return new Just(v.value3); + } + ; + throw new Error("Failed pattern match at Data.Map.Internal (line 281, column 7 - line 284, column 22): " + [v1.constructor.name]); + } + ; + throw new Error("Failed pattern match at Data.Map.Internal (line 278, column 8 - line 284, column 22): " + [v.constructor.name]); + } + ; + while (!$tco_done) { + $tco_result = $tco_loop($copy_v); + } + ; + return $tco_result; + }; + return go2; + }; +}; +var iterMapL = /* @__PURE__ */ function() { + var go2 = function($copy_iter) { + return function($copy_v) { + var $tco_var_iter = $copy_iter; + var $tco_done = false; + var $tco_result; + function $tco_loop(iter, v) { + if (v instanceof Leaf) { + $tco_done = true; + return iter; + } + ; + if (v instanceof Node) { + if (v.value5 instanceof Leaf) { + $tco_var_iter = new IterEmit(v.value2, v.value3, iter); + $copy_v = v.value4; + return; + } + ; + $tco_var_iter = new IterEmit(v.value2, v.value3, new IterNode(v.value5, iter)); + $copy_v = v.value4; + return; + } + ; + throw new Error("Failed pattern match at Data.Map.Internal (line 929, column 13 - line 936, column 48): " + [v.constructor.name]); + } + ; + while (!$tco_done) { + $tco_result = $tco_loop($tco_var_iter, $copy_v); + } + ; + return $tco_result; + }; + }; + return go2; +}(); +var stepAscCps = /* @__PURE__ */ stepWith(iterMapL); +var stepUnfoldr = /* @__PURE__ */ function() { + var step2 = function(k, v, next) { + return new Just(new Tuple(new Tuple(k, v), next)); + }; + return stepAscCps(step2)(function(v) { + return Nothing.value; + }); +}(); +var toUnfoldable = function(dictUnfoldable) { + var $767 = unfoldr(dictUnfoldable)(stepUnfoldr); + return function($768) { + return $767(toMapIter($768)); + }; +}; +var isEmpty = function(v) { + if (v instanceof Leaf) { + return true; + } + ; + return false; +}; +var insert = function(dictOrd) { + var compare2 = compare(dictOrd); + return function(k) { + return function(v) { + var go2 = function(v1) { + if (v1 instanceof Leaf) { + return singleton3(k)(v); + } + ; + if (v1 instanceof Node) { + var v2 = compare2(k)(v1.value2); + if (v2 instanceof LT) { + return unsafeBalancedNode(v1.value2, v1.value3, go2(v1.value4), v1.value5); + } + ; + if (v2 instanceof GT) { + return unsafeBalancedNode(v1.value2, v1.value3, v1.value4, go2(v1.value5)); + } + ; + if (v2 instanceof EQ) { + return new Node(v1.value0, v1.value1, k, v, v1.value4, v1.value5); + } + ; + throw new Error("Failed pattern match at Data.Map.Internal (line 469, column 7 - line 472, column 35): " + [v2.constructor.name]); + } + ; + throw new Error("Failed pattern match at Data.Map.Internal (line 466, column 8 - line 472, column 35): " + [v1.constructor.name]); + }; + return go2; + }; + }; +}; +var filterWithKey = function(dictOrd) { + return function(f) { + var go2 = function(v) { + if (v instanceof Leaf) { + return Leaf.value; + } + ; + if (v instanceof Node) { + if (f(v.value2)(v.value3)) { + return unsafeBalancedNode(v.value2, v.value3, go2(v.value4), go2(v.value5)); + } + ; + if (otherwise) { + return unsafeJoinNodes(go2(v.value4), go2(v.value5)); + } + ; + } + ; + throw new Error("Failed pattern match at Data.Map.Internal (line 625, column 8 - line 631, column 47): " + [v.constructor.name]); + }; + return go2; + }; +}; +var filter = function(dictOrd) { + var $769 = filterWithKey(dictOrd); + return function($770) { + return $769($$const($770)); + }; +}; +var empty2 = /* @__PURE__ */ function() { + return Leaf.value; +}(); +var fromFoldable = function(dictOrd) { + var insert1 = insert(dictOrd); + return function(dictFoldable) { + return foldl(dictFoldable)(function(m) { + return function(v) { + return insert1(v.value0)(v.value1)(m); + }; + })(empty2); + }; +}; +var unions = function(dictOrd) { + var union1 = union(dictOrd); + return function(dictFoldable) { + return foldl(dictFoldable)(union1)(empty2); + }; +}; +var $$delete = function(dictOrd) { + var compare2 = compare(dictOrd); + return function(k) { + var go2 = function(v) { + if (v instanceof Leaf) { + return Leaf.value; + } + ; + if (v instanceof Node) { + var v1 = compare2(k)(v.value2); + if (v1 instanceof LT) { + return unsafeBalancedNode(v.value2, v.value3, go2(v.value4), v.value5); + } + ; + if (v1 instanceof GT) { + return unsafeBalancedNode(v.value2, v.value3, v.value4, go2(v.value5)); + } + ; + if (v1 instanceof EQ) { + return unsafeJoinNodes(v.value4, v.value5); + } + ; + throw new Error("Failed pattern match at Data.Map.Internal (line 496, column 7 - line 499, column 43): " + [v1.constructor.name]); + } + ; + throw new Error("Failed pattern match at Data.Map.Internal (line 493, column 8 - line 499, column 43): " + [v.constructor.name]); + }; + return go2; + }; +}; + +// output/Data.String.CodeUnits/foreign.js +var toCharArray = function(s) { + return s.split(""); +}; +var singleton4 = function(c) { + return c; +}; +var _charAt = function(just) { + return function(nothing) { + return function(i) { + return function(s) { + return i >= 0 && i < s.length ? just(s.charAt(i)) : nothing; + }; + }; + }; +}; +var length2 = function(s) { + return s.length; +}; + +// output/Data.String.CodeUnits/index.js +var charAt2 = /* @__PURE__ */ function() { + return _charAt(Just.create)(Nothing.value); +}(); + +// output/Effect.Console/foreign.js +var log2 = function(s) { + return function() { + console.log(s); + }; +}; + +// output/Effect.Random/foreign.js +var random = Math.random; + +// output/Effect.Random/index.js +var randomInt = function(low2) { + return function(high2) { + return function __do3() { + var n = random(); + var asNumber = (toNumber(high2) - toNumber(low2) + 1) * n + toNumber(low2); + return floor2(asNumber); + }; + }; +}; + +// output/Graphics.Canvas/foreign.js +function getCanvasElementByIdImpl(id, Just2, Nothing2) { + return function() { + var el = document.getElementById(id); + if (el && el instanceof HTMLCanvasElement) { + return Just2(el); + } else { + return Nothing2; + } + }; +} +function getContext2D(c) { + return function() { + return c.getContext("2d"); + }; +} +function setCanvasWidth(canvas) { + return function(width8) { + return function() { + canvas.width = width8; + }; + }; +} +function setCanvasHeight(canvas) { + return function(height8) { + return function() { + canvas.height = height8; + }; + }; +} +function setFillStyle(ctx) { + return function(style) { + return function() { + ctx.fillStyle = style; + }; + }; +} +function fillRect(ctx) { + return function(r) { + return function() { + ctx.fillRect(r.x, r.y, r.width, r.height); + }; + }; +} +function clearRect(ctx) { + return function(r) { + return function() { + ctx.clearRect(r.x, r.y, r.width, r.height); + }; + }; +} +function setFont(ctx) { + return function(fontspec) { + return function() { + ctx.font = fontspec; + }; + }; +} +function fillText(ctx) { + return function(text5) { + return function(x) { + return function(y) { + return function() { + ctx.fillText(text5, x, y); + }; + }; + }; + }; +} + +// output/Graphics.Canvas/index.js +var applySecond2 = /* @__PURE__ */ applySecond(applyEffect); +var setCanvasDimensions = function(ce) { + return function(d) { + return applySecond2(setCanvasHeight(ce)(d.height))(setCanvasWidth(ce)(d.width)); + }; +}; +var getCanvasElementById = function(elId) { + return getCanvasElementByIdImpl(elId, Just.create, Nothing.value); +}; + +// output/Web.Event.EventTarget/foreign.js +function eventListener(fn) { + return function() { + return function(event) { + return fn(event)(); + }; + }; +} +function addEventListener(type) { + return function(listener) { + return function(useCapture) { + return function(target5) { + return function() { + return target5.addEventListener(type, listener, useCapture); + }; + }; + }; + }; +} + +// output/Web.HTML/foreign.js +var windowImpl = function() { + return window; +}; + +// output/Web.Internal.FFI/foreign.js +function _unsafeReadProtoTagged(nothing, just, name15, value12) { + if (typeof window !== "undefined") { + var ty = window[name15]; + if (ty != null && value12 instanceof ty) { + return just(value12); + } + } + var obj = value12; + while (obj != null) { + var proto = Object.getPrototypeOf(obj); + var constructorName = proto.constructor.name; + if (constructorName === name15) { + return just(value12); + } else if (constructorName === "Object") { + return nothing; + } + obj = proto; + } + return nothing; +} + +// output/Web.Internal.FFI/index.js +var unsafeReadProtoTagged = function(name15) { + return function(value12) { + return _unsafeReadProtoTagged(Nothing.value, Just.create, name15, value12); + }; +}; + +// output/Data.Nullable/foreign.js +function nullable(a, r, f) { + return a == null ? r : f(a); +} + +// output/Data.Nullable/index.js +var toMaybe = function(n) { + return nullable(n, Nothing.value, Just.create); +}; + +// output/Web.HTML.Window/foreign.js +function innerWidth(window2) { + return function() { + return window2.innerWidth; + }; +} +function innerHeight(window2) { + return function() { + return window2.innerHeight; + }; +} +function _open(url) { + return function(name15) { + return function(features) { + return function(window2) { + return function() { + return window2.open(url, name15, features); + }; + }; + }; + }; +} +function requestAnimationFrame(fn) { + return function(window2) { + return function() { + return window2.requestAnimationFrame(fn); + }; + }; +} + +// output/Web.HTML.Window/index.js +var map2 = /* @__PURE__ */ map(functorEffect); +var toEventTarget = unsafeCoerce2; +var open = function(url$prime) { + return function(name15) { + return function(features) { + return function(window2) { + return map2(toMaybe)(_open(url$prime)(name15)(features)(window2)); + }; + }; + }; +}; + +// output/Web.UIEvent.MouseEvent/foreign.js +function pageX(e) { + return e.pageX; +} +function pageY(e) { + return e.pageY; +} + +// output/Web.UIEvent.MouseEvent/index.js +var fromEvent = /* @__PURE__ */ unsafeReadProtoTagged("MouseEvent"); + +// output/Main/index.js +var ordRecord2 = /* @__PURE__ */ ordRecord()(/* @__PURE__ */ ordRecordCons(/* @__PURE__ */ ordRecordCons(ordRecordNil)()({ + reflectSymbol: function() { + return "y"; + } +})(ordInt))()({ + reflectSymbol: function() { + return "x"; + } +})(ordInt)); +var filter2 = /* @__PURE__ */ filter(ordRecord2); +var toUnfoldable2 = /* @__PURE__ */ toUnfoldable(unfoldableArray); +var pure2 = /* @__PURE__ */ pure(applicativeEffect); +var insert2 = /* @__PURE__ */ insert(ordRecord2); +var $$delete2 = /* @__PURE__ */ $$delete(ordRecord2); +var map3 = /* @__PURE__ */ map(functorEffect); +var discard2 = /* @__PURE__ */ discard(discardUnit); +var fromFoldable2 = /* @__PURE__ */ fromFoldable(ordRecord2)(foldableArray); +var $$void2 = /* @__PURE__ */ $$void(functorEffect); +var unions2 = /* @__PURE__ */ unions(ordRecord2)(foldableArray); +var map1 = /* @__PURE__ */ map(functorArray); +var union2 = /* @__PURE__ */ union(ordRecord2); +var append3 = /* @__PURE__ */ append(semigroupArray); +var lookup2 = /* @__PURE__ */ lookup(ordRecord2); +var member2 = /* @__PURE__ */ member(ordRecord2); +var $$for2 = /* @__PURE__ */ $$for(applicativeEffect)(traversableArray); +var discard22 = /* @__PURE__ */ discard2(/* @__PURE__ */ bindStateT(monadEffect)); +var monadStateStateT2 = /* @__PURE__ */ monadStateStateT(monadEffect); +var monadEffectState2 = /* @__PURE__ */ monadEffectState(monadEffectEffect); +var applicativeStateT2 = /* @__PURE__ */ applicativeStateT(monadEffect); +var pure1 = /* @__PURE__ */ pure(applicativeStateT2); +var when2 = /* @__PURE__ */ when(applicativeStateT2); +var void1 = /* @__PURE__ */ $$void(/* @__PURE__ */ functorStateT(functorEffect)); +var for1 = /* @__PURE__ */ $$for(applicativeStateT2)(traversableArray); +var GfxWhiteout = /* @__PURE__ */ function() { + function GfxWhiteout2() { + } + ; + GfxWhiteout2.value = new GfxWhiteout2(); + return GfxWhiteout2; +}(); +var EventGfx = /* @__PURE__ */ function() { + function EventGfx2(value0) { + this.value0 = value0; + } + ; + EventGfx2.create = function(value0) { + return new EventGfx2(value0); + }; + return EventGfx2; +}(); +var EventMouseClick = /* @__PURE__ */ function() { + function EventMouseClick2(value0, value1) { + this.value0 = value0; + this.value1 = value1; + } + ; + EventMouseClick2.create = function(value0) { + return function(value1) { + return new EventMouseClick2(value0, value1); + }; + }; + return EventMouseClick2; +}(); +var EventMouseMove = /* @__PURE__ */ function() { + function EventMouseMove2(value0, value1) { + this.value0 = value0; + this.value1 = value1; + } + ; + EventMouseMove2.create = function(value0) { + return function(value1) { + return new EventMouseMove2(value0, value1); + }; + }; + return EventMouseMove2; +}(); +var tick = function(dictMonadState) { + return modify_(dictMonadState)(function(st) { + var $109 = {}; + for (var $110 in st) { + if ({}.hasOwnProperty.call(st, $110)) { + $109[$110] = st[$110]; + } + ; + } + ; + $109.tick = st.tick + 1 | 0; + $109.transitions = function() { + var v1 = uncons(st.transitions); + if (v1 instanceof Nothing) { + return st.transitions; + } + ; + if (v1 instanceof Just) { + var $105 = isEmpty(v1.value0.head.cells); + if ($105) { + return v1.value0.tail; + } + ; + return st.transitions; + } + ; + throw new Error("Failed pattern match at Main (line 217, column 19 - line 219, column 79): " + [v1.constructor.name]); + }(); + $109.inverse = filter2(function(v1) { + return st.tick <= v1; + })(st.inverse); + return $109; + }); +}; +var tick1 = /* @__PURE__ */ tick(monadStateStateT2); +var pickRandom = function(cells2) { + var arr = toUnfoldable2(cells2); + return function __do3() { + var idx = randomInt(0)(length(arr) - 1 | 0)(); + var v = index(arr)(idx); + if (v instanceof Nothing) { + return Nothing.value; + } + ; + if (v instanceof Just) { + return new Just(v.value0); + } + ; + throw new Error("Failed pattern match at Main (line 135, column 3 - line 137, column 28): " + [v.constructor.name]); + }; +}; +var pickCell = function(dictMonadState) { + var get2 = get(dictMonadState); + var put2 = put(dictMonadState); + return function(dictMonadEffect) { + var Monad0 = dictMonadEffect.Monad0(); + var bind1 = bind(Monad0.Bind1()); + var pure22 = pure(Monad0.Applicative0()); + var liftEffect2 = liftEffect(dictMonadEffect); + return bind1(get2)(function(st) { + var v = uncons(st.transitions); + if (v instanceof Nothing) { + return pure22(unit); + } + ; + if (v instanceof Just) { + return bind1(liftEffect2(v.value0.head.picker(v.value0.head.cells)))(function(v1) { + if (v1 instanceof Nothing) { + return pure22(unit); + } + ; + if (v1 instanceof Just) { + return put2(function() { + var $119 = {}; + for (var $120 in st) { + if ({}.hasOwnProperty.call(st, $120)) { + $119[$120] = st[$120]; + } + ; + } + ; + $119.cells = insert2(v1.value0.value0)(v1.value0.value1)(st.cells); + $119.transitions = cons(function() { + var $116 = {}; + for (var $117 in v.value0.head) { + if ({}.hasOwnProperty.call(v.value0.head, $117)) { + $116[$117] = v["value0"]["head"][$117]; + } + ; + } + ; + $116.cells = $$delete2(v1.value0.value0)(v.value0.head.cells); + return $116; + }())(v.value0.tail); + return $119; + }()); + } + ; + throw new Error("Failed pattern match at Main (line 249, column 49 - line 252, column 120): " + [v1.constructor.name]); + }); + } + ; + throw new Error("Failed pattern match at Main (line 246, column 3 - line 252, column 120): " + [v.constructor.name]); + }); + }; +}; +var pickCell1 = /* @__PURE__ */ pickCell(monadStateStateT2)(monadEffectState2); +var newContext = function __do() { + var w = windowImpl(); + var v = getCanvasElementById("lcolonq-canvas")(); + if (v instanceof Nothing) { + return Nothing.value; + } + ; + if (v instanceof Just) { + var width8 = map3(toNumber)(innerWidth(w))(); + var height8 = map3(toNumber)(innerHeight(w))(); + setCanvasDimensions(v.value0)({ + width: width8, + height: height8 + })(); + var render = getContext2D(v.value0)(); + setFont(render)("bold 0.8vw Iosevka Comfy")(); + var cellDim = toNumber(ceil2(width8 / 100)); + return new Just({ + window: w, + canvas: v.value0, + render, + width: width8, + height: height8, + cellDim, + widthCells: ceil2(100), + heightCells: ceil2(height8 / cellDim), + events: [new EventGfx(GfxWhiteout.value)] + }); + } + ; + throw new Error("Failed pattern match at Main (line 77, column 45 - line 97, column 10): " + [v.constructor.name]); +}; +var initialState = { + tick: 0, + cells: empty2, + inverse: empty2, + transitions: [] +}; +var gfxTransitions = function(ctx) { + return function(v) { + var link = function(y) { + return function(fgc) { + return function(bgc) { + return function(str) { + return function(url) { + return fromFoldable2(mapWithIndex2(function(i) { + return function(c) { + return new Tuple({ + x: i, + y + }, { + bg: bgc, + fg: fgc, + "char": singleton4(c), + click: function(st) { + return function __do3() { + $$void2(open(url)("_blank")("")(ctx.window))(); + return st; + }; + } + }); + }; + })(toCharArray(str))); + }; + }; + }; + }; + }; + var fg = unions2([link(0)("purple")("white")("twitch.tv/lcolonq")("https://twitch.tv/lcolonq"), link(1)("blue")("white")("twitter.com/lcolonq")("https://twitter.com/lcolonq")]); + var bg = fromFoldable2(concat(flip(map1)(range2(0)(ctx.widthCells))(function(x) { + return flip(map1)(range2(0)(ctx.heightCells))(function(y) { + return new Tuple({ + x, + y + }, { + bg: "white", + fg: "black", + click: pure2, + "char": function() { + var v1 = charAt2(rem(x + y | 0)(length2("LCOLONQ")))("LCOLONQ"); + if (v1 instanceof Nothing) { + return "?"; + } + ; + if (v1 instanceof Just) { + return singleton4(v1.value0); + } + ; + throw new Error("Failed pattern match at Main (line 182, column 12 - line 184, column 39): " + [v1.constructor.name]); + }() + }); + }); + }))); + var cells2 = union2(fg)(bg); + return [{ + cells: cells2, + speed: 20, + cadence: 1, + picker: pickRandom + }]; + }; +}; +var pullEvents = function(dictMonadState) { + var get2 = get(dictMonadState); + var put2 = put(dictMonadState); + return function(dictMonadEffect) { + var Monad0 = dictMonadEffect.Monad0(); + var Bind1 = Monad0.Bind1(); + var bind1 = bind(Bind1); + var liftEffect2 = liftEffect(dictMonadEffect); + var pure22 = pure(Monad0.Applicative0()); + var discard3 = discard2(Bind1); + return function(rc) { + return bind1(liftEffect2(read(rc)))(function(ctx) { + return bind1(get2)(function(st) { + return bind1(function() { + var v = uncons(ctx.events); + if (v instanceof Nothing) { + return pure22(st); + } + ; + if (v instanceof Just) { + return discard3(liftEffect2(write({ + canvas: ctx.canvas, + cellDim: ctx.cellDim, + height: ctx.height, + heightCells: ctx.heightCells, + render: ctx.render, + width: ctx.width, + widthCells: ctx.widthCells, + window: ctx.window, + events: v.value0.tail + })(rc)))(function() { + if (v.value0.head instanceof EventGfx) { + return pure22({ + cells: st.cells, + inverse: st.inverse, + tick: st.tick, + transitions: append3(st.transitions)(gfxTransitions(ctx)(v.value0.head.value0)) + }); + } + ; + if (v.value0.head instanceof EventMouseClick) { + var v1 = lookup2({ + x: v.value0.head.value0, + y: v.value0.head.value1 + })(st.cells); + if (v1 instanceof Nothing) { + return pure22(st); + } + ; + if (v1 instanceof Just) { + return liftEffect2(v1.value0.click(st)); + } + ; + throw new Error("Failed pattern match at Main (line 234, column 11 - line 236, column 53): " + [v1.constructor.name]); + } + ; + if (v.value0.head instanceof EventMouseMove) { + var inv = fromFoldable2(concat(flip(map1)(range2(v.value0.head.value0 - 1 | 0)(v.value0.head.value0 + 1 | 0))(function(x) { + return flip(map1)(range2(v.value0.head.value1 - 1 | 0)(v.value0.head.value1 + 1 | 0))(function(y) { + return new Tuple({ + x, + y + }, st.tick + 30 | 0); + }); + }))); + return pure22({ + cells: st.cells, + tick: st.tick, + transitions: st.transitions, + inverse: union2(inv)(st.inverse) + }); + } + ; + throw new Error("Failed pattern match at Main (line 231, column 7 - line 240, column 53): " + [v.value0.head.constructor.name]); + }); + } + ; + throw new Error("Failed pattern match at Main (line 227, column 10 - line 240, column 53): " + [v.constructor.name]); + }())(function(st$prime) { + return put2(st$prime); + }); + }); + }); + }; + }; +}; +var pullEvents1 = /* @__PURE__ */ pullEvents(monadStateStateT2)(monadEffectState2); +var drawCell = function(ctx) { + return function(st) { + return function(v) { + return function(pos) { + var x = toNumber(pos.x) * ctx.cellDim; + var y = toNumber(pos.y) * ctx.cellDim; + var fg = function() { + var $150 = member2({ + x: pos.x, + y: pos.y + })(st.inverse); + if ($150) { + return v.bg; + } + ; + return v.fg; + }(); + var bg = function() { + var $151 = member2({ + x: pos.x, + y: pos.y + })(st.inverse); + if ($151) { + return v.fg; + } + ; + return v.bg; + }(); + return function __do3() { + setFillStyle(ctx.render)(bg)(); + fillRect(ctx.render)({ + x, + y, + width: ctx.cellDim, + height: ctx.cellDim + })(); + setFillStyle(ctx.render)(fg)(); + return fillText(ctx.render)(v["char"])(x + ctx.cellDim / 4)(y + ctx.cellDim / 1.4)(); + }; + }; + }; + }; +}; +var drawCells = function(ctx) { + return function(st) { + return function(cells2) { + return $$void2($$for2(toUnfoldable2(cells2))(function(v) { + return drawCell(ctx)(st)(v.value1)(v.value0); + })); + }; + }; +}; +var loop2 = function(rc) { + return function(st) { + return function __do3() { + var ctx = read(rc)(); + clearRect(ctx.render)({ + x: 0, + y: 0, + width: ctx.width, + height: ctx.height + })(); + drawCells(ctx)(st)(st.cells)(); + var v = flip(runStateT)(st)(discard22(tick1)(function() { + return discard22(pullEvents1(rc))(function() { + var v2 = head(st.transitions); + if (v2 instanceof Nothing) { + return pure1(unit); + } + ; + if (v2 instanceof Just) { + return when2(rem(st.tick)(v2.value0.cadence) === 0)(void1(for1(range2(0)(v2.value0.speed))(function(v1) { + return pickCell1; + }))); + } + ; + throw new Error("Failed pattern match at Main (line 264, column 5 - line 268, column 58): " + [v2.constructor.name]); + }); + }))(); + return $$void2(requestAnimationFrame(loop2(rc)(v.value1))(ctx.window))(); + }; + }; +}; +var main = function __do2() { + var w = windowImpl(); + (function __do3() { + var v = newContext(); + if (v instanceof Nothing) { + return log2("failed to find canvas")(); + } + ; + if (v instanceof Just) { + var rc = $$new(v.value0)(); + var lresize = eventListener(function(_e) { + return function __do4() { + var v1 = newContext(); + if (v1 instanceof Nothing) { + return log2("failed to find canvas")(); + } + ; + if (v1 instanceof Just) { + return write(v1.value0)(rc)(); + } + ; + throw new Error("Failed pattern match at Main (line 56, column 24 - line 58, column 41): " + [v1.constructor.name]); + }; + })(); + addEventListener("resize")(lresize)(false)(toEventTarget(w))(); + var lmouse = function(h) { + return eventListener(function(e) { + var v1 = fromEvent(e); + if (v1 instanceof Nothing) { + return pure2(unit); + } + ; + if (v1 instanceof Just) { + var px = toNumber(pageX(v1.value0)); + var py = toNumber(pageY(v1.value0)); + return function __do4() { + var ctx = read(rc)(); + return write({ + canvas: ctx.canvas, + cellDim: ctx.cellDim, + height: ctx.height, + heightCells: ctx.heightCells, + render: ctx.render, + width: ctx.width, + widthCells: ctx.widthCells, + window: ctx.window, + events: cons(h(floor2(px / ctx.cellDim))(floor2(py / ctx.cellDim)))(ctx.events) + })(rc)(); + }; + } + ; + throw new Error("Failed pattern match at Main (line 60, column 42 - line 66, column 116): " + [v1.constructor.name]); + }); + }; + var lmouseclick = lmouse(EventMouseClick.create)(); + addEventListener("click")(lmouseclick)(false)(toEventTarget(w))(); + var lmousemove = lmouse(EventMouseMove.create)(); + addEventListener("mousemove")(lmousemove)(false)(toEventTarget(w))(); + return loop2(rc)(initialState)(); + } + ; + throw new Error("Failed pattern match at Main (line 51, column 18 - line 71, column 27): " + [v.constructor.name]); + })(); + return unit; +}; + +// <stdin> +main(); diff --git a/fig-frontend-client/src/Main.purs b/fig-frontend-client/src/Main.purs new file mode 100644 index 0000000..723acd8 --- /dev/null +++ b/fig-frontend-client/src/Main.purs @@ -0,0 +1,269 @@ +module Main where + +import Prelude + +import Control.Monad.State (class MonadState, get, modify_, put, runStateT) +import Data.Array (concat, cons, head, length, mapWithIndex, range, uncons, zip, (!!)) +import Data.Int (ceil, floor, rem, round, toNumber) +import Data.Map (Map, delete, empty, filter, fromFoldable, insert, isEmpty, lookup, member, toUnfoldable, union, unions) +import Data.Maybe (Maybe(..)) +import Data.Set (Set) +import Data.Set as Set +import Data.String.CodeUnits (toCharArray) +import Data.String.CodeUnits as String +import Data.Traversable (for) +import Data.Tuple (Tuple(..)) +import Effect (Effect) +import Effect.Class (class MonadEffect, liftEffect) +import Effect.Console (log) +import Effect.Random (randomInt) +import Effect.Ref (Ref, new, read, write) +import Graphics.Canvas (CanvasElement, Context2D, clearRect, fillRect, fillText, getCanvasElementById, getContext2D, setCanvasDimensions, setFillStyle, setFont) +import Web.Event.Event (EventType(..)) +import Web.Event.EventTarget (addEventListener, eventListener) +import Web.HTML (window) +import Web.HTML.Window (Window, innerHeight, innerWidth, open, requestAnimationFrame) +import Web.HTML.Window as Window +import Web.UIEvent.MouseEvent (fromEvent, pageX, pageY) + +type Context = + { window :: Window + , canvas :: CanvasElement + , render :: Context2D + , width :: Number + , height :: Number + , cellDim :: Number + , widthCells :: Int + , heightCells :: Int + , events :: Array Event + } + +main :: Effect Unit +main = do + -- d <- toDocument <$> document w + -- getElementById "foo" (toNonElementParentNode d) >>= case _ of + -- Nothing -> log "failed to find foo" + -- Just e -> do + -- l <- eventListener \_e -> + -- log "click" + -- addEventListener click l false $ toEventTarget e + w <- window + newContext >>= case _ of + Nothing -> log "failed to find canvas" + Just ictx -> do + rc <- new ictx + lresize <- eventListener \_e -> do + newContext >>= case _ of + Nothing -> log "failed to find canvas" + Just newctx -> write newctx rc + addEventListener (EventType "resize") lresize false $ Window.toEventTarget w + let lmouse h = eventListener \e -> case fromEvent e of + Nothing -> pure unit + Just me -> do + let px = toNumber $ pageX me + let py = toNumber $ pageY me + ctx <- read rc + write (ctx { events = cons (h (floor $ px / ctx.cellDim) (floor $ py / ctx.cellDim)) ctx.events }) rc + lmouseclick <- lmouse EventMouseClick + addEventListener (EventType "click") lmouseclick false $ Window.toEventTarget w + lmousemove <- lmouse EventMouseMove + addEventListener (EventType "mousemove") lmousemove false $ Window.toEventTarget w + loop rc initialState + pure unit + +newContext :: Effect (Maybe Context) +newContext = do + w <- window + getCanvasElementById "lcolonq-canvas" >>= case _ of + Nothing -> pure Nothing + Just canvas -> do + width <- toNumber <$> innerWidth w + height <- toNumber <$> innerHeight w + setCanvasDimensions canvas { width, height } + render <- getContext2D canvas + setFont render "bold 0.8vw Iosevka Comfy" + let widthCells = 100.0 + let cellDim = toNumber $ ceil $ width / widthCells + pure $ Just + { window: w + , canvas + , render + , width + , height + , cellDim + , widthCells: ceil widthCells + , heightCells: ceil $ height / cellDim + , events: [EventGfx GfxWhiteout] + } + +newtype Cell = Cell + { fg :: String + , bg :: String + , char :: String + , click :: State -> Effect State + } + +drawCell :: forall t. Context -> State -> Cell -> { x :: Int, y :: Int | t } -> Effect Unit +drawCell ctx st (Cell c) pos = do + let x = toNumber pos.x * ctx.cellDim + let y = toNumber pos.y * ctx.cellDim + let fg = if member { x: pos.x, y: pos.y } st.inverse then c.bg else c.fg + let bg = if member { x: pos.x, y: pos.y } st.inverse then c.fg else c.bg + setFillStyle ctx.render bg + fillRect ctx.render + { x + , y + , width: ctx.cellDim + , height: ctx.cellDim + } + setFillStyle ctx.render fg + fillText ctx.render c.char (x + ctx.cellDim / 4.0) (y + ctx.cellDim / 1.4) + +type Cells = Map { x :: Int, y :: Int } Cell + +drawCells :: Context -> State -> Cells -> Effect Unit +drawCells ctx st cells = do + void $ for (toUnfoldable cells :: Array _) \(Tuple pos c) -> do + drawCell ctx st c pos + +type Picker = Cells -> Effect (Maybe (Tuple { x :: Int, y :: Int} Cell)) + +pickRandom :: Picker +pickRandom cells = do + let arr = toUnfoldable cells + idx <- randomInt 0 $ length arr - 1 + case arr !! idx of + Nothing -> pure Nothing + Just c -> pure $ Just c + +type Transition = + { cells :: Cells + , speed :: Int + , cadence :: Int + , picker :: Picker + } + +type State = + { tick :: Int + , cells :: Cells + , inverse :: Map { x :: Int, y :: Int } Int + , transitions :: Array Transition + } + +initialState :: State +initialState = + { tick: 0 + , cells: empty + , inverse: empty + , transitions: [] + } + +data Event + = EventGfx Gfx + | EventMouseClick Int Int + | EventMouseMove Int Int + +data Gfx + = GfxWhiteout + +gfxTransitions :: Context -> Gfx -> Array Transition +gfxTransitions ctx GfxWhiteout = + let + bg = fromFoldable $ concat $ flip map (range 0 ctx.widthCells) \x -> + flip map (range 0 ctx.heightCells) \y -> + Tuple + { x, y } + $ Cell + { bg: "white" + , fg: "black" + , click: pure + , char: + let base = "LCOLONQ" + in case String.charAt (rem (x + y) (String.length base)) base of + Nothing -> "?" + Just c -> String.singleton c + } + link :: Int -> String -> String -> String -> String -> Cells + link y fgc bgc str url = + fromFoldable $ mapWithIndex + (\i c -> + Tuple { x: i, y } + $ Cell + { bg: bgc, fg: fgc, char: String.singleton c + , click: \st -> do + void $ open url "_blank" "" ctx.window + pure st + } + ) + $ toCharArray str + fg = + unions + [ link 0 "purple" "white" "twitch.tv/lcolonq" "https://twitch.tv/lcolonq" + , link 1 "blue" "white" "twitter.com/lcolonq" "https://twitter.com/lcolonq" + ] + cells = union fg bg + in + [ { cells + , speed: 20 + , cadence: 1 + , picker: pickRandom + } + ] + +tick :: forall m. MonadState State m => m Unit +tick = modify_ \st -> + st + { tick = st.tick + 1 + , transitions = case uncons st.transitions of + Nothing -> st.transitions + Just { head, tail } -> if isEmpty head.cells then tail else st.transitions + , inverse = filter (st.tick <= _) st.inverse + } + +pullEvents :: forall m. MonadState State m => MonadEffect m => Ref Context -> m Unit +pullEvents rc = do + ctx <- liftEffect $ read rc + st <- get + st' <- case uncons ctx.events of + Nothing -> pure st + Just { head, tail } -> do + liftEffect $ write (ctx { events = tail }) rc + case head of + EventGfx gfx -> pure $ st { transitions = st.transitions <> gfxTransitions ctx gfx } + EventMouseClick mx my -> + case lookup { x: mx, y: my } st.cells of + Nothing -> pure st + Just (Cell c) -> liftEffect $ c.click st + EventMouseMove mx my -> do + let inv = fromFoldable $ concat $ flip map (range (mx - 1) (mx + 1)) \x -> + flip map (range (my - 1) (my + 1)) \y -> Tuple { x, y } (st.tick + 30) + pure st { inverse = union inv st.inverse } + put st' + +pickCell :: forall m. MonadState State m => MonadEffect m => m Unit +pickCell = do + st <- get + case uncons st.transitions of + Nothing -> pure unit + Just { head: trans, tail } -> + liftEffect (trans.picker trans.cells) >>= case _ of + Nothing -> pure unit + Just (Tuple pk pv) -> + put st { cells = insert pk pv st.cells, transitions = cons (trans { cells = (delete pk trans.cells) }) tail } + +loop :: Ref Context -> State -> Effect Unit +loop rc st = do + ctx <- read rc + -- render + clearRect ctx.render { x: 0.0, y: 0.0, width: ctx.width, height: ctx.height } + drawCells ctx st st.cells + -- update + Tuple _ st' <- flip runStateT st do + tick + pullEvents rc + case head st.transitions of + Nothing -> pure unit + Just trans -> do + when (rem st.tick trans.cadence == 0) do + void $ for (range 0 trans.speed) \_ -> pickCell + void $ requestAnimationFrame (loop rc st') ctx.window diff --git a/fig-frontend/client/package-lock.json b/fig-frontend/client/package-lock.json deleted file mode 100644 index ab2278b..0000000 --- a/fig-frontend/client/package-lock.json +++ /dev/null @@ -1,598 +0,0 @@ -{ - "name": "fig-frontend", - "version": "1.0.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "fig-frontend", - "version": "1.0.0", - "dependencies": { - "@adobe/lit-mobx": "^2.2.1", - "interactjs": "^1.10.26", - "lit": "^3.0.0", - "mobx": "^6.12.0" - }, - "devDependencies": { - "esbuild": "^0.17.18", - "typescript": "^5.0.4", - "typescript-formatter": "^7.2.2", - "typescript-language-server": "^4.0.0" - } - }, - "node_modules/@adobe/lit-mobx": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/@adobe/lit-mobx/-/lit-mobx-2.2.1.tgz", - "integrity": "sha512-5CCGIjPkzOG5k1pyJSzpQMhj/BSWy3hzykawtxZ4oM/wItqgEitfxypqHlAIDhfMhhp4J4OlFlqCzbnEL6sYzQ==", - "peerDependencies": { - "lit": "^2.0.0 || ^3.0.0", - "mobx": "^5.0.0 || ^6.0.0" - } - }, - "node_modules/@esbuild/android-arm": { - "version": "0.17.19", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.17.19.tgz", - "integrity": "sha512-rIKddzqhmav7MSmoFCmDIb6e2W57geRsM94gV2l38fzhXMwq7hZoClug9USI2pFRGL06f4IOPHHpFNOkWieR8A==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-arm64": { - "version": "0.17.19", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.17.19.tgz", - "integrity": "sha512-KBMWvEZooR7+kzY0BtbTQn0OAYY7CsiydT63pVEaPtVYF0hXbUaOyZog37DKxK7NF3XacBJOpYT4adIJh+avxA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-x64": { - "version": "0.17.19", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.17.19.tgz", - "integrity": "sha512-uUTTc4xGNDT7YSArp/zbtmbhO0uEEK9/ETW29Wk1thYUJBz3IVnvgEiEwEa9IeLyvnpKrWK64Utw2bgUmDveww==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.17.19", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.17.19.tgz", - "integrity": "sha512-80wEoCfF/hFKM6WE1FyBHc9SfUblloAWx6FJkFWTWiCoht9Mc0ARGEM47e67W9rI09YoUxJL68WHfDRYEAvOhg==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.17.19", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.17.19.tgz", - "integrity": "sha512-IJM4JJsLhRYr9xdtLytPLSH9k/oxR3boaUIYiHkAawtwNOXKE8KoU8tMvryogdcT8AU+Bflmh81Xn6Q0vTZbQw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.17.19", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.19.tgz", - "integrity": "sha512-pBwbc7DufluUeGdjSU5Si+P3SoMF5DQ/F/UmTSb8HXO80ZEAJmrykPyzo1IfNbAoaqw48YRpv8shwd1NoI0jcQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.17.19", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.17.19.tgz", - "integrity": "sha512-4lu+n8Wk0XlajEhbEffdy2xy53dpR06SlzvhGByyg36qJw6Kpfk7cp45DR/62aPH9mtJRmIyrXAS5UWBrJT6TQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm": { - "version": "0.17.19", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.17.19.tgz", - "integrity": "sha512-cdmT3KxjlOQ/gZ2cjfrQOtmhG4HJs6hhvm3mWSRDPtZ/lP5oe8FWceS10JaSJC13GBd4eH/haHnqf7hhGNLerA==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.17.19", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.17.19.tgz", - "integrity": "sha512-ct1Tg3WGwd3P+oZYqic+YZF4snNl2bsnMKRkb3ozHmnM0dGWuxcPTTntAF6bOP0Sp4x0PjSF+4uHQ1xvxfRKqg==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.17.19", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.17.19.tgz", - "integrity": "sha512-w4IRhSy1VbsNxHRQpeGCHEmibqdTUx61Vc38APcsRbuVgK0OPEnQ0YD39Brymn96mOx48Y2laBQGqgZ0j9w6SQ==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.17.19", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.17.19.tgz", - "integrity": "sha512-2iAngUbBPMq439a+z//gE+9WBldoMp1s5GWsUSgqHLzLJ9WoZLZhpwWuym0u0u/4XmZ3gpHmzV84PonE+9IIdQ==", - "cpu": [ - "loong64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.17.19", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.17.19.tgz", - "integrity": "sha512-LKJltc4LVdMKHsrFe4MGNPp0hqDFA1Wpt3jE1gEyM3nKUvOiO//9PheZZHfYRfYl6AwdTH4aTcXSqBerX0ml4A==", - "cpu": [ - "mips64el" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.17.19", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.17.19.tgz", - "integrity": "sha512-/c/DGybs95WXNS8y3Ti/ytqETiW7EU44MEKuCAcpPto3YjQbyK3IQVKfF6nbghD7EcLUGl0NbiL5Rt5DMhn5tg==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.17.19", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.17.19.tgz", - "integrity": "sha512-FC3nUAWhvFoutlhAkgHf8f5HwFWUL6bYdvLc/TTuxKlvLi3+pPzdZiFKSWz/PF30TB1K19SuCxDTI5KcqASJqA==", - "cpu": [ - "riscv64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.17.19", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.17.19.tgz", - "integrity": "sha512-IbFsFbxMWLuKEbH+7sTkKzL6NJmG2vRyy6K7JJo55w+8xDk7RElYn6xvXtDW8HCfoKBFK69f3pgBJSUSQPr+4Q==", - "cpu": [ - "s390x" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-x64": { - "version": "0.17.19", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.17.19.tgz", - "integrity": "sha512-68ngA9lg2H6zkZcyp22tsVt38mlhWde8l3eJLWkyLrp4HwMUr3c1s/M2t7+kHIhvMjglIBrFpncX1SzMckomGw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.17.19", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.17.19.tgz", - "integrity": "sha512-CwFq42rXCR8TYIjIfpXCbRX0rp1jo6cPIUPSaWwzbVI4aOfX96OXY8M6KNmtPcg7QjYeDmN+DD0Wp3LaBOLf4Q==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.17.19", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.17.19.tgz", - "integrity": "sha512-cnq5brJYrSZ2CF6c35eCmviIN3k3RczmHz8eYaVlNasVqsNY+JKohZU5MKmaOI+KkllCdzOKKdPs762VCPC20g==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.17.19", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.17.19.tgz", - "integrity": "sha512-vCRT7yP3zX+bKWFeP/zdS6SqdWB8OIpaRq/mbXQxTGHnIxspRtigpkUcDMlSCOejlHowLqII7K2JKevwyRP2rg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.17.19", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.17.19.tgz", - "integrity": "sha512-yYx+8jwowUstVdorcMdNlzklLYhPxjniHWFKgRqH7IFlUEa0Umu3KuYplf1HUZZ422e3NU9F4LGb+4O0Kdcaag==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.17.19", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.17.19.tgz", - "integrity": "sha512-eggDKanJszUtCdlVs0RB+h35wNlb5v4TWEkq4vZcmVt5u/HiDZrTXe2bWFQUez3RgNHwx/x4sk5++4NSSicKkw==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-x64": { - "version": "0.17.19", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.17.19.tgz", - "integrity": "sha512-lAhycmKnVOuRYNtRtatQR1LPQf2oYCkRGkSFnseDAKPl8lu5SOsK/e1sXe5a0Pc5kHIHe6P2I/ilntNv2xf3cA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@interactjs/types": { - "version": "1.10.26", - "resolved": "https://registry.npmjs.org/@interactjs/types/-/types-1.10.26.tgz", - "integrity": "sha512-DekYpdkMV3XJVd/0k3f4pJluZAsCiG86yEtVXvGLK0lS/Fj0+OzYEv7HoMpcBZSkQ8s7//yaeEBgnxy2tV81lA==" - }, - "node_modules/@lit-labs/ssr-dom-shim": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@lit-labs/ssr-dom-shim/-/ssr-dom-shim-1.1.2.tgz", - "integrity": "sha512-jnOD+/+dSrfTWYfSXBXlo5l5f0q1UuJo3tkbMDCYA2lKUYq79jaxqtGEvnRoh049nt1vdo1+45RinipU6FGY2g==" - }, - "node_modules/@lit/reactive-element": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-2.0.2.tgz", - "integrity": "sha512-SVOwLAWUQg3Ji1egtOt1UiFe4zdDpnWHyc5qctSceJ5XIu0Uc76YmGpIjZgx9YJ0XtdW0Jm507sDvjOu+HnB8w==", - "dependencies": { - "@lit-labs/ssr-dom-shim": "^1.1.2" - } - }, - "node_modules/@types/trusted-types": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", - "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==" - }, - "node_modules/commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true - }, - "node_modules/commandpost": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/commandpost/-/commandpost-1.4.0.tgz", - "integrity": "sha512-aE2Y4MTFJ870NuB/+2z1cXBhSBBzRydVVjzhFC4gtenEhpnj15yu0qptWGJsO9YGrcPZ3ezX8AWb1VA391MKpQ==", - "dev": true - }, - "node_modules/editorconfig": { - "version": "0.15.3", - "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-0.15.3.tgz", - "integrity": "sha512-M9wIMFx96vq0R4F+gRpY3o2exzb8hEj/n9S8unZtHSvYjibBp/iMufSzvmOcV/laG0ZtuTVGtiJggPOSW2r93g==", - "dev": true, - "dependencies": { - "commander": "^2.19.0", - "lru-cache": "^4.1.5", - "semver": "^5.6.0", - "sigmund": "^1.0.1" - }, - "bin": { - "editorconfig": "bin/editorconfig" - } - }, - "node_modules/esbuild": { - "version": "0.17.19", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.17.19.tgz", - "integrity": "sha512-XQ0jAPFkK/u3LcVRcvVHQcTIqD6E2H1fvZMA5dQPSOWb3suUbWbfbRf94pjc0bNzRYLfIrDRQXr7X+LHIm5oHw==", - "dev": true, - "hasInstallScript": true, - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=12" - }, - "optionalDependencies": { - "@esbuild/android-arm": "0.17.19", - "@esbuild/android-arm64": "0.17.19", - "@esbuild/android-x64": "0.17.19", - "@esbuild/darwin-arm64": "0.17.19", - "@esbuild/darwin-x64": "0.17.19", - "@esbuild/freebsd-arm64": "0.17.19", - "@esbuild/freebsd-x64": "0.17.19", - "@esbuild/linux-arm": "0.17.19", - "@esbuild/linux-arm64": "0.17.19", - "@esbuild/linux-ia32": "0.17.19", - "@esbuild/linux-loong64": "0.17.19", - "@esbuild/linux-mips64el": "0.17.19", - "@esbuild/linux-ppc64": "0.17.19", - "@esbuild/linux-riscv64": "0.17.19", - "@esbuild/linux-s390x": "0.17.19", - "@esbuild/linux-x64": "0.17.19", - "@esbuild/netbsd-x64": "0.17.19", - "@esbuild/openbsd-x64": "0.17.19", - "@esbuild/sunos-x64": "0.17.19", - "@esbuild/win32-arm64": "0.17.19", - "@esbuild/win32-ia32": "0.17.19", - "@esbuild/win32-x64": "0.17.19" - } - }, - "node_modules/interactjs": { - "version": "1.10.26", - "resolved": "https://registry.npmjs.org/interactjs/-/interactjs-1.10.26.tgz", - "integrity": "sha512-5gNTNDTfEHp2EifqtWGi5VkD3CMZVJSTGmtK/IsVRd+rkOk3E63iVs5Z+IeD5K1Lr0qZpU2754VHAwf5i+Z9xg==", - "dependencies": { - "@interactjs/types": "1.10.26" - } - }, - "node_modules/lit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/lit/-/lit-3.1.0.tgz", - "integrity": "sha512-rzo/hmUqX8zmOdamDAeydfjsGXbbdtAFqMhmocnh2j9aDYqbu0fjXygjCa0T99Od9VQ/2itwaGrjZz/ZELVl7w==", - "dependencies": { - "@lit/reactive-element": "^2.0.0", - "lit-element": "^4.0.0", - "lit-html": "^3.1.0" - } - }, - "node_modules/lit-element": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-4.0.2.tgz", - "integrity": "sha512-/W6WQZUa5VEXwC7H9tbtDMdSs9aWil3Ou8hU6z2cOKWbsm/tXPAcsoaHVEtrDo0zcOIE5GF6QgU55tlGL2Nihg==", - "dependencies": { - "@lit-labs/ssr-dom-shim": "^1.1.2", - "@lit/reactive-element": "^2.0.0", - "lit-html": "^3.1.0" - } - }, - "node_modules/lit-html": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-3.1.0.tgz", - "integrity": "sha512-FwAjq3iNsaO6SOZXEIpeROlJLUlrbyMkn4iuv4f4u1H40Jw8wkeR/OUXZUHUoiYabGk8Y4Y0F/rgq+R4MrOLmA==", - "dependencies": { - "@types/trusted-types": "^2.0.2" - } - }, - "node_modules/lru-cache": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", - "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", - "dev": true, - "dependencies": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" - } - }, - "node_modules/mobx": { - "version": "6.12.0", - "resolved": "https://registry.npmjs.org/mobx/-/mobx-6.12.0.tgz", - "integrity": "sha512-Mn6CN6meXEnMa0a5u6a5+RKrqRedHBhZGd15AWLk9O6uFY4KYHzImdt8JI8WODo1bjTSRnwXhJox+FCUZhCKCQ==", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mobx" - } - }, - "node_modules/pseudomap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==", - "dev": true - }, - "node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/sigmund": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", - "integrity": "sha512-fCvEXfh6NWpm+YSuY2bpXb/VIihqWA6hLsgboC+0nl71Q7N7o2eaCW8mJa/NLvQhs6jpd3VZV4UiUQlV6+lc8g==", - "dev": true - }, - "node_modules/typescript": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", - "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==", - "dev": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/typescript-formatter": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/typescript-formatter/-/typescript-formatter-7.2.2.tgz", - "integrity": "sha512-V7vfI9XArVhriOTYHPzMU2WUnm5IMdu9X/CPxs8mIMGxmTBFpDABlbkBka64PZJ9/xgQeRpK8KzzAG4MPzxBDQ==", - "dev": true, - "dependencies": { - "commandpost": "^1.0.0", - "editorconfig": "^0.15.0" - }, - "bin": { - "tsfmt": "bin/tsfmt" - }, - "engines": { - "node": ">= 4.2.0" - }, - "peerDependencies": { - "typescript": "^2.1.6 || >=2.7.0-dev || >=2.8.0-dev || >=2.9.0-dev || >=3.0.0-dev" - } - }, - "node_modules/typescript-language-server": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/typescript-language-server/-/typescript-language-server-4.2.0.tgz", - "integrity": "sha512-1yKDqKeWLTQkN4mN+CT84aBr7ckp6sNVb8DZg+eXl0TDl14edn6Yh1wPqPA1rQ4AGVJc02fYbXTFsklaVYy4Uw==", - "dev": true, - "bin": { - "typescript-language-server": "lib/cli.mjs" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==", - "dev": true - } - } -} diff --git a/fig-frontend/client/package.json b/fig-frontend/client/package.json deleted file mode 100644 index 2812cd4..0000000 --- a/fig-frontend/client/package.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "name": "fig-frontend", - "version": "1.0.0", - "scripts": { - "build": "esbuild src/index.ts --loader:.jpg=file --outdir=../../fig-frontend-assets/js --bundle --minify" - }, - "dependencies": { - "@adobe/lit-mobx": "^2.2.1", - "interactjs": "^1.10.26", - "lit": "^3.0.0", - "mobx": "^6.12.0" - }, - "devDependencies": { - "esbuild": "^0.17.18", - "typescript": "^5.0.4", - "typescript-formatter": "^7.2.2", - "typescript-language-server": "^4.0.0" - } -} diff --git a/fig-frontend/client/src/assets/blueprint.jpg b/fig-frontend/client/src/assets/blueprint.jpg Binary files differdeleted file mode 100644 index 6efe89d..0000000 --- a/fig-frontend/client/src/assets/blueprint.jpg +++ /dev/null diff --git a/fig-frontend/client/src/components/backdrop.ts b/fig-frontend/client/src/components/backdrop.ts deleted file mode 100644 index d35d205..0000000 --- a/fig-frontend/client/src/components/backdrop.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { html, css, LitElement, unsafeCSS } from "lit"; -import { customElement } from "lit/decorators.js"; - -import * as Config from "../config"; - -import blueprint from "../assets/blueprint.jpg"; - -@customElement("fig-backdrop") -export class Backdrop extends LitElement { - static styles = css` -#backdrop { - z-index: -2; - position: absolute; - left: 0px; - top: 0px; - width: 100vw; - height: 100vh; - background-image: url("${unsafeCSS(new URL(blueprint, Config.SCRIPT_URL))}"); -} -#blur { - z-index: -1; - backdrop-filter: blur(3px); - position: absolute; - left: 0px; - top: 0px; - width: 100vw; - height: 100vh; - background-size: 100px 100px; - background-position: -20px -20px; - background-image: - linear-gradient(to right, lightgrey 1px, transparent 1px), - linear-gradient(to bottom, lightgrey 1px, transparent 1px); -} -`; - render() { - return html` -<div id="backdrop"></div> -<div id="blur"></div> -`; - } -} diff --git a/fig-frontend/client/src/components/footer.ts b/fig-frontend/client/src/components/footer.ts deleted file mode 100644 index 64e35ae..0000000 --- a/fig-frontend/client/src/components/footer.ts +++ /dev/null @@ -1,72 +0,0 @@ -import { html, css, LitElement } from "lit"; -import { customElement, state } from "lit/decorators.js"; - -import * as Config from "../config"; -import * as State from "../state"; -import * as Twitch from "../twitch"; - -@customElement("fig-footer") -export class Footer extends LitElement { - private global = State.global; - static styles = css` -#footer { - position: absolute; - bottom: 0px; - left: 0px; - right: 0px; - height: 4ex; - background: linear-gradient(0deg, rgba(79,39,0,1) 0%, rgba(212,151,113,1) 50%, rgba(213,139,45,1) 100%); -} -button { - font-family: "Rubik Maps"; - height: 100%; - color: black; - border-style: none; - background: linear-gradient(0deg, rgba(79,39,0,1) 0%, rgba(212,151,113,1) 50%, rgba(213,139,45,1) 100%); - filter: brightness(125%); -} -button:hover { - filter: brightness(150%); -} -button:active { - filter: brightness(75%); -} -`; - - // twitch login - login() { - Twitch.startTwitchAuth(); - } - async check() { - const resp = await fetch(`${Config.API_URL}/check`); - console.log(await resp.text()); - } - button_login() { - const token = Twitch.getAuthToken(); - console.log(token); - if (token) { - return html` -<button @click=${this.check}>CHECK</button> -`; - } else { - return html` -<button @click=${this.login}>LOGIN</button> -`; - } - } - - // toggle gizmo pane - toggle_gizmo() { - console.log(this.global.gizmo_active); - this.global.toggle_gizmo(); - } - - render() { - return html` -<div id="footer"> - ${this.button_login()} - <button @click=${this.toggle_gizmo}>GIZMO</button> -</div> -`; - } -} diff --git a/fig-frontend/client/src/components/gizmo.ts b/fig-frontend/client/src/components/gizmo.ts deleted file mode 100644 index bd1285c..0000000 --- a/fig-frontend/client/src/components/gizmo.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { MobxLitElement } from "@adobe/lit-mobx"; -import { html, css } from "lit"; -import { customElement } from "lit/decorators.js"; - -import * as State from "../state"; - -@customElement("fig-gizmo") -export class Gizmo extends MobxLitElement { - private global = State.global; - - static style = css` -`; - - static get(id: string): Gizmo | null { - const e = document.getElementById(id); - if (e instanceof Gizmo) return e; - return null; - } - - constructor() { - super(); - } - - render() { - console.log("render", this.global.gizmo_active); - if (this.global.gizmo_active) { - return html` -<fig-window> -<h1>hi</h1> -</fig-window> -`; - } - } -} diff --git a/fig-frontend/client/src/components/globals.d.ts b/fig-frontend/client/src/components/globals.d.ts deleted file mode 100644 index 65e20c0..0000000 --- a/fig-frontend/client/src/components/globals.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -declare module "*.png"; -declare module "*.jpg"; diff --git a/fig-frontend/client/src/components/header.ts b/fig-frontend/client/src/components/header.ts deleted file mode 100644 index c4c709f..0000000 --- a/fig-frontend/client/src/components/header.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { html, css, LitElement } from "lit"; -import { customElement } from "lit/decorators.js"; - -@customElement("fig-header") -export class Header extends LitElement { - static styles = css` -#header { - position: absolute; - text-align: center; - border-radius: 100px; - border-style: solid; - border-color: silver; - border-width: 5px; - background: linear-gradient(0deg, rgba(89,89,89,1) 35%, rgba(158,158,158,1) 100%); - top: 1em; - left: 33vw; - width: 33vw; -} -#header:hover { - filter: brightness(150%); -} -h1 { - color: #b5a642; - font-family: "Rubik Maps"; -} -`; - render() { - return html` -<div id="header"> - <h1>"The JunkYard"</h1> -</div> -`; - } -} diff --git a/fig-frontend/client/src/components/login.ts b/fig-frontend/client/src/components/login.ts deleted file mode 100644 index 195c97f..0000000 --- a/fig-frontend/client/src/components/login.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { html, css, LitElement } from "lit"; -import { customElement } from "lit/decorators.js"; - -import * as Config from "../config"; -import * as Twitch from "../twitch"; - -@customElement("fig-login") -export class Login extends LitElement { - static styles = css` - `; - - login() { - Twitch.startTwitchAuth(); - } - - async check() { - const resp = await fetch(`${Config.API_URL}/check`); - console.log(await resp.text()); - } - - render() { - const token = Twitch.getAuthToken(); - console.log(token); - if (token) { - return html` -<button @click=${this.check}>check token</button> -`; - } else { - return html` -<button @click=${this.login}>login</button> -`; - } - } -} diff --git a/fig-frontend/client/src/components/window.ts b/fig-frontend/client/src/components/window.ts deleted file mode 100644 index 9a8f93a..0000000 --- a/fig-frontend/client/src/components/window.ts +++ /dev/null @@ -1,130 +0,0 @@ -import { html, css, LitElement } from "lit"; -import { customElement, property } from "lit/decorators.js"; - -import interact from "interactjs"; - -@customElement("fig-window") -export class Window extends LitElement { - static z: number = 0; - - x: number; - y: number; - - @property() - title: string; - - @property() - hidden: boolean; - - static styles = css` -#windowcontainer { - z-index: 0; - position: relative; - width: 100%; - height: 100%; - display: grid; - grid-template-columns: auto; - grid-template-rows: 4ex 1fr; - user-select: none; -} -#title { - font-family: "Rubik Maps"; - font-size: 150%; - color: black; - grid-column: 1; - grid-row: 1; - height: 2.2ex; - overflow: hidden; - z-index: 2; - margin-bottom: -1ex; - background: linear-gradient(0deg, rgba(89,89,89,1) 35%, rgba(158,158,158,1) 100%); - border-radius: 100px; - border-style: solid; - border-color: silver; - border-width: 5px; - text-align: center; -} -#window { - overflow: hidden; - grid-column: 1; - grid-row-start: 2; - grid-row-end: 2; - z-index: 1; - background-color: white; - border-radius: 5ex; - border-style: solid; - border-color: black; - border-width: 2px; - border-top-width: 0px; - padding-top: 1ex; - padding-left: 2ex; - padding-right: 2ex; -} -`; - - static get(id: string): Window | null { - const e = document.getElementById(id); - if (e instanceof Window) return e; - return null; - } - - constructor() { - super(); - this.x = 0; - this.y = 0; - this.style.left = `${this.x}px` - this.style.top = `${this.y}px` - this.style.width = "300px" - this.style.height = "300px" - interact(this).draggable({ - allowFrom: "#title", - modifiers: [ - interact.modifiers.restrict({ - restriction: "body", - endOnly: true - }) - ], - listeners: { - move(event) { - event.target.x += event.dx - event.target.y += event.dy - event.target.style.left = `${event.target.x}px` - event.target.style.top = `${event.target.y}px` - }, - } - }).resizable({ - edges: { top: false, bottom: true, left: true, right: true }, - listeners: { - move(event) { - event.target.x += event.deltaRect.left - event.target.y += event.deltaRect.top - event.target.style.left = `${event.target.x}px` - event.target.style.top = `${event.target.y}px` - event.target.style.width = `${Math.max(event.rect.width, 300)}px` - event.target.style.height = `${Math.max(event.rect.height, 300)}px` - }, - }, - }); - } - - toggle() { - this.hidden = !this.hidden; - } - - click() { - this.style.zIndex = `${++Window.z}`; - } - - render() { - if (!this.hidden) { - return html` -<div id="windowcontainer" @pointerdown=${this.click}> - <div id="title">${this.title}</slot></div> - <div id="window"> - <slot></slot> - </div> -</div> -`; - } - } -} diff --git a/fig-frontend/client/src/config.ts b/fig-frontend/client/src/config.ts deleted file mode 100644 index e001107..0000000 --- a/fig-frontend/client/src/config.ts +++ /dev/null @@ -1,4 +0,0 @@ -export const URL = "http://localhost:8000"; -export const API_URL = `${URL}/api/`; -export const SCRIPT_URL = `${URL}/js/`; -export const CLIENT_ID = "q486jugzn2my4iw6l181o006ugye4j"; diff --git a/fig-frontend/client/src/index.css b/fig-frontend/client/src/index.css deleted file mode 100644 index b1c8427..0000000 --- a/fig-frontend/client/src/index.css +++ /dev/null @@ -1,14 +0,0 @@ -body { - margin: 0px; - position: absolute; - left: 0px; - top: 0px; - width: 100vw; - height: 100vh; - overflow: hidden; -} - -fig-window { - display: block; - position: absolute; -} diff --git a/fig-frontend/client/src/index.ts b/fig-frontend/client/src/index.ts deleted file mode 100644 index be0b0c5..0000000 --- a/fig-frontend/client/src/index.ts +++ /dev/null @@ -1,10 +0,0 @@ -import "./components/backdrop"; -import "./components/header"; -import "./components/footer"; -import "./components/login"; -import "./components/window"; -import "./components/gizmo"; - -import "./index.css"; - -console.log("welcome to \"the junkyard\""); diff --git a/fig-frontend/client/src/state.ts b/fig-frontend/client/src/state.ts deleted file mode 100644 index 19bc5d9..0000000 --- a/fig-frontend/client/src/state.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { observable, action } from 'mobx'; - -class Global { - @observable - public gizmo_active: boolean = true; - - @action - public toggle_gizmo() { - this.gizmo_active = !this.gizmo_active; - } -} - -export const global = new Global(); diff --git a/fig-frontend/client/src/twitch.ts b/fig-frontend/client/src/twitch.ts deleted file mode 100644 index 4c264be..0000000 --- a/fig-frontend/client/src/twitch.ts +++ /dev/null @@ -1,43 +0,0 @@ -import * as Config from "./config"; - -function generateNonce(): string { - var arr = new Uint8Array(20); - window.crypto.getRandomValues(arr); - return Array.from(arr, b => b.toString(16).padStart(2, "0")).join(""); -} - -export function startTwitchAuth() { - const nonce = generateNonce(); - document.cookie = `authnonce=${nonce}; path=/;`; - window.location.href = - `https://id.twitch.tv/oauth2/authorize?response_type=id_token` - + `&client_id=${Config.CLIENT_ID}` - + `&redirect_uri=${Config.URL}` - + `&scope=openid` - + `&nonce=${nonce}` - + `&claims=${{id_token: {preferred_username: null}}}` - ; -} - -export function getFragmentQuery(): Map<string, string> { - let query = new Map(); - const hashQuery = document.location.hash.slice(1).split("&"); - for (let equals of hashQuery) { - const pair = equals.split("="); - query.set(decodeURIComponent(pair[0]), decodeURIComponent(pair[1])); - } - return query; -} - -export function getAuthToken(): String | null { - const frag = getFragmentQuery(); - const token = frag.get("id_token"); - if (token) { - document.cookie = `id_token=${token}; path=/; SameSite=Strict`; - } - for (let c of document.cookie.split("; ")) { - const [k, v] = c.split("="); - if (k === "id_token") return v; - } - return null; -} diff --git a/fig-frontend/client/tsconfig.json b/fig-frontend/client/tsconfig.json deleted file mode 100644 index d529f64..0000000 --- a/fig-frontend/client/tsconfig.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "compilerOptions": { - "rootDir": "./src", - "module": "esnext", - "moduleResolution": "node", - "target": "es6", - "lib": ["ESNext", "dom"], - "skipLibCheck": true, - "useDefineForClassFields": false, - "experimentalDecorators": true, - "strictPropertyInitialization": false, - "noImplicitAny": true, - "strictNullChecks": true, - "removeComments": true, - "preserveConstEnums": true, - "sourceMap": true - } -} diff --git a/fig-frontend/src/Fig/Frontend.hs b/fig-frontend/src/Fig/Frontend.hs index b1c6aed..fd2754c 100644 --- a/fig-frontend/src/Fig/Frontend.hs +++ b/fig-frontend/src/Fig/Frontend.hs @@ -6,7 +6,7 @@ import Control.Lens (use) import Data.Text (toLower) --- import qualified Network.Wai.Middleware.Static as Wai.Static +import qualified Network.Wai.Middleware.Static as Wai.Static import qualified Network.Wai.Handler.Warp as Warp import qualified Web.Twain as Tw @@ -36,16 +36,19 @@ app cfg = do st <- stateRef pure $ foldr' @[] ($) (Tw.notFound . Tw.send $ Tw.text "not found") - -- [ Wai.Static.staticPolicy $ Wai.Static.addBase cfg.assetPath - [ Tw.get "/" - . Tw.send . Tw.html - . L.renderBS - $ L.doctypehtml_ do - L.head_ do - L.title_ "clonk zone api home page" - L.link_ [L.rel_ "icon", L.href_ "data:;base64,iVBORw0KGgo="] - L.body_ do - "hello" + [ Wai.Static.staticPolicy $ Wai.Static.addBase cfg.assetPath + -- , Tw.get "/" + -- . Tw.send . Tw.html + -- . L.renderBS + -- $ L.doctypehtml_ do + -- L.head_ do + -- L.title_ "clonk zone api home page" + -- L.link_ [L.rel_ "icon", L.href_ "data:;base64,iVBORw0KGgo="] + -- L.link_ [L.rel_ "stylesheet", L.href_ "main.css"] + -- L.script_ [L.type_ "module", L.src_ "main.js"] ("" :: L.Html ()) + -- L.body_ do + -- L.button_ [L.id_ "foo"] do + -- "hello" , Tw.get "/api/check" $ authed cfg \auth -> do Tw.send $ Tw.json @[Text] [auth.id, auth.name] , Tw.put "/api/buffer" do diff --git a/fig-monitor-bullfrog/fig-monitor-bullfrog.cabal b/fig-monitor-bullfrog/fig-monitor-bullfrog.cabal index 2d06268..0cc111e 100644 --- a/fig-monitor-bullfrog/fig-monitor-bullfrog.cabal +++ b/fig-monitor-bullfrog/fig-monitor-bullfrog.cabal @@ -25,7 +25,6 @@ common deps , mtl , network , safe-exceptions - , scotty , text , time , tomland @@ -52,4 +51,4 @@ executable fig-monitor-bullfrog build-depends: fig-monitor-bullfrog, optparse-applicative hs-source-dirs: main - main-is: Main.hs
\ No newline at end of file + main-is: Main.hs diff --git a/fig-monitor-twitch/fig-monitor-twitch.cabal b/fig-monitor-twitch/fig-monitor-twitch.cabal index b177d32..5c63bc5 100644 --- a/fig-monitor-twitch/fig-monitor-twitch.cabal +++ b/fig-monitor-twitch/fig-monitor-twitch.cabal @@ -25,7 +25,6 @@ common deps , mtl , network , safe-exceptions - , scotty , text , time , tomland @@ -55,4 +54,4 @@ executable fig-monitor-twitch build-depends: fig-monitor-twitch, optparse-applicative hs-source-dirs: main - main-is: Main.hs
\ No newline at end of file + main-is: Main.hs @@ -1,24 +1,290 @@ { "nodes": { + "docs-search": { + "flake": false, + "locked": { + "lastModified": 1675992564, + "narHash": "sha256-Tk9VSogFHXtXe9O9vuCEfM/PV/S7plMIO0I++fCZn7U=", + "owner": "purs-nix", + "repo": "purescript-docs-search", + "rev": "35822b1d6ce65b1a07f80dd9e2caf15c3ee83e2c", + "type": "github" + }, + "original": { + "owner": "purs-nix", + "repo": "purescript-docs-search", + "type": "github" + } + }, + "flake-utils": { + "locked": { + "lastModified": 1644229661, + "narHash": "sha256-1YdnJAsNy69bpcjuoKdOYQX0YxZBiCYZo4Twxerqv7k=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "3cecb5b042f7f209c56ffd8371b2711a290ec797", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_2": { + "locked": { + "lastModified": 1618217525, + "narHash": "sha256-WGrhVczjXTiswQaoxQ+0PTfbLNeOQM6M36zvLn78AYg=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "c6169a2772643c4a93a0b5ac1c61e296cba68544", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_3": { + "locked": { + "lastModified": 1618217525, + "narHash": "sha256-WGrhVczjXTiswQaoxQ+0PTfbLNeOQM6M36zvLn78AYg=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "c6169a2772643c4a93a0b5ac1c61e296cba68544", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "get-flake": { + "locked": { + "lastModified": 1644686428, + "narHash": "sha256-zkhYsURWFrvEZLkIoBeqFBzSu+cA2u5mo6M8vq9LN7M=", + "owner": "ursi", + "repo": "get-flake", + "rev": "703f15558daa56dfae19d1858bb3046afe68831a", + "type": "github" + }, + "original": { + "owner": "ursi", + "repo": "get-flake", + "type": "github" + } + }, + "lint-utils": { + "inputs": { + "flake-utils": "flake-utils", + "nixpkgs": [ + "purs-nix", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1707777931, + "narHash": "sha256-PsPb5xMBZ9dPDP04o9vqKEUIEG80Z84/74fPuOMs0ZI=", + "owner": "homotopic", + "repo": "lint-utils", + "rev": "5f11e3e51d8f1aa4ed62a89e90f05953931e105a", + "type": "github" + }, + "original": { + "owner": "homotopic", + "repo": "lint-utils", + "type": "github" + } + }, + "make-shell": { + "locked": { + "lastModified": 1634940815, + "narHash": "sha256-P69OmveboXzS+es1vQGS4bt+ckwbeIExqxfGLjGuJqA=", + "owner": "ursi", + "repo": "nix-make-shell", + "rev": "8add91681170924e4d0591b22f294aee3f5516f9", + "type": "github" + }, + "original": { + "owner": "ursi", + "ref": "1", + "repo": "nix-make-shell", + "type": "github" + } + }, + "make-shell_2": { + "locked": { + "lastModified": 1634940815, + "narHash": "sha256-P69OmveboXzS+es1vQGS4bt+ckwbeIExqxfGLjGuJqA=", + "owner": "ursi", + "repo": "nix-make-shell", + "rev": "8add91681170924e4d0591b22f294aee3f5516f9", + "type": "github" + }, + "original": { + "owner": "ursi", + "ref": "1", + "repo": "nix-make-shell", + "type": "github" + } + }, "nixpkgs": { "locked": { - "lastModified": 1696697597, - "narHash": "sha256-q26Qv4DQ+h6IeozF2o1secyQG0jt2VUT3V0K58jr3pg=", + "lastModified": 1708815994, + "narHash": "sha256-hL7N/ut2Xu0NaDxDMsw2HagAjgDskToGiyZOWriiLYM=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "5a237aecb57296f67276ac9ab296a41c23981f56", + "rev": "9a9dae8f6319600fa9aebde37f340975cab4b8c0", "type": "github" }, "original": { "owner": "NixOS", - "ref": "nixos-23.05", + "ref": "nixpkgs-unstable", "repo": "nixpkgs", "type": "github" } }, + "nixpkgs_2": { + "locked": { + "lastModified": 1704161960, + "narHash": "sha256-QGua89Pmq+FBAro8NriTuoO/wNaUtugt29/qqA8zeeM=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "63143ac2c9186be6d9da6035fa22620018c85932", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_3": { + "locked": { + "lastModified": 1656549732, + "narHash": "sha256-eILutFZGjfk2bEzfim8S/qyYc//0S1KsCeO+OWbtoR0=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "d3248619647234b5dc74a6921bcdf6dd8323eb22", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "parsec": { + "locked": { + "lastModified": 1635533376, + "narHash": "sha256-/HrG0UPGnI5VdkhrNrpDiM2+nhdL6lD/bqyGtYv0QDE=", + "owner": "nprindle", + "repo": "nix-parsec", + "rev": "1bf25dd9c5de1257a1c67de3c81c96d05e8beb5e", + "type": "github" + }, + "original": { + "owner": "nprindle", + "repo": "nix-parsec", + "type": "github" + } + }, + "ps-tools": { + "inputs": { + "make-shell": "make-shell_2", + "nixpkgs": "nixpkgs_3", + "utils": "utils" + }, + "locked": { + "lastModified": 1704567308, + "narHash": "sha256-WbFPIkKLtyQOPBUjintckKIYnfs7MvIbmfVsLRSAPlc=", + "owner": "purs-nix", + "repo": "purescript-tools", + "rev": "ac626313141cbee78f06eb3c5e90359f695aef9b", + "type": "github" + }, + "original": { + "owner": "purs-nix", + "repo": "purescript-tools", + "type": "github" + } + }, + "purs-nix": { + "inputs": { + "docs-search": "docs-search", + "get-flake": "get-flake", + "lint-utils": "lint-utils", + "make-shell": "make-shell", + "nixpkgs": "nixpkgs_2", + "parsec": "parsec", + "ps-tools": "ps-tools", + "utils": "utils_2" + }, + "locked": { + "lastModified": 1707933489, + "narHash": "sha256-LP05KSBQ02mgBDiVdW53h9ViFBtFQIo4dT3FCebucI0=", + "owner": "purs-nix", + "repo": "purs-nix", + "rev": "72c9a8b7df0e53ff8b24fef00d9ea74d3a5b6522", + "type": "github" + }, + "original": { + "owner": "purs-nix", + "ref": "ps-0.15", + "repo": "purs-nix", + "type": "github" + } + }, "root": { "inputs": { - "nixpkgs": "nixpkgs" + "nixpkgs": "nixpkgs", + "ps-tools": [ + "purs-nix", + "ps-tools" + ], + "purs-nix": "purs-nix" + } + }, + "utils": { + "inputs": { + "flake-utils": "flake-utils_2" + }, + "locked": { + "lastModified": 1656044990, + "narHash": "sha256-f01BB7CaOyntOab9XnpH9HD63rGcnu2iyL4M2ubs5F8=", + "owner": "ursi", + "repo": "flake-utils", + "rev": "f53b674a2c90f6202a2f4cd491aba121775490b5", + "type": "github" + }, + "original": { + "owner": "ursi", + "ref": "8", + "repo": "flake-utils", + "type": "github" + } + }, + "utils_2": { + "inputs": { + "flake-utils": "flake-utils_3" + }, + "locked": { + "lastModified": 1656044990, + "narHash": "sha256-f01BB7CaOyntOab9XnpH9HD63rGcnu2iyL4M2ubs5F8=", + "owner": "ursi", + "repo": "flake-utils", + "rev": "f53b674a2c90f6202a2f4cd491aba121775490b5", + "type": "github" + }, + "original": { + "owner": "ursi", + "ref": "8", + "repo": "flake-utils", + "type": "github" } } }, @@ -1,12 +1,20 @@ { description = "fig"; - inputs.nixpkgs.url = github:NixOS/nixpkgs/nixos-23.05; + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; + ps-tools.follows = "purs-nix/ps-tools"; + purs-nix.url = "github:purs-nix/purs-nix/ps-0.15"; + }; - outputs = { self, nixpkgs }: + outputs = { self, nixpkgs, ... }@inputs: let - pkgs = nixpkgs.legacyPackages.x86_64-linux; - overrides = self: super: { + system = "x86_64-linux"; + pkgs = nixpkgs.legacyPackages.${system}; + ps-tools = inputs.ps-tools.legacyPackages.${system}; + purs-nix = inputs.purs-nix { inherit system; }; + + haskellOverrides = self: super: { discord-haskell = self.callCabal2nix "discord-haskell" ./deps/discord-haskell {}; irc-conduit = self.callCabal2nix "irc-conduit" ./deps/irc-conduit {}; irc-client = self.callCabal2nix "irc-client" ./deps/irc-client {}; @@ -20,11 +28,26 @@ fig-frontend = self.callCabal2nix "fig-frontend" ./fig-frontend {}; }; haskellPackages = pkgs.haskell.packages.ghc94.override { - inherit overrides; + overrides = haskellOverrides; }; - # haskellPackagesStatic = pkgs.pkgsStatic.haskell.packages.ghc94.override { - # inherit overrides; - # }; + + purescript = purs-nix.purs { + dependencies = [ + "console" + "effect" + "prelude" + "random" + "refs" + "web-html" + "web-dom" + "web-uievents" + "canvas" + ]; + dir = ./fig-frontend-client; + srcs = [ "src" ]; + }; + fig-frontend-client = purescript.bundle {}; + figBusModule = { config, lib, ... }: let cfg = config.colonq.services.fig-bus; @@ -233,6 +256,11 @@ withHoogle = true; buildInputs = [ haskellPackages.haskell-language-server + pkgs.nodejs + (purescript.command {}) + ps-tools.for-0_15.purescript-language-server + purs-nix.esbuild + purs-nix.purescript ]; }; packages.x86_64-linux = { |
