-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.html
556 lines (552 loc) · 31.2 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, height=device-height" />
<meta name="description"
content="An online cellular automata playground, providing support and customization for a variety of automata.">
<meta name="author" content="Mohamed Shahul Hameed Niyaz">
<title>Cellula</title>
<!--Base for github pages-->
<base href="./" target="_blank" />
<!--Import Resources-->
<link rel="icon" type="image/x-icon" href="./images/favicon.ico" />
<link rel="stylesheet" href="./css/styles.css" />
<link rel="stylesheet" href="./css/toolbar.css" />
<link rel="stylesheet" href="./css/windows.css" />
<link rel="stylesheet" href="./css/selector.css" />
<link rel="stylesheet" href="./css/settings.css" />
<!--GPU.js CDN-->
<script src="https://cdn.jsdelivr.net/npm/gpu.js@2.10.1/dist/gpu-browser.min.js" defer></script>
<!--Pixelify Sans Font-->
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link rel="preload" href="https://fonts.googleapis.com/css2?family=Pixelify+Sans:wght@400..700&display=swap"
as="style" onload="this.onload=null;this.rel='stylesheet'" />
<noscript>
<link href="https://fonts.googleapis.com/css2?family=Pixelify+Sans:wght@400..700&display=swap"
rel="stylesheet" />
</noscript>
<!--Ace Editor-->
<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.23.0/ace.js"></script>
</head>
<body>
<!--! Toolbar -->
<div id="toolbar">
<a id="app-title" href="https://github.com/Niyaz-Mohamed/Cellula">Cellula</a>
<p id="fps-tracker">FPS: <span id="fps-span">0</span></p>
<!--Automata window trigger-->
<div class="dropdown window-trigger">
<button class="dropbtn triggerbtn" id="automata-btn">Life</button>
</div>
<!--Settings window trigger-->
<div class="dropdown window-trigger">
<button class="dropbtn triggerbtn" id="settings-btn">Settings</button>
</div>
<!--File dropdown-->
<div class="dropdown">
<button class="dropbtn">File</button>
<div class="dropdown-content">
<!--TODO: Replace these with proper shortcuts-->
<button class="dropdown-option">
<span class="option-name">Save</span>
</button>
<!--TODO: This should open a window-->
<button class="dropdown-option">
<span class="option-name">Load</span>
</button>
</div>
</div>
<!--Controls dropdown-->
<div class="dropdown">
<button class="dropbtn">Controls</button>
<div class="dropdown-content">
<p>View</p>
<button class="dropdown-option">
<span class="option-name">Toggle Toolbar</span>
<span class="option-shortcut">Esc</span>
</button>
<button class="dropdown-option">
<span class="option-name">Step</span>
<span class="option-shortcut">.</span>
</button>
<button class="dropdown-option">
<span class="option-name">Pause/Unpause</span>
<span class="option-shortcut">Space/P</span>
</button>
<button class="dropdown-option">
<span class="option-name">Randomize Grid</span>
<span class="option-shortcut">Tab/R</span>
</button>
<button class="dropdown-option">
<span class="option-name">Clear Grid</span>
<span class="option-shortcut">
\
</span>
</button>
<button class="dropdown-option">
<span class="option-name">Higher Cell Size</span>
<span class="option-shortcut">e</span>
</button>
<button class="dropdown-option">
<span class="option-name">Lower Cell Size</span>
<span class="option-shortcut">q</span>
</button>
<p>Pen</p>
<button class="dropdown-option">
<span class="option-name">Higher Fill Amt</span>
<span class="option-shortcut">+/ArrowUp</span>
</button>
<button class="dropdown-option">
<span class="option-name">Lower Fill Amt</span>
<span class="option-shortcut">-/ArrowDown</span>
</button>
<button class="dropdown-option">
<span class="option-name">Change Pen Fill</span>
<span class="option-shortcut">Shift</span>
</button>
</div>
</div>
<!--Console-->
<p id="console-container">
»
<span id="console">Welcome to Cellula!
</span>
</p>
</div>
<!--! Draggeable Startup -->
<div id="startup" class="window">
<div id="startup-header" class="window-header">
<span class="window-title">Startup</span>
<span class="window-delete">X</span>
</div>
<!--Content for File Load-->
<div id="startup-window-content" class='window-content'>
<p><b>EPILEPSY WARNING:</b><br> Some patterns may include rapidly flashing lights</p>
<p><b>PERFORMANCE ISSUES?</b><br> Reduce cell size by pressing 'E' or going to "Controls"</p>
</div>
</div>
<!--! Draggable Automata Select -->
<div id="automata" class="window">
<div id="automata-header" class="window-header">
<span class="window-title">Select Automata</span>
<span class="window-delete">X</span>
</div>
<div id='automata-content' class='window-content'>
<!--Buttons for selection-->
<div class="sidenav">
<p>Discrete</p>
<button class="select-btn selected">Life</button>
<button class="select-btn">Langton's Ant</button>
<button class="select-btn">Elementary</button>
<button class="select-btn">Brian's Brain</button>
<button class="select-btn">Wireworld</button>
<button class="select-btn">Rock, Paper, Scissors</button>
<p>Continuous</p>
<button class="select-btn">Neural</button>
<button class="select-btn">Huegene</button>
</div>
<!--Content for Life-->
<div id="life-info" class="side-content">
<h1>Game of Life</h1>
<img src="./images/Life.webp" alt="Life GIF">
<h2>Description</h2>
<p>
Conway's Game of Life (GoL) is a zero-player game, where the evolution of the game board depends
only on the state of the board.
It is the best known example of a cellular automaton. To interact with the game, you can create an
initial configuration and see how it evolves,
pausing or stepping through the states of the board. Interestingly, the GoL is turing-complete and
can simulate a universal constructor or any other turing machine.
</p>
<h2>Rules</h2>
<p>The GoL has cells in 2 states, alive and dead. The evolution of a cell depends on its 8
neighbors. For the GoL, the below are the rules:</p>
<ul>
<li>A dead cell comes alive if it has exactly 3 neighbors</li>
<li>A live cell survives only if it has 2 or 3 neighbors</li>
</ul>
<p>The above rules can be represented by the rulestring B3/S23. Life-like automata are a class of
automata which can be represented by such rulestring. For example, the automata "HighLife" is
represented by B36/S23, where birth occurs when a cell has 3 or 6 neighbors, and survival occurs
when a live cell has 2 or 3 neighbors.</p>
<h2>Additional Info</h2>
<p>This simulator has been modified to allow for modification of the neighborhoods for life-like
automata. For automata with neighborhoods of size greater than 10, numbers in rulestrings can be
wrapped in brackets [Example: B1(10)/S2(10)].</p>
<p>Click here for more info on <a href="https://conwaylife.com/wiki/Rulestring">rulestrings</a> and
<a href="https://conwaylife.com/wiki/List_of_Life-like_rules">life-like automata</a>.
</p>
</div>
<!--Content for Langton's Ant-->
<div id="ant-info" class="side-content">
<h1>Langton's Ant</h1>
<img src="./images/LangtonAnt.webp" alt="Langton's Ant GIF">
<h2>Description</h2>
<p>Another very simple Turing-complete automata is Langton's Ant. While the grid has only 2 states,
alive and dead, there are also ants walking along the grid. While the ant staying on a cell does not
affect the cell's state, the ants define the rule for the automaton. Another interesting thing to
note is that after a period of chaos, the ant converges on a recurrent "highway" pattern regardless
of the initial configuration, displaying emergent order.</p>
<h2>Rules</h2>
<p>Below are the rules of Langton's Ant, defined for each ant:</p>
<ul>
<li>An ant at a white square flips the color of the square and turns 90 degrees clockwise</li>
<li>An ant at a black square flips the color of the square and turns 90 degrees anticlockwise</li>
<li>All ants take a step forward after turning</li>
</ul>
<h2>Additional Info</h2>
<p>For more info on Langton's Ant and generalisations to more states or more complex rules (Langton's
Ants can be generalised to automata known as Turmites), check out the <a
href="https://en.wikipedia.org/wiki/Langton%27s_ant">Wikipedia Article</a></p>
</div>
<!--Content for Elementary CA-->
<div id="elementary-info" class="side-content">
<h1>Elementary Automata</h1>
<img src="./images/Elementary.webp" alt="Elementary CA GIF">
<h2>Description</h2>
<p>Contrary to most other cellular automata, Elementary Cellular Automata is actually a 1-dimensional
automata. You can think of the automata as black and white squares on a long piece of tape. The next
state of each square is dependent on both its own state and its 3 neighbors. While you can't exactly
represent a 1D automata on a 2d grid, it is possible to draw each timestep of the automata on a
different row. In such a case, you can think of the state of each cell being determined by the 3
cells above it. </p>
<h2>Rules</h2>
<p>There a 2^3 possible permutations that the 3 neighbors can take, and each permutation can result in a
black or white square in the next state, resulting in exactly 256 possible rulesets. Each rule can
be represented by a number from 0 to 255: these rules are termed the <a
href="https://en.wikipedia.org/wiki/Wolfram_code">Wolfram Code</a>. Below are some rules with
interesting results.</p>
<ul>
<li>Rule 30: Despite its simple rule, it produces highly unpredictable patterns. It has been used as
a Random Number Generator.</li>
<li>Rule 90: Creates a fractal pattern known as the Sierpiński triangle</li>
<li>Rule 110: A turing-complete rule, capable of universal computation</li>
<li>Rule 54: Generates stable structures and moving gliders, similar to the gliders in Conway's GoL
</li>
</ul>
<h2>Additional Info</h2>
<p>For a more detailed list of interesting rulesets and their properties, check out the <a
href="https://en.wikipedia.org/wiki/Elementary_cellular_automaton">Wikipedia Article</a></p>
</div>
<!--Content for Brian's Brain-->
<div id="brain-info" class="side-content">
<h1>Brian's Brain</h1>
<img src="./images/BrianBrain.webp" alt="Brian's Brain GIF">
<h2>Description</h2>
<p>
Brian's Brain is an extension of the "Seeds" lifelike automata (B2/S) to 3 states. Because of the
automaton's name, it can be linkened to a brain and each cell likened to a neuron. The 3 states
of the cells are named approppriately (ready, firing, refactory). Brian's Brain displays the
interesting property where small patterns tend to blow up and almost all patterns are spaceships:
patterns which mvoe across the grid.
</p>
<h2>Rules</h2>
<p>Brian's Brain has cells in 3 states, ready (neurons prepared to fire), firing (active neurons) and
refactory (neurons resting after firing). The evolution of a cell, similar to life-like automata,
depends on its 8 neighbors. Below are the rules:</p>
<ul>
<li>A ready cell fires if it has exactly 2 firing neighbors</li>
<li>A firing cell always becomes refactory</li>
<li>A refactory cell always becomes ready</li>
</ul>
<p>This editor has been customized such that you can change the conditions on which a cell fires. The
rulestring "2/3/4" means a cell will fire if it has 2, 3 or 4 neighbors.</p>
</div>
<!--Content for Wireworld-->
<div id="wire-info" class="side-content">
<h1>Wireworld</h1>
<img src="./images/Wireworld.webp" alt="Wireworld GIF">
<h2>Description</h2>
<p>Wireworld is a 4-state cellular automata operating in a 2-d neighborhood with a Moore neighborhood (8
direct neighbors). Wireworld is especially suited for simulating digital electronic circuits as ot
has
been defined similarly to how a circuit behaves. Unlike conventional life-like cellular automata,
the evolution of Wireworld is constrained to only onccur within wires/conductors. Given an infinite
2D plane, Wireworld is
turing-complete due to its ability to make logic gates.</p>
<h2>Rules</h2>
<p>Wireworld has 4 states: empty, electron head, electron tail, and conductor, similar to components of
a circuit. Below are its rules:</p>
<ul>
<li>Empty cells always stay as empty cells</li>
<li>Electron heads always become electron tails</li>
<li>Electron tails always become conductors</li>
<li>Conductors become electron tails if they have exactly 1 or 2 electron head neighbors</li>
</ul>
<h2>Additional Info</h2>
<p>Wireworld can make complex mechanisms such as logic gates, 8-bit multipliers and adders, clocks and
even displays. A <a href="https://demonstrations.wolfram.com/WireWorldGatesAndGadgets/">list of
interesting components</a> is also available.</p>
</div>
<!--Content for Rock, Paper, Scissors-->
<div id="rps-info" class="side-content">
<h1>Rock, Paper, Scissors</h1>
<img src="./images/RPS.webp" alt="Rock Paper Scissors GIF">
<h2>Description</h2>
<p>Everyone knows how rock, paper, scissors works. This is just that game in cellular automata form!
It's a 3-state automata where each color beats exactly one other color. It has a tendency to form
spiral patterns after a few generations regardless of initial state.</p>
<h2>Rules</h2>
<p>Below are the rules of the automata:</p>
<ul>
<li>Rock (red) is converted to paper if 3 or more neighbors are paper</li>
<li>Paper (Green) is converted to scissors if 3 or more neighbors are paper</li>
<li>Scissors (Blue) is converted to paper if 3 or more neighbors are paper</li>
</ul>
<p>The option to change the number of neighbors required for a cell to be beaten is provided in the
settings. This automata can also be extended to 4-state and 5-state neighborhoods by adding in
Lizard
(light-green) and Spock (light-blue). Note that in 4-state games, it is impossible for all states to
be equally powerful and this may lead to extinction of weakest color or complete domination of
strongest color.</p>
<h2>Additional Info</h2>
<p>This automata was inspired by <a href="https://www.youtube.com/watch?v=TvZI6Xc0J1Y">this video</a>
which shows how proportion of each state varies with
time.</p>
</div>
<!--Content for Neural CA-->
<div id="neural-info" class="side-content">
<h1>Neural Automata</h1>
<img src="./images/Neural.webp" alt="Neural GIF">
<h2>Description</h2>
<p>
Neural Cellular Automata are based on neural networks, and they involve a convolution (summing up
the values of neighboring cells multiplied by the weight of each cell), and then an activation (a
mathematical function applied to the value of a cell calculated after convolution). Interestingly,
neural CA can be trained to regenerate images even when portions of them are taken away, as seen in
<a href="https://distill.pub/2020/growing-ca/">this Neural CA simulator</a>.
</p>
<p>While making such neural automata involves training on the image, we will instead use random weights
and activations in an attempt to find interesting patterns. Credit to <a
href="https://www.youtube.com/watch?v=3H79ZcBuw4M">Emergent Garden on Youtube</a>, who provided
the idea for this automata.</p>
<h2>Rules</h2>
<p>For each timestep, each cell undergoes a convolution, and then an activation.</p>
<ul>
<li>First, the new value of a cell is calculated via a convolution with its neighbors. The value of
each neighbor is multiplied by the neighbor's weight and then summed up to give the new value.
</li>
<li>Then an activation occurs, wherein a mathematical function is applied to the new value to give
rise to more complex behavior. This can be functions like the identity (x maps to x) or power (x
maps to x squared), or other more complex functions.</li>
<li>Values lower than 0 or 1 are clipped back into the range.</li>
</ul>
</div>
<!--Content for Huegene-->
<div id="huegene-info" class="side-content">
<h1>Huegene</h1>
<img src="./images/Huegene.webp" alt="Huegene GIF">
<h2>Description</h2>
<p>
Huegene is an automata modeling slow evolution by changing the hue of cells. Some models of huegene
involve predator and prey, but this implementation is a simpler version I found on a <a
href='https://www.reddit.com/r/creativecoding/comments/ozt21p/huegene_cellular_automata/'>reddit
post</a>.
</p>
<h2>Rules</h2>
<p>Huegene works by keeping the value and saturation of every color constant and changing only hue.
Extent of possible hue shift can be controlled via the random factor.</p>
<ul>
<li>For empty cells with empty neighbors, they remain empty.</li>
<li>For empty cells with filled neighbors, they randomly select a neighbor, offset their hue, and
become filled.</li>
<li>Filled cells always keep their hue.</li>
</ul>
</div>
</div>
</div>
<!--! Draggable Settings -->
<div id="settings" class="window">
<div id="settings-header" class="window-header">
<span class="window-title">Settings</span>
<span class="window-delete">X</span>
</div>
<!--Content for Settings-->
<div id="settings-window-content" class='window-content'>
<!--Settings for GoL-->
<div id="life-settings" class="automata-settings" style="display: block;">
<div class="rule-div">
<label for="life-rule-input">Rulestring</label>
<p class="desc">B/S rulestring. See "Select Automata" window for details.</p>
<input type="text" id="life-rule-input" placeholder="B/S Rulestring" value="B3/S23" />
</div>
<div class="rule-div">
<label>Neighborhood</label>
<p class="desc">Select the neighborhood of each cell.</p>
<div class="grid-size-selector">
<div>
<label for="life-rows">Rows:</label>
<input type="number" id="life-rows" class="row-select" value="3">
</div>
<div>
<label for="life-columns">Columns:</label>
<input type="number" id="life-columns" class="column-select" value="3">
</div>
</div>
</div>
<div class="neighbor-grid"></div>
</div>
<!--Settings for Langton's Ant-->
<div id="ant-settings" class="automata-settings">
<p>No settings available for Langton's Ant</p>
</div>
<!--Settings for Elementary CA-->
<div id="elementary-settings" class="automata-settings">
<div class="rule-div">
<label for="elementary-rule-input">Wolfram Code</label>
<p class="desc">Wolfram Code, between 0 and 255 inclusive.</p>
<input type="text" id="elementary-rule-input" placeholder="Number between 0 and 255" value="90" />
</div>
</div>
<!--Settings for Brian's Brain-->
<div id="brain-settings" class="automata-settings">
<div class="rule-div">
<label for="brain-rule-input">Rulestring</label>
<p class="desc">Number of neighbors for birth, separated by slash (/). Example: 2/3</p>
<input type="text" id="brain-rule-input" placeholder="2/3/etc." value="2/3" />
</div>
<div class="rule-div">
<label>Neighborhood</label>
<p class="desc">Select the neighborhood of each cell.</p>
<div class="grid-size-selector">
<div>
<label for="brain-rows">Rows:</label>
<input type="number" id="brain-rows" class="row-select" value="3">
</div>
<div>
<label for="brain-columns">Columns:</label>
<input type="number" id="brain-columns" class="column-select" value="3">
</div>
</div>
</div>
<div class="neighbor-grid"></div>
</div>
<!--Settings for Wireworld-->
<div id="wire-settings" class="automata-settings">
<p>No settings available for Wireworld</p>
</div>
<!--Settings for Rock Paper Scissors-->
<div id="rps-settings" class="automata-settings">
<div class="rule-div">
<label for="rps-rule-input">Rulestring</label>
<p class="desc">A cell will be converted if it has more than these many neighbors which beat it</p>
<input type="text" id="rps-rule-input" placeholder="3" value="3" min="1" />
</div>
<div class="rule-div">
<label for="rps-state-select">Number of States</label>
<p class="desc">Number of states in the game. Lizard and Spock can be added as extra states</p>
<select id="rps-state-select">
<option value="3" selected>3-State</option>
<option value="4">4-State (Unbalanced)</option>
<option value="5">5-State</option>
</select>
</div>
<div class="rule-div">
<label>Neighborhood</label>
<p class="desc">Select the neighborhood of each cell.</p>
<div class="grid-size-selector">
<div>
<label for="rps-rows">Rows:</label>
<input type="number" id="rps-rows" class="row-select" value="3">
</div>
<div>
<label for="rps-columns">Columns:</label>
<input type="number" id="rps-columns" class="column-select" value="3">
</div>
</div>
</div>
<div class="neighbor-grid"></div>
</div>
<!--Settings for Neural CA-->
<div id="neural-settings" class="automata-settings">
<div class="rule-div">
<label for="neural-preset-select">Presets</label>
<p class="desc">Select an interesting premade setting (using custom activations).</p>
<select id="neural-preset-select">
<option value="worms" selected>Worms</option>
<option value="game-of-life">Game of Life</option>
<option value="stars">Stars</option>
<option value="waves">Waves</option>
<option value="mitosis">Mitosis</option>
<option value="pathways">Pathways</option>
</select>
</div>
<div class="rule-div">
<label>Cell Weights</label>
<p class="desc">Select the weight of each cell to be used in convolution.</p>
<div class="grid-size-selector">
<div>
<label for="life-rows">Rows:</label>
<input type="number" id="life-rows" class="row-select" value="3">
</div>
<div>
<label for="life-columns">Columns:</label>
<input type="number" id="life-columns" class="column-select" value="3">
</div>
</div>
</div>
<div class="neighbor-grid"></div>
<button id="neural-randomize">Randomize</button>
<div class="rule-div">
<label for="neural-activation-select">Activation Function</label>
<p class="desc">Activation Function applied after each convolution</p>
<select id="neural-activation-select">
<option value="identity">Identity</option>
<option value="power">Power</option>
<option value="absolute">Absolute</option>
<option value="tanh">tanh</option>
<option value="inverse-gaussian">Inverse Gaussian</option>
<option selected disabled>Custom</option>
</select>
<div id="neural-code-editor"></div>
</div>
<div class="rule-div horizontal-rule">
<label for="neural-skip-input">Skip Frames</label>
<input type="checkbox" id="neural-skip-input">
</div>
</div>
<!--Settings for Huegene-->
<div id="huegene-settings" class="automata-settings">
<div class="rule-div">
<label for="huegene-random-input">Random Factor</label>
<p class="desc">Number >= 0, represents randomness of hue evolution.</p>
<input type="text" id="huegene-random-input" />
</div>
<div class="rule-div horizontal-rule">
<label for="huegene-fade-input">Fade Pixels</label>
<input type="checkbox" id="huegene-fade-input">
</div>
<div class="rule-div horizontal-rule">
<label for="huegene-psychedelic-input">Psychedelic Mode</label>
<input type="checkbox" id="huegene-psychedelic-input">
</div>
</div>
</div>
</div>
<!--! Draggeable File Load -->
<div id="load" class="window">
<div id="load-header" class="window-header">
<span class="window-title">Load File</span>
<span class="window-delete">X</span>
</div>
<!--Content for File Load-->
<div id="load-window-content" class='window-content'>
<div id="load-settings" class="rule-div">
<!--Actual Content goes here-->
<label>File to Load</label>
<p class="desc">Input a file you have downloaded previously</p>
<label for="file-input" class="custom-file-upload">Select file</label>
<input type="file" id="file-input" accept="application/json">
<p id="invalid-file-notice">Invalid File!</p>
</div>
</div>
</div>
<canvas id="overlayCanvas"></canvas>
<canvas id="cellGrid"></canvas>
<!--Attach Scripts-->
<script type="module" src="./js/automata.js"></script>
<script type="module" src="./js/inputs/userInput.js"></script>
<script type="module" src="./js/inputs/settings.js"></script>
</body>
</html>