├── .formatter.exs
├── .gitignore
├── .vscode
└── settings.json
├── README.md
├── ants.gif
├── assets
├── .gitignore
├── .prettierignore
├── .prettierrc
├── README.md
├── bsconfig.json
├── index.js
├── lib
│ └── js
│ │ └── src
│ │ ├── components
│ │ ├── AntIcon.bs.js
│ │ ├── MainComponent.bs.js
│ │ ├── NotFoundComponent.bs.js
│ │ ├── SimComponent.bs.js
│ │ ├── SimStartComponent.bs.js
│ │ ├── TileComponent.bs.js
│ │ ├── TodoAppComponent.bs.js
│ │ ├── TodoInputComponent.bs.js
│ │ ├── TodoItemComponent.bs.js
│ │ └── WorldComponent.bs.js
│ │ ├── domain
│ │ ├── Knobs.bs.js
│ │ ├── KnobsResponse.bs.js
│ │ ├── SimId.bs.js
│ │ ├── SimResponse.bs.js
│ │ ├── Tile.bs.js
│ │ ├── TileResponse.bs.js
│ │ ├── TodoItem.bs.js
│ │ └── World.bs.js
│ │ └── lib
│ │ ├── Http.bs.js
│ │ └── Utils.bs.js
├── package.json
├── src
│ ├── components
│ │ ├── AntIcon.re
│ │ ├── MainComponent.re
│ │ ├── NotFoundComponent.re
│ │ ├── SimComponent.re
│ │ ├── SimStartComponent.re
│ │ ├── TileComponent.re
│ │ └── WorldComponent.re
│ ├── domain
│ │ ├── Knobs.re
│ │ ├── KnobsResponse.re
│ │ ├── SimId.re
│ │ ├── SimResponse.re
│ │ ├── Tile.re
│ │ ├── TileResponse.re
│ │ └── World.re
│ └── lib
│ │ ├── Http.re
│ │ └── Utils.re
├── static
│ ├── favicon.ico
│ └── robots.txt
├── styles
│ ├── components
│ │ ├── button.scss
│ │ ├── icon.scss
│ │ ├── index.scss
│ │ ├── not-found.scss
│ │ ├── sim-start.scss
│ │ ├── sim.scss
│ │ ├── tile.scss
│ │ └── world.scss
│ ├── main.scss
│ ├── mixins
│ │ ├── fonts.scss
│ │ ├── icon.scss
│ │ └── layout.scss
│ ├── reset.scss
│ ├── typography.scss
│ └── variables
│ │ └── colors.scss
├── webpack.config.js
└── yarn.lock
├── config
├── config.exs
├── dev.exs
├── prod.exs
├── test.exs
└── test.mocks.exs
├── git_hooks
└── pre-commit
├── lib
├── ants.ex
├── ants
│ ├── ants
│ │ ├── ant.ex
│ │ ├── ant_food.ex
│ │ ├── ant_id.ex
│ │ ├── ant_move.ex
│ │ ├── ant_supervisor.ex
│ │ ├── ants.ex
│ │ ├── move.ex
│ │ ├── tile_selector.ex
│ │ └── to_home.ex
│ ├── application.ex
│ ├── shared
│ │ ├── knobs.ex
│ │ ├── pair.ex
│ │ ├── simulation_registry.ex
│ │ └── utils.ex
│ ├── simulations
│ │ ├── render.ex
│ │ ├── simulation_id.ex
│ │ ├── simulation_supervisor.ex
│ │ ├── simulations.ex
│ │ └── simulations_supervisor.ex
│ └── worlds
│ │ ├── point.ex
│ │ ├── surroundings.ex
│ │ ├── tile.ex
│ │ ├── tile_lookup.ex
│ │ ├── tile_supervisor.ex
│ │ ├── tile_type.ex
│ │ ├── world_map.ex
│ │ ├── world_map_data.ex
│ │ └── worlds.ex
├── ants_web.ex
└── ants_web
│ ├── channels
│ └── user_socket.ex
│ ├── controllers
│ ├── api
│ │ ├── fallback_controller.ex
│ │ ├── knob_controller.ex
│ │ ├── sim_controller.ex
│ │ └── turn_controller.ex
│ └── app_controller.ex
│ ├── endpoint.ex
│ ├── gettext.ex
│ ├── router.ex
│ ├── templates
│ └── layout
│ │ └── app.html.eex
│ └── views
│ ├── api
│ ├── knob_view.ex
│ ├── sim_view.ex
│ ├── tile_view.ex
│ └── turn_view.ex
│ ├── error_helpers.ex
│ ├── error_view.ex
│ └── layout_view.ex
├── mix.exs
├── mix.lock
├── priv
└── gettext
│ ├── en
│ └── LC_MESSAGES
│ │ └── errors.po
│ └── errors.pot
└── test
├── ants
├── ants
│ ├── ant_food_test.exs
│ ├── ant_move_test.exs
│ ├── ant_test.exs
│ ├── move_test.exs
│ └── tile_selector_test.exs
├── shared
│ └── utils_test.exs
└── worlds
│ ├── surroundings_test.exs
│ ├── tile_test.exs
│ ├── tile_type_test.exs
│ └── world_test.exs
├── ants_web
├── controllers
│ └── app_controller_test.exs
└── views
│ ├── app_view_test.exs
│ ├── error_view_test.exs
│ └── layout_view_test.exs
├── support
├── channel_case.ex
├── conn_case.ex
└── mocks.ex
└── test_helper.exs
/.formatter.exs:
--------------------------------------------------------------------------------
1 | [
2 | inputs: ["mix.exs", ".formatter.exs", "{config,lib,test}/**/*.{ex,exs}"]
3 | ]
4 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 |
3 | # App artifacts
4 | /_build
5 | /db
6 | /deps
7 | /*.ez
8 |
9 | # Generated on crash by the VM
10 | erl_crash.dump
11 |
12 | # Generated on crash by NPM
13 | npm-debug.log
14 |
15 | # Static artifacts
16 | /assets/node_modules
17 |
18 | # Since we are building assets from assets/,
19 | # we ignore priv/static. You may want to comment
20 | # this depending on your deployment strategy.
21 | /priv/static/
22 |
23 | # Files matching config/*.secret.exs pattern contain sensitive
24 | # data and you should not commit them into version control.
25 | #
26 | # Alternatively, you may comment the line below and commit the
27 | # secrets files as long as you replace their contents by environment
28 | # variables.
29 | /config/*.secret.exs
30 |
31 | .elixir_ls
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "editor.formatOnSave": true,
3 | "elixirLS.dialyzerEnabled": true,
4 | "search.exclude": {
5 | "**/node_modules": true,
6 | "_build": true,
7 | "deps": true,
8 | "erl_crash.dump": true
9 | },
10 | "reason.diagnostics.tools": [
11 | "merlin",
12 | "bsb"
13 | ]
14 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Ants
2 |
3 | 
4 |
5 | To start your Phoenix server:
6 |
7 | * Install dependencies with `mix deps.get`
8 | * Install Node.js dependencies with `cd assets && yarn install`
9 | * Start Phoenix with `mix phx.server`
10 | * Start Reason with `yarn start` in another terminal
11 |
12 | Now you can visit [`localhost:4000`](http://localhost:4000) from your browser.
13 |
--------------------------------------------------------------------------------
/ants.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/will-wow/ants/305e827f62090b5ad0242728eb5330ce815a2839/ants.gif
--------------------------------------------------------------------------------
/assets/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | .merlin
3 | .bsb.lock
4 | npm-debug.log
5 | /lib/bs/
6 | /node_modules/
--------------------------------------------------------------------------------
/assets/.prettierignore:
--------------------------------------------------------------------------------
1 | lib
--------------------------------------------------------------------------------
/assets/.prettierrc:
--------------------------------------------------------------------------------
1 | {}
2 |
--------------------------------------------------------------------------------
/assets/README.md:
--------------------------------------------------------------------------------
1 | # ants
2 |
3 | Run this project:
4 |
5 | ```
6 | yarn install
7 | yarn start
8 | # in another tab
9 | yarn webpack
10 | ```
11 |
12 | After you see the webpack compilation succeed (the `npm run webpack` step), open up the nested html files in `src/*` (**no server needed!**). Then modify whichever file in `src` and refresh the page to see the changes.
13 |
14 | **For more elaborate ReasonReact examples**, please see https://github.com/reasonml-community/reason-react-example
15 |
--------------------------------------------------------------------------------
/assets/bsconfig.json:
--------------------------------------------------------------------------------
1 | /* This is the BuckleScript configuration file. Note that this is a comment;
2 | BuckleScript comes with a JSON parser that supports comments and trailing
3 | comma. If this screws with your editor highlighting, please tell us by filing
4 | an issue! */
5 | {
6 | "name": "react-template",
7 | "reason": { "react-jsx": 2 },
8 | "sources": [{ "dir": "src", "subdirs": true }],
9 | "package-specs": [
10 | {
11 | "module": "commonjs"
12 | }
13 | ],
14 | "suffix": ".bs.js",
15 | "namespace": true,
16 | "bs-dependencies": ["reason-react", "bs-fetch", "@glennsl/bs-json"],
17 |
18 | "refmt": 3
19 | }
20 |
--------------------------------------------------------------------------------
/assets/index.js:
--------------------------------------------------------------------------------
1 | import "promise-polyfill/src/polyfill";
2 |
3 | import "./styles/main.scss";
4 |
5 | import "./lib/js/src/components/MainComponent.bs.js";
6 |
--------------------------------------------------------------------------------
/assets/lib/js/src/components/AntIcon.bs.js:
--------------------------------------------------------------------------------
1 | // Generated by BUCKLESCRIPT VERSION 2.1.1, PLEASE EDIT WITH CARE
2 | 'use strict';
3 |
4 | var React = require("react");
5 | var ReasonReact = require("reason-react/lib/js/src/ReasonReact.js");
6 | var Utils$ReactTemplate = require("../lib/Utils.bs.js");
7 |
8 | var component = ReasonReact.statelessComponent("AntIcon");
9 |
10 | function make() {
11 | var newrecord = component.slice();
12 | newrecord[/* render */9] = (function () {
13 | return React.createElement("span", {
14 | className: "icon"
15 | }, Utils$ReactTemplate.str("🐜"));
16 | });
17 | return newrecord;
18 | }
19 |
20 | exports.component = component;
21 | exports.make = make;
22 | /* component Not a pure module */
23 |
--------------------------------------------------------------------------------
/assets/lib/js/src/components/MainComponent.bs.js:
--------------------------------------------------------------------------------
1 | // Generated by BUCKLESCRIPT VERSION 2.1.1, PLEASE EDIT WITH CARE
2 | 'use strict';
3 |
4 | var ReactDOMRe = require("reason-react/lib/js/src/ReactDOMRe.js");
5 | var Caml_format = require("bs-platform/lib/js/caml_format.js");
6 | var ReasonReact = require("reason-react/lib/js/src/ReasonReact.js");
7 | var SimComponent$ReactTemplate = require("./SimComponent.bs.js");
8 | var NotFoundComponent$ReactTemplate = require("./NotFoundComponent.bs.js");
9 | var SimStartComponent$ReactTemplate = require("./SimStartComponent.bs.js");
10 |
11 | function renderForRoute(element) {
12 | return ReactDOMRe.renderToElementWithId(element, "root");
13 | }
14 |
15 | ReasonReact.Router[/* watchUrl */1]((function (url) {
16 | var match = url[/* path */0];
17 | var element;
18 | var exit = 0;
19 | if (match) {
20 | if (match[0] === "sim") {
21 | var match$1 = match[1];
22 | if (match$1 && !match$1[1]) {
23 | element = ReasonReact.element(/* None */0, /* None */0, SimComponent$ReactTemplate.make(Caml_format.caml_int_of_string(match$1[0]), /* array */[]));
24 | } else {
25 | exit = 1;
26 | }
27 | } else {
28 | exit = 1;
29 | }
30 | } else {
31 | element = ReasonReact.element(/* None */0, /* None */0, SimStartComponent$ReactTemplate.make(/* array */[]));
32 | }
33 | if (exit === 1) {
34 | element = ReasonReact.element(/* None */0, /* None */0, NotFoundComponent$ReactTemplate.make(/* array */[]));
35 | }
36 | return ReactDOMRe.renderToElementWithId(element, "root");
37 | }));
38 |
39 | ReasonReact.Router[/* push */0](window.location.pathname.pathname);
40 |
41 | exports.renderForRoute = renderForRoute;
42 | /* Not a pure module */
43 |
--------------------------------------------------------------------------------
/assets/lib/js/src/components/NotFoundComponent.bs.js:
--------------------------------------------------------------------------------
1 | // Generated by BUCKLESCRIPT VERSION 2.1.1, PLEASE EDIT WITH CARE
2 | 'use strict';
3 |
4 | var React = require("react");
5 | var ReasonReact = require("reason-react/lib/js/src/ReasonReact.js");
6 | var Utils$ReactTemplate = require("../lib/Utils.bs.js");
7 |
8 | var component = ReasonReact.statelessComponent("NotFound");
9 |
10 | function make() {
11 | var newrecord = component.slice();
12 | newrecord[/* render */9] = (function () {
13 | return React.createElement("div", {
14 | className: "not-found"
15 | }, React.createElement("h1", undefined, Utils$ReactTemplate.str("404")), React.createElement("p", undefined, Utils$ReactTemplate.str("The ants got lost!")));
16 | });
17 | return newrecord;
18 | }
19 |
20 | exports.component = component;
21 | exports.make = make;
22 | /* component Not a pure module */
23 |
--------------------------------------------------------------------------------
/assets/lib/js/src/components/SimComponent.bs.js:
--------------------------------------------------------------------------------
1 | // Generated by BUCKLESCRIPT VERSION 2.1.1, PLEASE EDIT WITH CARE
2 | 'use strict';
3 |
4 | var Block = require("bs-platform/lib/js/block.js");
5 | var Curry = require("bs-platform/lib/js/curry.js");
6 | var React = require("react");
7 | var ReasonReact = require("reason-react/lib/js/src/ReasonReact.js");
8 | var Http$ReactTemplate = require("../lib/Http.bs.js");
9 | var Knobs$ReactTemplate = require("../domain/Knobs.bs.js");
10 | var Utils$ReactTemplate = require("../lib/Utils.bs.js");
11 | var SimResponse$ReactTemplate = require("../domain/SimResponse.bs.js");
12 | var KnobsResponse$ReactTemplate = require("../domain/KnobsResponse.bs.js");
13 | var WorldComponent$ReactTemplate = require("./WorldComponent.bs.js");
14 |
15 | function updateWorld(send, json) {
16 | var world = SimResponse$ReactTemplate.parseWorld(json);
17 | return Curry._1(send, /* UpdateWorld */Block.__(0, [world]));
18 | }
19 |
20 | function updateKnobs(send, json) {
21 | var knobs = KnobsResponse$ReactTemplate.parse(json);
22 | return Curry._1(send, /* UpdateKnobs */Block.__(1, [knobs]));
23 | }
24 |
25 | function fetchWorld(send, simId) {
26 | Http$ReactTemplate.json(Http$ReactTemplate.get("/api/sim/" + (String(simId) + ""))).then((function (json) {
27 | return Promise.resolve(updateWorld(send, json));
28 | }));
29 | return /* () */0;
30 | }
31 |
32 | function fetchKnobs(send, simId) {
33 | Http$ReactTemplate.json(Http$ReactTemplate.get("/api/sim/" + (String(simId) + "/knob"))).then((function (response) {
34 | return Promise.resolve(updateKnobs(send, response));
35 | }));
36 | return /* () */0;
37 | }
38 |
39 | function doTurn(send, simId) {
40 | Http$ReactTemplate.post("/api/sim/" + (String(simId) + "/turn")).then((function (response) {
41 | if (response[/* status */1] === 201) {
42 | return Promise.resolve(Curry._1(send, /* Finished */5));
43 | } else {
44 | return Promise.resolve(updateWorld(send, response[/* json */0]));
45 | }
46 | }));
47 | return /* () */0;
48 | }
49 |
50 | function antStatusMessage(state) {
51 | if (state[/* finished */3]) {
52 | return "The ants found all the food!";
53 | } else if (state[/* fetching */2]) {
54 | return "The ants are marching!";
55 | } else {
56 | return "The ants are waiting!";
57 | }
58 | }
59 |
60 | var component = ReasonReact.reducerComponent("Sim");
61 |
62 | function make(simId, _) {
63 | var newrecord = component.slice();
64 | newrecord[/* didMount */4] = (function (param) {
65 | var send = param[/* send */4];
66 | Curry._1(send, /* FetchWorld */0);
67 | Curry._1(send, /* FetchKnobs */1);
68 | return /* NoUpdate */0;
69 | });
70 | newrecord[/* render */9] = (function (param) {
71 | var send = param[/* send */4];
72 | var state = param[/* state */2];
73 | var match = state[/* fetching */2];
74 | return React.createElement("div", {
75 | className: "sim"
76 | }, React.createElement("h1", undefined, Utils$ReactTemplate.str("Sim " + (String(simId) + ""))), React.createElement("h2", undefined, Utils$ReactTemplate.str(antStatusMessage(state))), ReasonReact.element(/* None */0, /* None */0, WorldComponent$ReactTemplate.make(state[/* world */0], state[/* knobs */1], /* array */[])), React.createElement("div", {
77 | className: "sim__buttons"
78 | }, React.createElement("button", {
79 | className: "button",
80 | onClick: (function () {
81 | return Curry._1(send, /* DoTurn */2);
82 | })
83 | }, Utils$ReactTemplate.str("Turn")), React.createElement("button", {
84 | className: "button",
85 | onClick: (function () {
86 | return Curry._1(send, /* Pause */4);
87 | })
88 | }, match !== 0 ? Utils$ReactTemplate.str("Pause") : Utils$ReactTemplate.str("Play")), React.createElement("a", {
89 | className: "button",
90 | href: "/"
91 | }, React.createElement("span", undefined, Utils$ReactTemplate.str("Back")))));
92 | });
93 | newrecord[/* initialState */10] = (function () {
94 | return /* record */[
95 | /* world : [] */0,
96 | /* knobs */Knobs$ReactTemplate.$$default,
97 | /* fetching : false */0,
98 | /* finished : false */0
99 | ];
100 | });
101 | newrecord[/* reducer */12] = (function (action, state) {
102 | if (typeof action === "number") {
103 | switch (action) {
104 | case 0 :
105 | return /* SideEffects */Block.__(2, [(function (param) {
106 | return fetchWorld(param[/* send */4], simId);
107 | })]);
108 | case 1 :
109 | return /* SideEffects */Block.__(2, [(function (param) {
110 | return fetchKnobs(param[/* send */4], simId);
111 | })]);
112 | case 2 :
113 | if (state[/* finished */3]) {
114 | return /* NoUpdate */0;
115 | } else {
116 | return /* SideEffects */Block.__(2, [(function (param) {
117 | return doTurn(param[/* send */4], simId);
118 | })]);
119 | }
120 | case 3 :
121 | return /* SideEffects */Block.__(2, [(function (param) {
122 | if (param[/* state */2][/* fetching */2]) {
123 | return Curry._1(param[/* send */4], /* DoTurn */2);
124 | } else {
125 | return 0;
126 | }
127 | })]);
128 | case 4 :
129 | return /* Update */Block.__(0, [/* record */[
130 | /* world */state[/* world */0],
131 | /* knobs */state[/* knobs */1],
132 | /* fetching */1 - state[/* fetching */2],
133 | /* finished */state[/* finished */3]
134 | ]]);
135 | case 5 :
136 | return /* Update */Block.__(0, [/* record */[
137 | /* world */state[/* world */0],
138 | /* knobs */state[/* knobs */1],
139 | /* fetching : false */0,
140 | /* finished : true */1
141 | ]]);
142 |
143 | }
144 | } else if (action.tag) {
145 | return /* Update */Block.__(0, [/* record */[
146 | /* world */state[/* world */0],
147 | /* knobs */action[0],
148 | /* fetching */state[/* fetching */2],
149 | /* finished */state[/* finished */3]
150 | ]]);
151 | } else {
152 | return /* Update */Block.__(0, [/* record */[
153 | /* world */action[0],
154 | /* knobs */state[/* knobs */1],
155 | /* fetching */state[/* fetching */2],
156 | /* finished */state[/* finished */3]
157 | ]]);
158 | }
159 | });
160 | newrecord[/* subscriptions */13] = (function (param) {
161 | var send = param[/* send */4];
162 | return /* :: */[
163 | /* Sub */[
164 | (function () {
165 | return setInterval((function () {
166 | return Curry._1(send, /* DoAutoTurn */3);
167 | }), 50);
168 | }),
169 | (function (prim) {
170 | clearInterval(prim);
171 | return /* () */0;
172 | })
173 | ],
174 | /* [] */0
175 | ];
176 | });
177 | return newrecord;
178 | }
179 |
180 | var str = Utils$ReactTemplate.str;
181 |
182 | var turnLength = 50;
183 |
184 | exports.str = str;
185 | exports.turnLength = turnLength;
186 | exports.updateWorld = updateWorld;
187 | exports.updateKnobs = updateKnobs;
188 | exports.fetchWorld = fetchWorld;
189 | exports.fetchKnobs = fetchKnobs;
190 | exports.doTurn = doTurn;
191 | exports.antStatusMessage = antStatusMessage;
192 | exports.component = component;
193 | exports.make = make;
194 | /* component Not a pure module */
195 |
--------------------------------------------------------------------------------
/assets/lib/js/src/components/SimStartComponent.bs.js:
--------------------------------------------------------------------------------
1 | // Generated by BUCKLESCRIPT VERSION 2.1.1, PLEASE EDIT WITH CARE
2 | 'use strict';
3 |
4 | var React = require("react");
5 | var ReasonReact = require("reason-react/lib/js/src/ReasonReact.js");
6 | var Http$ReactTemplate = require("../lib/Http.bs.js");
7 | var Utils$ReactTemplate = require("../lib/Utils.bs.js");
8 | var AntIcon$ReactTemplate = require("./AntIcon.bs.js");
9 | var SimResponse$ReactTemplate = require("../domain/SimResponse.bs.js");
10 |
11 | function startSim() {
12 | Http$ReactTemplate.json(Http$ReactTemplate.post("/api/sim")).then((function (json) {
13 | return Promise.resolve(SimResponse$ReactTemplate.parseSimId(json));
14 | })).then((function (simId) {
15 | return Promise.resolve(ReasonReact.Router[/* push */0]("sim/" + (String(simId) + "")));
16 | }));
17 | return /* () */0;
18 | }
19 |
20 | var component = ReasonReact.statelessComponent("SimStart");
21 |
22 | function make() {
23 | var newrecord = component.slice();
24 | newrecord[/* render */9] = (function () {
25 | return React.createElement("div", {
26 | className: "sim-start"
27 | }, React.createElement("h1", undefined, ReasonReact.element(/* None */0, /* None */0, AntIcon$ReactTemplate.make(/* array */[])), Utils$ReactTemplate.str("Ants"), ReasonReact.element(/* None */0, /* None */0, AntIcon$ReactTemplate.make(/* array */[]))), React.createElement("p", undefined, Utils$ReactTemplate.str("Simulate ant colony foraging behavior, using Elixir processes.")), React.createElement("button", {
28 | onClick: (function () {
29 | return startSim(/* () */0);
30 | })
31 | }, Utils$ReactTemplate.str("Start a simulation")));
32 | });
33 | return newrecord;
34 | }
35 |
36 | exports.startSim = startSim;
37 | exports.component = component;
38 | exports.make = make;
39 | /* component Not a pure module */
40 |
--------------------------------------------------------------------------------
/assets/lib/js/src/components/TileComponent.bs.js:
--------------------------------------------------------------------------------
1 | // Generated by BUCKLESCRIPT VERSION 2.1.1, PLEASE EDIT WITH CARE
2 | 'use strict';
3 |
4 | var Block = require("bs-platform/lib/js/block.js");
5 | var Curry = require("bs-platform/lib/js/curry.js");
6 | var React = require("react");
7 | var Printf = require("bs-platform/lib/js/printf.js");
8 | var Pervasives = require("bs-platform/lib/js/pervasives.js");
9 | var ReasonReact = require("reason-react/lib/js/src/ReasonReact.js");
10 |
11 | function tileClassName(tile) {
12 | switch (tile.tag | 0) {
13 | case 0 :
14 | case 1 :
15 | return "tile tile--land";
16 | case 2 :
17 | return "tile tile--home";
18 | case 3 :
19 | return "tile tile--rock";
20 |
21 | }
22 | }
23 |
24 | function is_pheromone(tile) {
25 | if (!tile.tag && tile[0][/* pheromone */1] > 0) {
26 | return /* true */1;
27 | } else {
28 | return /* false */0;
29 | }
30 | }
31 |
32 | function has_food(tile) {
33 | if (tile.tag === 1 && tile[0][/* food */1] > 0) {
34 | return /* true */1;
35 | } else {
36 | return /* false */0;
37 | }
38 | }
39 |
40 | function pheromoneOpacity(tile, maxPheromone) {
41 | if (tile.tag) {
42 | return "";
43 | } else {
44 | var pheromone = tile[0][/* pheromone */1];
45 | if (pheromone > 0) {
46 | return Pervasives.string_of_float(pheromone / maxPheromone);
47 | } else {
48 | return "";
49 | }
50 | }
51 | }
52 |
53 | function foodOpacity(tile, maxFood) {
54 | if (tile.tag === 1) {
55 | var food = tile[0][/* food */1];
56 | if (food > 0) {
57 | return Curry._1(Printf.sprintf(/* Format */[
58 | /* Float */Block.__(8, [
59 | /* Float_f */0,
60 | /* No_padding */0,
61 | /* No_precision */0,
62 | /* End_of_format */0
63 | ]),
64 | "%f"
65 | ]), food / maxFood);
66 | } else {
67 | return "";
68 | }
69 | } else {
70 | return "";
71 | }
72 | }
73 |
74 | function maxFood(knobs) {
75 | return knobs[/* startingFood */0];
76 | }
77 |
78 | function maxPheromone(knobs) {
79 | return 5 * knobs[/* pheromoneDeposit */3];
80 | }
81 |
82 | function antsOfTile(tile) {
83 | return tile[0][/* ants */0];
84 | }
85 |
86 | function antsClassName(tile, className) {
87 | var match = antsOfTile(tile);
88 | return className + (
89 | match !== 0 ? " tile--ants" : ""
90 | );
91 | }
92 |
93 | var component = ReasonReact.statelessComponent("World");
94 |
95 | function make(tile, knobs, _) {
96 | var newrecord = component.slice();
97 | newrecord[/* render */9] = (function () {
98 | return React.createElement("div", {
99 | className: antsClassName(tile, tileClassName(tile))
100 | }, is_pheromone(tile) ? React.createElement("div", {
101 | className: "tile--pheromone",
102 | style: {
103 | opacity: pheromoneOpacity(tile, 5 * knobs[/* pheromoneDeposit */3])
104 | }
105 | }) : null, has_food(tile) ? React.createElement("div", {
106 | className: "tile--food",
107 | style: {
108 | opacity: foodOpacity(tile, knobs[/* startingFood */0])
109 | }
110 | }) : null);
111 | });
112 | return newrecord;
113 | }
114 |
115 | exports.tileClassName = tileClassName;
116 | exports.is_pheromone = is_pheromone;
117 | exports.has_food = has_food;
118 | exports.pheromoneOpacity = pheromoneOpacity;
119 | exports.foodOpacity = foodOpacity;
120 | exports.maxFood = maxFood;
121 | exports.maxPheromone = maxPheromone;
122 | exports.antsOfTile = antsOfTile;
123 | exports.antsClassName = antsClassName;
124 | exports.component = component;
125 | exports.make = make;
126 | /* component Not a pure module */
127 |
--------------------------------------------------------------------------------
/assets/lib/js/src/components/TodoAppComponent.bs.js:
--------------------------------------------------------------------------------
1 | // Generated by BUCKLESCRIPT VERSION 2.1.1, PLEASE EDIT WITH CARE
2 | 'use strict';
3 |
4 | var List = require("bs-platform/lib/js/list.js");
5 | var $$Array = require("bs-platform/lib/js/array.js");
6 | var Block = require("bs-platform/lib/js/block.js");
7 | var Curry = require("bs-platform/lib/js/curry.js");
8 | var React = require("react");
9 | var Pervasives = require("bs-platform/lib/js/pervasives.js");
10 | var ReasonReact = require("reason-react/lib/js/src/ReasonReact.js");
11 | var Utils$ReactTemplate = require("../lib/Utils.bs.js");
12 | var TodoItem$ReactTemplate = require("../domain/TodoItem.bs.js");
13 | var TodoItemComponent$ReactTemplate = require("./TodoItemComponent.bs.js");
14 | var TodoInputComponent$ReactTemplate = require("./TodoInputComponent.bs.js");
15 |
16 | var lastId = [0];
17 |
18 | function newItem(text) {
19 | lastId[0] = lastId[0] + 1 | 0;
20 | return TodoItem$ReactTemplate.newItem(lastId[0], text);
21 | }
22 |
23 | function toggleOneItem(id, items) {
24 | return List.map((function (param) {
25 | return TodoItem$ReactTemplate.toggleItem(id, param);
26 | }), items);
27 | }
28 |
29 | var component = ReasonReact.reducerComponent("TodoApp");
30 |
31 | function make() {
32 | var newrecord = component.slice();
33 | newrecord[/* render */9] = (function (param) {
34 | var items = param[/* state */2][/* items */0];
35 | var reduce = param[/* reduce */1];
36 | var numItems = List.length(items);
37 | return React.createElement("div", {
38 | className: "todo"
39 | }, React.createElement("div", {
40 | className: "title"
41 | }, Utils$ReactTemplate.str("What to do"), ReasonReact.element(/* None */0, /* None */0, TodoInputComponent$ReactTemplate.make(Curry._1(reduce, (function (text) {
42 | return /* AddItem */Block.__(0, [text]);
43 | })), /* array */[]))), React.createElement("div", {
44 | className: "items"
45 | }, $$Array.of_list(List.map((function (item) {
46 | return ReasonReact.element(/* Some */[Pervasives.string_of_int(item[/* id */0])], /* None */0, TodoItemComponent$ReactTemplate.make(item, Curry._1(reduce, (function () {
47 | return /* ToggleItem */Block.__(1, [item[/* id */0]]);
48 | })), /* array */[]));
49 | }), items))), React.createElement("div", {
50 | className: "footer"
51 | }, Utils$ReactTemplate.str(Pervasives.string_of_int(numItems) + " items")));
52 | });
53 | newrecord[/* initialState */10] = (function () {
54 | return /* record */[/* items : [] */0];
55 | });
56 | newrecord[/* reducer */12] = (function (action, param) {
57 | var items = param[/* items */0];
58 | if (action.tag) {
59 | var id = action[0];
60 | return /* Update */Block.__(0, [/* record */[/* items */List.map((function (param) {
61 | return TodoItem$ReactTemplate.toggleItem(id, param);
62 | }), items)]]);
63 | } else {
64 | return /* Update */Block.__(0, [/* record */[/* items : :: */[
65 | newItem(action[0]),
66 | items
67 | ]]]);
68 | }
69 | });
70 | return newrecord;
71 | }
72 |
73 | exports.lastId = lastId;
74 | exports.newItem = newItem;
75 | exports.toggleOneItem = toggleOneItem;
76 | exports.component = component;
77 | exports.make = make;
78 | /* component Not a pure module */
79 |
--------------------------------------------------------------------------------
/assets/lib/js/src/components/TodoInputComponent.bs.js:
--------------------------------------------------------------------------------
1 | // Generated by BUCKLESCRIPT VERSION 2.1.1, PLEASE EDIT WITH CARE
2 | 'use strict';
3 |
4 | var Block = require("bs-platform/lib/js/block.js");
5 | var Curry = require("bs-platform/lib/js/curry.js");
6 | var React = require("react");
7 | var ReasonReact = require("reason-react/lib/js/src/ReasonReact.js");
8 |
9 | var component = ReasonReact.reducerComponent("TodoInput");
10 |
11 | function valueFromEvent($$event) {
12 | return $$event.target.value;
13 | }
14 |
15 | function make(onSubmit, _) {
16 | var newrecord = component.slice();
17 | newrecord[/* render */9] = (function (param) {
18 | var text = param[/* state */2];
19 | var reduce = param[/* reduce */1];
20 | return React.createElement("input", {
21 | placeholder: "Write something to do",
22 | type: "text",
23 | value: text,
24 | onKeyDown: (function ($$event) {
25 | if ($$event.key === "Enter") {
26 | Curry._1(onSubmit, text);
27 | return Curry._2(reduce, (function () {
28 | return "";
29 | }), /* () */0);
30 | } else {
31 | return 0;
32 | }
33 | }),
34 | onChange: Curry._1(reduce, (function ($$event) {
35 | return $$event.target.value;
36 | }))
37 | });
38 | });
39 | newrecord[/* initialState */10] = (function () {
40 | return "";
41 | });
42 | newrecord[/* reducer */12] = (function (newText, _) {
43 | return /* Update */Block.__(0, [newText]);
44 | });
45 | return newrecord;
46 | }
47 |
48 | exports.component = component;
49 | exports.valueFromEvent = valueFromEvent;
50 | exports.make = make;
51 | /* component Not a pure module */
52 |
--------------------------------------------------------------------------------
/assets/lib/js/src/components/TodoItemComponent.bs.js:
--------------------------------------------------------------------------------
1 | // Generated by BUCKLESCRIPT VERSION 2.1.1, PLEASE EDIT WITH CARE
2 | 'use strict';
3 |
4 | var Curry = require("bs-platform/lib/js/curry.js");
5 | var React = require("react");
6 | var Js_boolean = require("bs-platform/lib/js/js_boolean.js");
7 | var ReasonReact = require("reason-react/lib/js/src/ReasonReact.js");
8 | var Utils$ReactTemplate = require("../lib/Utils.bs.js");
9 |
10 | var component = ReasonReact.statelessComponent("TodoItem");
11 |
12 | function make(item, onToggle, _) {
13 | var newrecord = component.slice();
14 | newrecord[/* render */9] = (function () {
15 | return React.createElement("label", {
16 | className: "item"
17 | }, React.createElement("input", {
18 | checked: Js_boolean.to_js_boolean(item[/* completed */2]),
19 | type: "checkbox",
20 | onClick: (function () {
21 | return Curry._1(onToggle, /* () */0);
22 | })
23 | }), Utils$ReactTemplate.str(item[/* title */1]));
24 | });
25 | return newrecord;
26 | }
27 |
28 | exports.component = component;
29 | exports.make = make;
30 | /* component Not a pure module */
31 |
--------------------------------------------------------------------------------
/assets/lib/js/src/components/WorldComponent.bs.js:
--------------------------------------------------------------------------------
1 | // Generated by BUCKLESCRIPT VERSION 2.1.1, PLEASE EDIT WITH CARE
2 | 'use strict';
3 |
4 | var React = require("react");
5 | var Pervasives = require("bs-platform/lib/js/pervasives.js");
6 | var ReasonReact = require("reason-react/lib/js/src/ReasonReact.js");
7 | var Utils$ReactTemplate = require("../lib/Utils.bs.js");
8 | var TileComponent$ReactTemplate = require("./TileComponent.bs.js");
9 |
10 | var component = ReasonReact.statelessComponent("World");
11 |
12 | function make(world, knobs, _) {
13 | var newrecord = component.slice();
14 | newrecord[/* render */9] = (function () {
15 | return React.createElement("div", {
16 | className: "world"
17 | }, Utils$ReactTemplate.each_element(world, (function (i, row) {
18 | return React.createElement("div", {
19 | key: Pervasives.string_of_int(i),
20 | className: "world__row"
21 | }, Utils$ReactTemplate.each_element(row, (function (i, tile) {
22 | return React.createElement("div", {
23 | key: Pervasives.string_of_int(i),
24 | className: "world__tile"
25 | }, ReasonReact.element(/* None */0, /* None */0, TileComponent$ReactTemplate.make(tile, knobs, /* array */[])));
26 | })));
27 | })));
28 | });
29 | return newrecord;
30 | }
31 |
32 | exports.component = component;
33 | exports.make = make;
34 | /* component Not a pure module */
35 |
--------------------------------------------------------------------------------
/assets/lib/js/src/domain/Knobs.bs.js:
--------------------------------------------------------------------------------
1 | // Generated by BUCKLESCRIPT VERSION 2.1.1, PLEASE EDIT WITH CARE
2 | "use strict";
3 |
4 | var $$default = /* record */ [
5 | /* startingFood */ 0,
6 | /* mapSize */ 0,
7 | /* startingAnts */ 0,
8 | /* pheromoneDeposit */ 0,
9 | /* pheromoneEvaporationCoefficient */ 0,
10 | /* pheromoneInfluence */ 0
11 | ];
12 |
13 | exports.$$default = $$default;
14 | exports.default = $$default;
15 | exports.__esModule = true;
16 | /* No side effect */
17 |
--------------------------------------------------------------------------------
/assets/lib/js/src/domain/KnobsResponse.bs.js:
--------------------------------------------------------------------------------
1 | // Generated by BUCKLESCRIPT VERSION 2.1.1, PLEASE EDIT WITH CARE
2 | "use strict";
3 |
4 | var Json_decode = require("@glennsl/bs-json/lib/js/src/Json_decode.js");
5 |
6 | function parse(json) {
7 | return /* record */ [
8 | /* startingFood */ Json_decode.field(
9 | "starting_food",
10 | Json_decode.$$int,
11 | json
12 | ),
13 | /* mapSize */ Json_decode.field("map_size", Json_decode.$$int, json),
14 | /* startingAnts */ Json_decode.field(
15 | "starting_ants",
16 | Json_decode.$$int,
17 | json
18 | ),
19 | /* pheromoneDeposit */ Json_decode.field(
20 | "pheromone_deposit",
21 | Json_decode.$$float,
22 | json
23 | ),
24 | /* pheromoneEvaporationCoefficient */ Json_decode.field(
25 | "pheromone_evaporation_coefficient",
26 | Json_decode.$$float,
27 | json
28 | ),
29 | /* pheromoneInfluence */ Json_decode.field(
30 | "pheromone_influence",
31 | Json_decode.$$float,
32 | json
33 | )
34 | ];
35 | }
36 |
37 | exports.parse = parse;
38 | /* No side effect */
39 |
--------------------------------------------------------------------------------
/assets/lib/js/src/domain/SimId.bs.js:
--------------------------------------------------------------------------------
1 | // Generated by BUCKLESCRIPT VERSION 2.1.1, PLEASE EDIT WITH CARE
2 | /* This output is empty. Its source's type definitions, externals and/or unused code got optimized away. */
3 |
--------------------------------------------------------------------------------
/assets/lib/js/src/domain/SimResponse.bs.js:
--------------------------------------------------------------------------------
1 | // Generated by BUCKLESCRIPT VERSION 2.1.1, PLEASE EDIT WITH CARE
2 | 'use strict';
3 |
4 | var Json_decode = require("@glennsl/bs-json/lib/js/src/Json_decode.js");
5 | var TileResponse$ReactTemplate = require("./TileResponse.bs.js");
6 |
7 | function parse(json) {
8 | return /* record */[
9 | /* simId */Json_decode.field("sim_id", Json_decode.$$int, json),
10 | /* world */Json_decode.field("world", (function (param) {
11 | return Json_decode.list((function (param) {
12 | return Json_decode.list(TileResponse$ReactTemplate.parse, param);
13 | }), param);
14 | }), json)
15 | ];
16 | }
17 |
18 | function parseSimId(json) {
19 | return parse(json)[/* simId */0];
20 | }
21 |
22 | function parseWorld(json) {
23 | return parse(json)[/* world */1];
24 | }
25 |
26 | exports.parse = parse;
27 | exports.parseSimId = parseSimId;
28 | exports.parseWorld = parseWorld;
29 | /* No side effect */
30 |
--------------------------------------------------------------------------------
/assets/lib/js/src/domain/Tile.bs.js:
--------------------------------------------------------------------------------
1 | // Generated by BUCKLESCRIPT VERSION 2.1.1, PLEASE EDIT WITH CARE
2 | /* This output is empty. Its source's type definitions, externals and/or unused code got optimized away. */
3 |
--------------------------------------------------------------------------------
/assets/lib/js/src/domain/TileResponse.bs.js:
--------------------------------------------------------------------------------
1 | // Generated by BUCKLESCRIPT VERSION 2.1.1, PLEASE EDIT WITH CARE
2 | 'use strict';
3 |
4 | var Block = require("bs-platform/lib/js/block.js");
5 | var Json_decode = require("@glennsl/bs-json/lib/js/src/Json_decode.js");
6 |
7 | function food_tile(ants, json) {
8 | return /* record */[
9 | /* ants */ants,
10 | /* food */Json_decode.field("food", Json_decode.$$int, json)
11 | ];
12 | }
13 |
14 | function home_tile(ants, json) {
15 | return /* record */[
16 | /* ants */ants,
17 | /* food */Json_decode.field("food", Json_decode.$$int, json)
18 | ];
19 | }
20 |
21 | function land_tile(ants, json) {
22 | return /* record */[
23 | /* ants */ants,
24 | /* pheromone */Json_decode.field("pheromone", Json_decode.$$float, json)
25 | ];
26 | }
27 |
28 | function rock_tile(ants, _) {
29 | return /* record */[/* ants */ants];
30 | }
31 |
32 | function tile(kind, ants, json) {
33 | switch (kind) {
34 | case "food" :
35 | return /* Food */Block.__(1, [food_tile(ants, json)]);
36 | case "home" :
37 | return /* Home */Block.__(2, [home_tile(ants, json)]);
38 | case "land" :
39 | return /* Land */Block.__(0, [land_tile(ants, json)]);
40 | case "rock" :
41 | return /* Rock */Block.__(3, [/* record */[/* ants */ants]]);
42 | default:
43 | return /* Rock */Block.__(3, [/* record */[/* ants */ants]]);
44 | }
45 | }
46 |
47 | function parse(json) {
48 | var metadata_000 = /* kind */Json_decode.field("kind", Json_decode.string, json);
49 | var metadata_001 = /* ants */Json_decode.field("ants", Json_decode.bool, json);
50 | var partial_arg = metadata_001;
51 | var partial_arg$1 = metadata_000;
52 | return /* record */[/* tile */Json_decode.field("tile", (function (param) {
53 | return tile(partial_arg$1, partial_arg, param);
54 | }), json)][/* tile */0];
55 | }
56 |
57 | exports.food_tile = food_tile;
58 | exports.home_tile = home_tile;
59 | exports.land_tile = land_tile;
60 | exports.rock_tile = rock_tile;
61 | exports.tile = tile;
62 | exports.parse = parse;
63 | /* No side effect */
64 |
--------------------------------------------------------------------------------
/assets/lib/js/src/domain/TodoItem.bs.js:
--------------------------------------------------------------------------------
1 | // Generated by BUCKLESCRIPT VERSION 2.1.1, PLEASE EDIT WITH CARE
2 | 'use strict';
3 |
4 |
5 | function newItem(id, text) {
6 | return /* record */[
7 | /* id */id,
8 | /* title */text,
9 | /* completed : false */0
10 | ];
11 | }
12 |
13 | function toggleItem(id, item) {
14 | if (item[/* id */0] === id) {
15 | return /* record */[
16 | /* id */item[/* id */0],
17 | /* title */item[/* title */1],
18 | /* completed */1 - item[/* completed */2]
19 | ];
20 | } else {
21 | return item;
22 | }
23 | }
24 |
25 | exports.newItem = newItem;
26 | exports.toggleItem = toggleItem;
27 | /* No side effect */
28 |
--------------------------------------------------------------------------------
/assets/lib/js/src/domain/World.bs.js:
--------------------------------------------------------------------------------
1 | // Generated by BUCKLESCRIPT VERSION 2.1.1, PLEASE EDIT WITH CARE
2 | /* This output is empty. Its source's type definitions, externals and/or unused code got optimized away. */
3 |
--------------------------------------------------------------------------------
/assets/lib/js/src/lib/Http.bs.js:
--------------------------------------------------------------------------------
1 | // Generated by BUCKLESCRIPT VERSION 2.1.1, PLEASE EDIT WITH CARE
2 | 'use strict';
3 |
4 | var Fetch = require("bs-fetch/lib/js/src/Fetch.js");
5 |
6 | var jsonHeaders = {
7 | "Content-Type": "application/json"
8 | };
9 |
10 | var getOpts = Fetch.RequestInit[/* make */0](/* Some */[/* Get */0], /* Some */[jsonHeaders], /* None */0, /* None */0, /* None */0, /* None */0, /* None */0, /* None */0, /* None */0, /* None */0, /* None */0)(/* () */0);
11 |
12 | var postOpts = Fetch.RequestInit[/* make */0](/* Some */[/* Post */2], /* Some */[jsonHeaders], /* None */0, /* None */0, /* None */0, /* None */0, /* None */0, /* None */0, /* None */0, /* None */0, /* None */0)(/* () */0);
13 |
14 | var putOpts = Fetch.RequestInit[/* make */0](/* Some */[/* Put */3], /* Some */[jsonHeaders], /* None */0, /* None */0, /* None */0, /* None */0, /* None */0, /* None */0, /* None */0, /* None */0, /* None */0)(/* () */0);
15 |
16 | var deleteOpts = Fetch.RequestInit[/* make */0](/* Some */[/* Delete */4], /* Some */[jsonHeaders], /* None */0, /* None */0, /* None */0, /* None */0, /* None */0, /* None */0, /* None */0, /* None */0, /* None */0)(/* () */0);
17 |
18 | function dataAndStatus(response) {
19 | return response.json().then((function (json) {
20 | return Promise.resolve(/* record */[
21 | /* json */json,
22 | /* status */response.status
23 | ]);
24 | }));
25 | }
26 |
27 | function get(url) {
28 | return fetch(url, getOpts).then(dataAndStatus);
29 | }
30 |
31 | function post(url) {
32 | return fetch(url, postOpts).then(dataAndStatus);
33 | }
34 |
35 | function put(url, _) {
36 | return fetch(url, putOpts).then(dataAndStatus);
37 | }
38 |
39 | function $$delete(url, _) {
40 | return fetch(url, deleteOpts).then(dataAndStatus);
41 | }
42 |
43 | function json(promise) {
44 | return promise.then((function (response) {
45 | return Promise.resolve(response[/* json */0]);
46 | }));
47 | }
48 |
49 | exports.jsonHeaders = jsonHeaders;
50 | exports.getOpts = getOpts;
51 | exports.postOpts = postOpts;
52 | exports.putOpts = putOpts;
53 | exports.deleteOpts = deleteOpts;
54 | exports.dataAndStatus = dataAndStatus;
55 | exports.get = get;
56 | exports.post = post;
57 | exports.put = put;
58 | exports.$$delete = $$delete;
59 | exports.json = json;
60 | /* getOpts Not a pure module */
61 |
--------------------------------------------------------------------------------
/assets/lib/js/src/lib/Utils.bs.js:
--------------------------------------------------------------------------------
1 | // Generated by BUCKLESCRIPT VERSION 2.1.1, PLEASE EDIT WITH CARE
2 | 'use strict';
3 |
4 | var List = require("bs-platform/lib/js/list.js");
5 | var $$Array = require("bs-platform/lib/js/array.js");
6 |
7 | function str(prim) {
8 | return prim;
9 | }
10 |
11 | function map_with_index(list, _) {
12 | return List.mapi((function (index, item) {
13 | return /* tuple */[
14 | index,
15 | item
16 | ];
17 | }), list);
18 | }
19 |
20 | function each_element(list, toElement) {
21 | return $$Array.of_list(List.mapi(toElement, list));
22 | }
23 |
24 | exports.str = str;
25 | exports.map_with_index = map_with_index;
26 | exports.each_element = each_element;
27 | /* No side effect */
28 |
--------------------------------------------------------------------------------
/assets/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ants",
3 | "version": "0.1.0",
4 | "scripts": {
5 | "build": "bsb -make-world",
6 | "start": "bsb -make-world -w",
7 | "clean": "bsb -clean-world",
8 | "test": "echo \"Error: no test specified\" && exit 1",
9 | "webpack": "webpack -w",
10 | "format": "yarn format-reason && yarn format-prettier",
11 | "format-reason": "refmt --in-place src/**/*.re",
12 | "format-prettier": "prettier --write '**/*.{js,json,scss}'"
13 | },
14 | "keywords": ["BuckleScript"],
15 | "author": "",
16 | "license": "MIT",
17 | "dependencies": {
18 | "@glennsl/bs-json": "^1.1.0",
19 | "bs-fetch": "^0.2.0",
20 | "promise-polyfill": "^7.0.0",
21 | "react": "^16.2.0",
22 | "react-dom": "^16.2.0",
23 | "reason-react": ">=0.3.1",
24 | "whatwg-fetch": "^2.0.3"
25 | },
26 | "devDependencies": {
27 | "bs-platform": "^2.1.0",
28 | "copy-webpack-plugin": "^4.3.1",
29 | "css-loader": "^0.28.8",
30 | "node-sass": "^4.7.2",
31 | "prettier": "^1.10.2",
32 | "sass-loader": "^6.0.6",
33 | "style-loader": "^0.19.1",
34 | "webpack": "^3.10.0"
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/assets/src/components/AntIcon.re:
--------------------------------------------------------------------------------
1 | let component = ReasonReact.statelessComponent("AntIcon");
2 |
3 | let make = _children => {
4 | ...component,
5 | render: (_) => (Utils.str({js|🐜|js}))
6 | };
7 |
--------------------------------------------------------------------------------
/assets/src/components/MainComponent.re:
--------------------------------------------------------------------------------
1 | let renderForRoute = element =>
2 | ReactDOMRe.renderToElementWithId(element, "root");
3 |
4 | ReasonReact.Router.watchUrl(url =>
5 | (
6 | switch url.path {
7 | | [] =>
(Utils.str("The ants got lost!"))
9 |23 | ( 24 | Utils.str( 25 | "Simulate ant colony foraging behavior, using Elixir processes." 26 | ) 27 | ) 28 |
29 | 32 |