aboutsummaryrefslogtreecommitdiff
path: root/aoc2023/build/dev/erlang/gleam_erlang
diff options
context:
space:
mode:
Diffstat (limited to 'aoc2023/build/dev/erlang/gleam_erlang')
-rw-r--r--aoc2023/build/dev/erlang/gleam_erlang/_gleam_artefacts/gleam@@compile.erl157
-rw-r--r--aoc2023/build/dev/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang.cachebin0 -> 9002 bytes
-rw-r--r--aoc2023/build/dev/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang.cache_metabin0 -> 122 bytes
-rw-r--r--aoc2023/build/dev/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang.erl90
-rw-r--r--aoc2023/build/dev/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@atom.cachebin0 -> 2925 bytes
-rw-r--r--aoc2023/build/dev/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@atom.cache_metabin0 -> 50 bytes
-rw-r--r--aoc2023/build/dev/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@atom.erl26
-rw-r--r--aoc2023/build/dev/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@charlist.cachebin0 -> 879 bytes
-rw-r--r--aoc2023/build/dev/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@charlist.cache_metabin0 -> 29 bytes
-rw-r--r--aoc2023/build/dev/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@charlist.erl15
-rw-r--r--aoc2023/build/dev/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@file.cachebin0 -> 28770 bytes
-rw-r--r--aoc2023/build/dev/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@file.cache_metabin0 -> 72 bytes
-rw-r--r--aoc2023/build/dev/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@file.erl190
-rw-r--r--aoc2023/build/dev/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@node.cachebin0 -> 3128 bytes
-rw-r--r--aoc2023/build/dev/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@node.cache_metabin0 -> 54 bytes
-rw-r--r--aoc2023/build/dev/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@node.erl33
-rw-r--r--aoc2023/build/dev/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@os.cachebin0 -> 3355 bytes
-rw-r--r--aoc2023/build/dev/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@os.cache_metabin0 -> 46 bytes
-rw-r--r--aoc2023/build/dev/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@os.erl27
-rw-r--r--aoc2023/build/dev/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@process.cachebin0 -> 31850 bytes
-rw-r--r--aoc2023/build/dev/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@process.cache_metabin0 -> 115 bytes
-rw-r--r--aoc2023/build/dev/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@process.erl374
-rw-r--r--aoc2023/build/dev/erlang/gleam_erlang/_gleam_artefacts/gleam_erlang_ffi.erl263
-rw-r--r--aoc2023/build/dev/erlang/gleam_erlang/ebin/gleam@erlang.beambin0 -> 4304 bytes
-rw-r--r--aoc2023/build/dev/erlang/gleam_erlang/ebin/gleam@erlang@atom.beambin0 -> 1804 bytes
-rw-r--r--aoc2023/build/dev/erlang/gleam_erlang/ebin/gleam@erlang@charlist.beambin0 -> 1344 bytes
-rw-r--r--aoc2023/build/dev/erlang/gleam_erlang/ebin/gleam@erlang@file.beambin0 -> 5960 bytes
-rw-r--r--aoc2023/build/dev/erlang/gleam_erlang/ebin/gleam@erlang@node.beambin0 -> 1932 bytes
-rw-r--r--aoc2023/build/dev/erlang/gleam_erlang/ebin/gleam@erlang@os.beambin0 -> 1784 bytes
-rw-r--r--aoc2023/build/dev/erlang/gleam_erlang/ebin/gleam@erlang@process.beambin0 -> 14832 bytes
-rw-r--r--aoc2023/build/dev/erlang/gleam_erlang/ebin/gleam_erlang.app7
-rw-r--r--aoc2023/build/dev/erlang/gleam_erlang/ebin/gleam_erlang_ffi.beambin0 -> 13908 bytes
-rw-r--r--aoc2023/build/dev/erlang/gleam_erlang/include/gleam@erlang@file_FileInfo.hrl15
-rw-r--r--aoc2023/build/dev/erlang/gleam_erlang/include/gleam@erlang@process_Abnormal.hrl1
-rw-r--r--aoc2023/build/dev/erlang/gleam_erlang/include/gleam@erlang@process_CalleeDown.hrl1
-rw-r--r--aoc2023/build/dev/erlang/gleam_erlang/include/gleam@erlang@process_Cancelled.hrl1
-rw-r--r--aoc2023/build/dev/erlang/gleam_erlang/include/gleam@erlang@process_ExitMessage.hrl4
-rw-r--r--aoc2023/build/dev/erlang/gleam_erlang/include/gleam@erlang@process_ProcessDown.hrl4
-rw-r--r--aoc2023/build/dev/erlang/gleam_erlang/include/gleam@erlang@process_ProcessMonitor.hrl1
-rw-r--r--aoc2023/build/dev/erlang/gleam_erlang/include/gleam@erlang@process_Subject.hrl4
-rw-r--r--aoc2023/build/dev/erlang/gleam_erlang/include/gleam@erlang_ApplicationFailedToStart.hrl4
-rw-r--r--aoc2023/build/dev/erlang/gleam_erlang/include/gleam@erlang_UnknownApplication.hrl1
42 files changed, 1218 insertions, 0 deletions
diff --git a/aoc2023/build/dev/erlang/gleam_erlang/_gleam_artefacts/gleam@@compile.erl b/aoc2023/build/dev/erlang/gleam_erlang/_gleam_artefacts/gleam@@compile.erl
new file mode 100644
index 0000000..543db88
--- /dev/null
+++ b/aoc2023/build/dev/erlang/gleam_erlang/_gleam_artefacts/gleam@@compile.erl
@@ -0,0 +1,157 @@
+#!/usr/bin/env escript
+
+% TODO: Don't concurrently print warnings and errors
+% TODO: Some tests
+
+-record(arguments, {lib = "./", out = "./", modules = []}).
+
+main(Args) ->
+ #arguments{out = Out, lib = Lib, modules = Modules} = parse(Args),
+ IsElixirModule = fun(Module) ->
+ filename:extension(Module) =:= ".ex"
+ end,
+ {ElixirModules, ErlangModules} = lists:partition(IsElixirModule, Modules),
+ ok = configure_logging(),
+ ok = add_lib_to_erlang_path(Lib),
+ ok = filelib:ensure_dir([Out, $/]),
+ {ErlangOk, _ErlangBeams} = compile_erlang(ErlangModules, Out),
+ {ElixirOk, _ElixirBeams} = case ErlangOk of
+ true -> compile_elixir(ElixirModules, Out);
+ false -> {false, []}
+ end,
+ case ErlangOk and ElixirOk of
+ true -> ok;
+ false -> erlang:halt(1)
+ end.
+
+compile_erlang(Modules, Out) ->
+ Workers = start_compiler_workers(Out),
+ ok = producer_loop(Modules, Workers),
+ collect_results({true, []}).
+
+collect_results(Acc = {Result, Beams}) ->
+ receive
+ {compiled, Beam} -> collect_results({Result, [Beam | Beams]});
+ failed -> collect_results({false, Beams})
+ after 0 -> Acc
+ end.
+
+producer_loop([], 0) ->
+ ok;
+producer_loop([], Workers) ->
+ receive
+ {work_please, _} -> producer_loop([], Workers - 1)
+ end;
+producer_loop([Module | Modules], Workers) ->
+ receive
+ {work_please, Worker} ->
+ erlang:send(Worker, {module, Module}),
+ producer_loop(Modules, Workers)
+ end.
+
+start_compiler_workers(Out) ->
+ Parent = self(),
+ NumSchedulers = erlang:system_info(schedulers),
+ SpawnWorker = fun(_) ->
+ erlang:spawn_link(fun() -> worker_loop(Parent, Out) end)
+ end,
+ lists:foreach(SpawnWorker, lists:seq(1, NumSchedulers)),
+ NumSchedulers.
+
+worker_loop(Parent, Out) ->
+ Options = [report_errors, report_warnings, debug_info, {outdir, Out}],
+ erlang:send(Parent, {work_please, self()}),
+ receive
+ {module, Module} ->
+ log({compiling, Module}),
+ case compile:file(Module, Options) of
+ {ok, ModuleName} ->
+ Beam = filename:join(Out, ModuleName) ++ ".beam",
+ Message = {compiled, Beam},
+ log(Message),
+ erlang:send(Parent, Message);
+ error ->
+ log({failed, Module}),
+ erlang:send(Parent, failed)
+ end,
+ worker_loop(Parent, Out)
+ end.
+
+compile_elixir(Modules, Out) ->
+ Error = [
+ "The program elixir was not found. Is it installed?",
+ $\n,
+ "Documentation for installing Elixir can be viewed here:",
+ $\n,
+ "https://elixir-lang.org/install.html"
+ ],
+ case Modules of
+ [] -> {true, []};
+ _ ->
+ log({starting, "compiler.app"}),
+ ok = application:start(compiler),
+ log({starting, "elixir.app"}),
+ case application:start(elixir) of
+ ok -> do_compile_elixir(Modules, Out);
+ _ ->
+ io:put_chars(standard_error, [Error, $\n]),
+ {false, []}
+ end
+ end.
+
+do_compile_elixir(Modules, Out) ->
+ ModuleBins = lists:map(fun(Module) ->
+ log({compiling, Module}),
+ list_to_binary(Module)
+ end, Modules),
+ OutBin = list_to_binary(Out),
+ Options = [{dest, OutBin}],
+ % Silence "redefining module" warnings.
+ % Compiled modules in the build directory are added to the code path.
+ % These warnings result from recompiling loaded modules.
+ % TODO: This line can likely be removed if/when the build directory is cleaned before every compilation.
+ 'Elixir.Code':compiler_options([{ignore_module_conflict, true}]),
+ case 'Elixir.Kernel.ParallelCompiler':compile_to_path(ModuleBins, OutBin, Options) of
+ {ok, ModuleAtoms, _} ->
+ ToBeam = fun(ModuleAtom) ->
+ Beam = filename:join(Out, atom_to_list(ModuleAtom)) ++ ".beam",
+ log({compiled, Beam}),
+ Beam
+ end,
+ {true, lists:map(ToBeam, ModuleAtoms)};
+ {error, Errors, _} ->
+ % Log all filenames associated with modules that failed to compile.
+ % Note: The compiler prints compilation errors upon encountering them.
+ ErrorFiles = lists:usort([File || {File, _, _} <- Errors]),
+ Log = fun(File) ->
+ log({failed, binary_to_list(File)})
+ end,
+ lists:foreach(Log, ErrorFiles),
+ {false, []};
+ _ -> {false, []}
+ end.
+
+add_lib_to_erlang_path(Lib) ->
+ code:add_paths(filelib:wildcard([Lib, "/*/ebin"])).
+
+parse(Args) ->
+ parse(Args, #arguments{}).
+
+parse([], Arguments) ->
+ Arguments;
+parse(["--lib", Lib | Rest], Arguments) ->
+ parse(Rest, Arguments#arguments{lib = Lib});
+parse(["--out", Out | Rest], Arguments) ->
+ parse(Rest, Arguments#arguments{out = Out});
+parse([Module | Rest], Arguments = #arguments{modules = Modules}) ->
+ parse(Rest, Arguments#arguments{modules = [Module | Modules]}).
+
+configure_logging() ->
+ Enabled = os:getenv("GLEAM_LOG") /= false,
+ persistent_term:put(gleam_logging_enabled, Enabled).
+
+log(Term) ->
+ case persistent_term:get(gleam_logging_enabled) of
+ true -> erlang:display(Term), ok;
+ false -> ok
+ end.
diff --git a/aoc2023/build/dev/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang.cache b/aoc2023/build/dev/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang.cache
new file mode 100644
index 0000000..a136f2b
--- /dev/null
+++ b/aoc2023/build/dev/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang.cache
Binary files differ
diff --git a/aoc2023/build/dev/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang.cache_meta b/aoc2023/build/dev/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang.cache_meta
new file mode 100644
index 0000000..12933b2
--- /dev/null
+++ b/aoc2023/build/dev/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang.cache_meta
Binary files differ
diff --git a/aoc2023/build/dev/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang.erl b/aoc2023/build/dev/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang.erl
new file mode 100644
index 0000000..c689364
--- /dev/null
+++ b/aoc2023/build/dev/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang.erl
@@ -0,0 +1,90 @@
+-module(gleam@erlang).
+-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]).
+
+-export([format/1, term_to_binary/1, get_line/1, system_time/1, erlang_timestamp/0, rescue/1, binary_to_term/1, unsafe_binary_to_term/1, start_arguments/0, ensure_all_started/1, make_reference/0, priv_directory/1]).
+-export_type([safe/0, get_line_error/0, time_unit/0, crash/0, ensure_all_started_error/0, reference_/0]).
+
+-type safe() :: safe.
+
+-type get_line_error() :: eof | no_data.
+
+-type time_unit() :: second | millisecond | microsecond | nanosecond.
+
+-type crash() :: {exited, gleam@dynamic:dynamic_()} |
+ {thrown, gleam@dynamic:dynamic_()} |
+ {errored, gleam@dynamic:dynamic_()}.
+
+-type ensure_all_started_error() :: {unknown_application,
+ gleam@erlang@atom:atom_()} |
+ {application_failed_to_start,
+ gleam@erlang@atom:atom_(),
+ gleam@dynamic:dynamic_()}.
+
+-type reference_() :: any().
+
+-spec format(any()) -> binary().
+format(Term) ->
+ unicode:characters_to_binary(io_lib:format(<<"~p"/utf8>>, [Term])).
+
+-spec term_to_binary(any()) -> bitstring().
+term_to_binary(A) ->
+ erlang:term_to_binary(A).
+
+-spec get_line(binary()) -> {ok, binary()} | {error, get_line_error()}.
+get_line(Prompt) ->
+ gleam_erlang_ffi:get_line(Prompt).
+
+-spec system_time(time_unit()) -> integer().
+system_time(A) ->
+ os:system_time(A).
+
+-spec erlang_timestamp() -> {integer(), integer(), integer()}.
+erlang_timestamp() ->
+ os:timestamp().
+
+-spec rescue(fun(() -> GWM)) -> {ok, GWM} | {error, crash()}.
+rescue(A) ->
+ gleam_erlang_ffi:rescue(A).
+
+-spec binary_to_term(bitstring()) -> {ok, gleam@dynamic:dynamic_()} |
+ {error, nil}.
+binary_to_term(Binary) ->
+ case gleam_erlang_ffi:rescue(
+ fun() -> erlang:binary_to_term(Binary, [safe]) end
+ ) of
+ {ok, Term} ->
+ {ok, Term};
+
+ {error, _} ->
+ {error, nil}
+ end.
+
+-spec unsafe_binary_to_term(bitstring()) -> {ok, gleam@dynamic:dynamic_()} |
+ {error, nil}.
+unsafe_binary_to_term(Binary) ->
+ case gleam_erlang_ffi:rescue(fun() -> erlang:binary_to_term(Binary, []) end) of
+ {ok, Term} ->
+ {ok, Term};
+
+ {error, _} ->
+ {error, nil}
+ end.
+
+-spec start_arguments() -> list(binary()).
+start_arguments() ->
+ _pipe = init:get_plain_arguments(),
+ gleam@list:map(_pipe, fun unicode:characters_to_binary/1).
+
+-spec ensure_all_started(gleam@erlang@atom:atom_()) -> {ok,
+ list(gleam@erlang@atom:atom_())} |
+ {error, ensure_all_started_error()}.
+ensure_all_started(Application) ->
+ gleam_erlang_ffi:ensure_all_started(Application).
+
+-spec make_reference() -> reference_().
+make_reference() ->
+ erlang:make_ref().
+
+-spec priv_directory(binary()) -> {ok, binary()} | {error, nil}.
+priv_directory(Name) ->
+ gleam_erlang_ffi:priv_directory(Name).
diff --git a/aoc2023/build/dev/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@atom.cache b/aoc2023/build/dev/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@atom.cache
new file mode 100644
index 0000000..83a03cd
--- /dev/null
+++ b/aoc2023/build/dev/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@atom.cache
Binary files differ
diff --git a/aoc2023/build/dev/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@atom.cache_meta b/aoc2023/build/dev/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@atom.cache_meta
new file mode 100644
index 0000000..be33011
--- /dev/null
+++ b/aoc2023/build/dev/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@atom.cache_meta
Binary files differ
diff --git a/aoc2023/build/dev/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@atom.erl b/aoc2023/build/dev/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@atom.erl
new file mode 100644
index 0000000..f35c631
--- /dev/null
+++ b/aoc2023/build/dev/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@atom.erl
@@ -0,0 +1,26 @@
+-module(gleam@erlang@atom).
+-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]).
+
+-export([from_string/1, create_from_string/1, to_string/1, from_dynamic/1]).
+-export_type([atom_/0, from_string_error/0]).
+
+-type atom_() :: any().
+
+-type from_string_error() :: atom_not_loaded.
+
+-spec from_string(binary()) -> {ok, atom_()} | {error, from_string_error()}.
+from_string(A) ->
+ gleam_erlang_ffi:atom_from_string(A).
+
+-spec create_from_string(binary()) -> atom_().
+create_from_string(A) ->
+ erlang:binary_to_atom(A).
+
+-spec to_string(atom_()) -> binary().
+to_string(A) ->
+ erlang:atom_to_binary(A).
+
+-spec from_dynamic(gleam@dynamic:dynamic_()) -> {ok, atom_()} |
+ {error, list(gleam@dynamic:decode_error())}.
+from_dynamic(From) ->
+ gleam_erlang_ffi:atom_from_dynamic(From).
diff --git a/aoc2023/build/dev/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@charlist.cache b/aoc2023/build/dev/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@charlist.cache
new file mode 100644
index 0000000..b4053cc
--- /dev/null
+++ b/aoc2023/build/dev/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@charlist.cache
Binary files differ
diff --git a/aoc2023/build/dev/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@charlist.cache_meta b/aoc2023/build/dev/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@charlist.cache_meta
new file mode 100644
index 0000000..82cfdb5
--- /dev/null
+++ b/aoc2023/build/dev/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@charlist.cache_meta
Binary files differ
diff --git a/aoc2023/build/dev/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@charlist.erl b/aoc2023/build/dev/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@charlist.erl
new file mode 100644
index 0000000..dc1670d
--- /dev/null
+++ b/aoc2023/build/dev/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@charlist.erl
@@ -0,0 +1,15 @@
+-module(gleam@erlang@charlist).
+-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]).
+
+-export([to_string/1, from_string/1]).
+-export_type([charlist/0]).
+
+-type charlist() :: any().
+
+-spec to_string(charlist()) -> binary().
+to_string(A) ->
+ unicode:characters_to_binary(A).
+
+-spec from_string(binary()) -> charlist().
+from_string(A) ->
+ unicode:characters_to_list(A).
diff --git a/aoc2023/build/dev/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@file.cache b/aoc2023/build/dev/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@file.cache
new file mode 100644
index 0000000..b447be6
--- /dev/null
+++ b/aoc2023/build/dev/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@file.cache
Binary files differ
diff --git a/aoc2023/build/dev/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@file.cache_meta b/aoc2023/build/dev/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@file.cache_meta
new file mode 100644
index 0000000..1cb342b
--- /dev/null
+++ b/aoc2023/build/dev/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@file.cache_meta
Binary files differ
diff --git a/aoc2023/build/dev/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@file.erl b/aoc2023/build/dev/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@file.erl
new file mode 100644
index 0000000..396b31a
--- /dev/null
+++ b/aoc2023/build/dev/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@file.erl
@@ -0,0 +1,190 @@
+-module(gleam@erlang@file).
+-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]).
+
+-export([file_info/1, link_info/1, is_directory/1, is_regular/1, file_exists/1, link_exists/1, make_directory/1, list_directory/1, delete_directory/1, recursive_delete/1, read/1, read_bits/1, write/2, write_bits/2, append/2, append_bits/2, delete/1]).
+-export_type([reason/0, file_type/0, access/0, file_info/0]).
+
+-type reason() :: eacces |
+ eagain |
+ ebadf |
+ ebadmsg |
+ ebusy |
+ edeadlk |
+ edeadlock |
+ edquot |
+ eexist |
+ efault |
+ efbig |
+ eftype |
+ eintr |
+ einval |
+ eio |
+ eisdir |
+ eloop |
+ emfile |
+ emlink |
+ emultihop |
+ enametoolong |
+ enfile |
+ enobufs |
+ enodev |
+ enolck |
+ enolink |
+ enoent |
+ enomem |
+ enospc |
+ enosr |
+ enostr |
+ enosys |
+ enotblk |
+ enotdir |
+ enotsup |
+ enxio |
+ eopnotsupp |
+ eoverflow |
+ eperm |
+ epipe |
+ erange |
+ erofs |
+ espipe |
+ esrch |
+ estale |
+ etxtbsy |
+ exdev |
+ not_utf8.
+
+-type file_type() :: device | directory | other | regular | symlink.
+
+-type access() :: no_access | read | read_write | write.
+
+-type file_info() :: {file_info,
+ integer(),
+ file_type(),
+ access(),
+ integer(),
+ integer(),
+ integer(),
+ integer(),
+ integer(),
+ integer(),
+ integer(),
+ integer(),
+ integer(),
+ integer()}.
+
+-spec file_info(binary()) -> {ok, file_info()} | {error, reason()}.
+file_info(A) ->
+ gleam_erlang_ffi:file_info(A).
+
+-spec link_info(binary()) -> {ok, file_info()} | {error, reason()}.
+link_info(A) ->
+ gleam_erlang_ffi:link_info(A).
+
+-spec is_directory(binary()) -> {ok, boolean()} | {error, reason()}.
+is_directory(Path) ->
+ gleam@result:map(
+ gleam_erlang_ffi:file_info(Path),
+ fun(_use0) ->
+ {file_info, _, File_type, _, _, _, _, _, _, _, _, _, _, _} = _use0,
+ File_type =:= directory
+ end
+ ).
+
+-spec is_regular(binary()) -> {ok, boolean()} | {error, reason()}.
+is_regular(Path) ->
+ gleam@result:map(
+ gleam_erlang_ffi:file_info(Path),
+ fun(_use0) ->
+ {file_info, _, File_type, _, _, _, _, _, _, _, _, _, _, _} = _use0,
+ File_type =:= regular
+ end
+ ).
+
+-spec file_exists(binary()) -> {ok, boolean()} | {error, reason()}.
+file_exists(Path) ->
+ Result = begin
+ _pipe = Path,
+ _pipe@1 = gleam_erlang_ffi:file_info(_pipe),
+ gleam@result:replace(_pipe@1, true)
+ end,
+ case Result of
+ {error, enoent} ->
+ {ok, false};
+
+ _ ->
+ Result
+ end.
+
+-spec link_exists(binary()) -> {ok, boolean()} | {error, reason()}.
+link_exists(Path) ->
+ Result = begin
+ _pipe = Path,
+ _pipe@1 = gleam_erlang_ffi:link_info(_pipe),
+ gleam@result:replace(_pipe@1, true)
+ end,
+ case Result of
+ {error, enoent} ->
+ {ok, false};
+
+ _ ->
+ Result
+ end.
+
+-spec make_directory(binary()) -> {ok, nil} | {error, reason()}.
+make_directory(A) ->
+ gleam_erlang_ffi:make_directory(A).
+
+-spec list_directory(binary()) -> {ok, list(binary())} | {error, reason()}.
+list_directory(A) ->
+ gleam_erlang_ffi:list_directory(A).
+
+-spec delete_directory(binary()) -> {ok, nil} | {error, reason()}.
+delete_directory(A) ->
+ gleam_erlang_ffi:delete_directory(A).
+
+-spec recursive_delete(binary()) -> {ok, nil} | {error, reason()}.
+recursive_delete(A) ->
+ gleam_erlang_ffi:recursive_delete(A).
+
+-spec read(binary()) -> {ok, binary()} | {error, reason()}.
+read(Path) ->
+ _pipe = Path,
+ _pipe@1 = gleam_erlang_ffi:read_file(_pipe),
+ gleam@result:then(
+ _pipe@1,
+ fun(Content) -> case gleam@bit_array:to_string(Content) of
+ {ok, String} ->
+ {ok, String};
+
+ {error, nil} ->
+ {error, not_utf8}
+ end end
+ ).
+
+-spec read_bits(binary()) -> {ok, bitstring()} | {error, reason()}.
+read_bits(Path) ->
+ gleam_erlang_ffi:read_file(Path).
+
+-spec write(binary(), binary()) -> {ok, nil} | {error, reason()}.
+write(Contents, Path) ->
+ _pipe = Contents,
+ _pipe@1 = gleam_stdlib:identity(_pipe),
+ gleam_erlang_ffi:write_file(_pipe@1, Path).
+
+-spec write_bits(bitstring(), binary()) -> {ok, nil} | {error, reason()}.
+write_bits(Contents, Path) ->
+ gleam_erlang_ffi:write_file(Contents, Path).
+
+-spec append(binary(), binary()) -> {ok, nil} | {error, reason()}.
+append(Contents, Path) ->
+ _pipe = Contents,
+ _pipe@1 = gleam_stdlib:identity(_pipe),
+ gleam_erlang_ffi:append_file(_pipe@1, Path).
+
+-spec append_bits(bitstring(), binary()) -> {ok, nil} | {error, reason()}.
+append_bits(Contents, Path) ->
+ gleam_erlang_ffi:append_file(Contents, Path).
+
+-spec delete(binary()) -> {ok, nil} | {error, reason()}.
+delete(A) ->
+ gleam_erlang_ffi:delete_file(A).
diff --git a/aoc2023/build/dev/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@node.cache b/aoc2023/build/dev/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@node.cache
new file mode 100644
index 0000000..acd84e1
--- /dev/null
+++ b/aoc2023/build/dev/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@node.cache
Binary files differ
diff --git a/aoc2023/build/dev/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@node.cache_meta b/aoc2023/build/dev/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@node.cache_meta
new file mode 100644
index 0000000..085886a
--- /dev/null
+++ b/aoc2023/build/dev/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@node.cache_meta
Binary files differ
diff --git a/aoc2023/build/dev/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@node.erl b/aoc2023/build/dev/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@node.erl
new file mode 100644
index 0000000..e421e84
--- /dev/null
+++ b/aoc2023/build/dev/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@node.erl
@@ -0,0 +1,33 @@
+-module(gleam@erlang@node).
+-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]).
+
+-export([self/0, visible/0, connect/1, send/3, to_atom/1]).
+-export_type([node_/0, do_not_leak/0, connect_error/0]).
+
+-type node_() :: any().
+
+-type do_not_leak() :: any().
+
+-type connect_error() :: failed_to_connect | local_node_is_not_alive.
+
+-spec self() -> node_().
+self() ->
+ erlang:node().
+
+-spec visible() -> list(node_()).
+visible() ->
+ erlang:nodes().
+
+-spec connect(gleam@erlang@atom:atom_()) -> {ok, node_()} |
+ {error, connect_error()}.
+connect(Node) ->
+ gleam_erlang_ffi:connect_node(Node).
+
+-spec send(node_(), gleam@erlang@atom:atom_(), any()) -> nil.
+send(Node, Name, Message) ->
+ erlang:send({Name, Node}, Message),
+ nil.
+
+-spec to_atom(node_()) -> gleam@erlang@atom:atom_().
+to_atom(Node) ->
+ gleam_erlang_ffi:identity(Node).
diff --git a/aoc2023/build/dev/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@os.cache b/aoc2023/build/dev/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@os.cache
new file mode 100644
index 0000000..c7698fa
--- /dev/null
+++ b/aoc2023/build/dev/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@os.cache
Binary files differ
diff --git a/aoc2023/build/dev/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@os.cache_meta b/aoc2023/build/dev/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@os.cache_meta
new file mode 100644
index 0000000..1d5fa83
--- /dev/null
+++ b/aoc2023/build/dev/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@os.cache_meta
Binary files differ
diff --git a/aoc2023/build/dev/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@os.erl b/aoc2023/build/dev/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@os.erl
new file mode 100644
index 0000000..27bc111
--- /dev/null
+++ b/aoc2023/build/dev/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@os.erl
@@ -0,0 +1,27 @@
+-module(gleam@erlang@os).
+-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]).
+
+-export([get_all_env/0, get_env/1, set_env/2, unset_env/1, family/0]).
+-export_type([os_family/0]).
+
+-type os_family() :: windows_nt | linux | darwin | free_bsd | {other, binary()}.
+
+-spec get_all_env() -> gleam@dict:dict(binary(), binary()).
+get_all_env() ->
+ gleam_erlang_ffi:get_all_env().
+
+-spec get_env(binary()) -> {ok, binary()} | {error, nil}.
+get_env(Name) ->
+ gleam_erlang_ffi:get_env(Name).
+
+-spec set_env(binary(), binary()) -> nil.
+set_env(Name, Value) ->
+ gleam_erlang_ffi:set_env(Name, Value).
+
+-spec unset_env(binary()) -> nil.
+unset_env(Name) ->
+ gleam_erlang_ffi:unset_env(Name).
+
+-spec family() -> os_family().
+family() ->
+ gleam_erlang_ffi:os_family().
diff --git a/aoc2023/build/dev/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@process.cache b/aoc2023/build/dev/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@process.cache
new file mode 100644
index 0000000..bb95436
--- /dev/null
+++ b/aoc2023/build/dev/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@process.cache
Binary files differ
diff --git a/aoc2023/build/dev/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@process.cache_meta b/aoc2023/build/dev/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@process.cache_meta
new file mode 100644
index 0000000..ad9209c
--- /dev/null
+++ b/aoc2023/build/dev/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@process.cache_meta
Binary files differ
diff --git a/aoc2023/build/dev/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@process.erl b/aoc2023/build/dev/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@process.erl
new file mode 100644
index 0000000..f8562ef
--- /dev/null
+++ b/aoc2023/build/dev/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@process.erl
@@ -0,0 +1,374 @@
+-module(gleam@erlang@process).
+-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]).
+
+-export([self/0, start/2, new_subject/0, subject_owner/1, send/2, new_selector/0, select/2, select_forever/1, map_selector/2, merge_selector/2, flush_messages/0, selecting_trapped_exits/2, selecting/3, 'receive'/2, selecting_record2/3, selecting_record3/3, selecting_record4/3, selecting_record5/3, selecting_record6/3, selecting_record7/3, selecting_record8/3, selecting_anything/2, sleep/1, sleep_forever/0, is_alive/1, monitor_process/1, selecting_process_down/3, demonitor_process/1, try_call/3, call/3, link/1, unlink/1, send_after/3, cancel_timer/1, kill/1, send_exit/1, send_abnormal_exit/2, trap_exits/1, register/2, unregister/1, named/1]).
+-export_type([pid_/0, subject/1, do_not_leak/0, selector/1, exit_message/0, exit_reason/0, anything_selector_tag/0, process_monitor_flag/0, process_monitor/0, process_down/0, call_error/1, timer/0, cancelled/0, kill_flag/0]).
+
+-type pid_() :: any().
+
+-opaque subject(GYI) :: {subject, pid_(), gleam@erlang:reference_()} |
+ {gleam_phantom, GYI}.
+
+-type do_not_leak() :: any().
+
+-type selector(GYJ) :: any() | {gleam_phantom, GYJ}.
+
+-type exit_message() :: {exit_message, pid_(), exit_reason()}.
+
+-type exit_reason() :: normal | killed | {abnormal, binary()}.
+
+-type anything_selector_tag() :: anything.
+
+-type process_monitor_flag() :: process.
+
+-opaque process_monitor() :: {process_monitor, gleam@erlang:reference_()}.
+
+-type process_down() :: {process_down, pid_(), gleam@dynamic:dynamic_()}.
+
+-type call_error(GYK) :: {callee_down, gleam@dynamic:dynamic_()} |
+ call_timeout |
+ {gleam_phantom, GYK}.
+
+-type timer() :: any().
+
+-type cancelled() :: timer_not_found | {cancelled, integer()}.
+
+-type kill_flag() :: kill.
+
+-spec self() -> pid_().
+self() ->
+ erlang:self().
+
+-spec start(fun(() -> any()), boolean()) -> pid_().
+start(Implementation, Link) ->
+ case Link of
+ true ->
+ erlang:spawn_link(Implementation);
+
+ false ->
+ erlang:spawn(Implementation)
+ end.
+
+-spec new_subject() -> subject(any()).
+new_subject() ->
+ {subject, erlang:self(), erlang:make_ref()}.
+
+-spec subject_owner(subject(any())) -> pid_().
+subject_owner(Subject) ->
+ erlang:element(2, Subject).
+
+-spec send(subject(GYT), GYT) -> nil.
+send(Subject, Message) ->
+ erlang:send(
+ erlang:element(2, Subject),
+ {erlang:element(3, Subject), Message}
+ ),
+ nil.
+
+-spec new_selector() -> selector(any()).
+new_selector() ->
+ gleam_erlang_ffi:new_selector().
+
+-spec select(selector(GZB), integer()) -> {ok, GZB} | {error, nil}.
+select(From, Within) ->
+ gleam_erlang_ffi:select(From, Within).
+
+-spec select_forever(selector(GZF)) -> GZF.
+select_forever(From) ->
+ gleam_erlang_ffi:select(From).
+
+-spec map_selector(selector(GZH), fun((GZH) -> GZJ)) -> selector(GZJ).
+map_selector(A, B) ->
+ gleam_erlang_ffi:map_selector(A, B).
+
+-spec merge_selector(selector(GZL), selector(GZL)) -> selector(GZL).
+merge_selector(A, B) ->
+ gleam_erlang_ffi:merge_selector(A, B).
+
+-spec flush_messages() -> nil.
+flush_messages() ->
+ gleam_erlang_ffi:flush_messages().
+
+-spec selecting_trapped_exits(selector(GZP), fun((exit_message()) -> GZP)) -> selector(GZP).
+selecting_trapped_exits(Selector, Handler) ->
+ Tag = erlang:binary_to_atom(<<"EXIT"/utf8>>),
+ Handler@1 = fun(Message) ->
+ Reason = erlang:element(3, Message),
+ Normal = gleam@dynamic:from(normal),
+ Killed = gleam@dynamic:from(killed),
+ Reason@2 = case gleam@dynamic:string(Reason) of
+ _ when Reason =:= Normal ->
+ normal;
+
+ _ when Reason =:= Killed ->
+ killed;
+
+ {ok, Reason@1} ->
+ {abnormal, Reason@1};
+
+ {error, _} ->
+ {abnormal, gleam@string:inspect(Reason)}
+ end,
+ Handler({exit_message, erlang:element(2, Message), Reason@2})
+ end,
+ gleam_erlang_ffi:insert_selector_handler(Selector, {Tag, 3}, Handler@1).
+
+-spec selecting(selector(GZS), subject(GZU), fun((GZU) -> GZS)) -> selector(GZS).
+selecting(Selector, Subject, Transform) ->
+ Handler = fun(Message) -> Transform(erlang:element(2, Message)) end,
+ gleam_erlang_ffi:insert_selector_handler(
+ Selector,
+ {erlang:element(3, Subject), 2},
+ Handler
+ ).
+
+-spec 'receive'(subject(GYV), integer()) -> {ok, GYV} | {error, nil}.
+'receive'(Subject, Milliseconds) ->
+ _pipe = gleam_erlang_ffi:new_selector(),
+ _pipe@1 = selecting(_pipe, Subject, fun(X) -> X end),
+ gleam_erlang_ffi:select(_pipe@1, Milliseconds).
+
+-spec selecting_record2(
+ selector(GZX),
+ any(),
+ fun((gleam@dynamic:dynamic_()) -> GZX)
+) -> selector(GZX).
+selecting_record2(Selector, Tag, Transform) ->
+ Handler = fun(Message) -> Transform(erlang:element(2, Message)) end,
+ gleam_erlang_ffi:insert_selector_handler(Selector, {Tag, 2}, Handler).
+
+-spec selecting_record3(
+ selector(HAB),
+ any(),
+ fun((gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_()) -> HAB)
+) -> selector(HAB).
+selecting_record3(Selector, Tag, Transform) ->
+ Handler = fun(Message) ->
+ Transform(erlang:element(2, Message), erlang:element(3, Message))
+ end,
+ gleam_erlang_ffi:insert_selector_handler(Selector, {Tag, 3}, Handler).
+
+-spec selecting_record4(
+ selector(HAF),
+ any(),
+ fun((gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_()) -> HAF)
+) -> selector(HAF).
+selecting_record4(Selector, Tag, Transform) ->
+ Handler = fun(Message) ->
+ Transform(
+ erlang:element(2, Message),
+ erlang:element(3, Message),
+ erlang:element(4, Message)
+ )
+ end,
+ gleam_erlang_ffi:insert_selector_handler(Selector, {Tag, 4}, Handler).
+
+-spec selecting_record5(
+ selector(HAJ),
+ any(),
+ fun((gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_()) -> HAJ)
+) -> selector(HAJ).
+selecting_record5(Selector, Tag, Transform) ->
+ Handler = fun(Message) ->
+ Transform(
+ erlang:element(2, Message),
+ erlang:element(3, Message),
+ erlang:element(4, Message),
+ erlang:element(5, Message)
+ )
+ end,
+ gleam_erlang_ffi:insert_selector_handler(Selector, {Tag, 5}, Handler).
+
+-spec selecting_record6(
+ selector(HAN),
+ any(),
+ fun((gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_()) -> HAN)
+) -> selector(HAN).
+selecting_record6(Selector, Tag, Transform) ->
+ Handler = fun(Message) ->
+ Transform(
+ erlang:element(2, Message),
+ erlang:element(3, Message),
+ erlang:element(4, Message),
+ erlang:element(5, Message),
+ erlang:element(6, Message)
+ )
+ end,
+ gleam_erlang_ffi:insert_selector_handler(Selector, {Tag, 6}, Handler).
+
+-spec selecting_record7(
+ selector(HAR),
+ any(),
+ fun((gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_()) -> HAR)
+) -> selector(HAR).
+selecting_record7(Selector, Tag, Transform) ->
+ Handler = fun(Message) ->
+ Transform(
+ erlang:element(2, Message),
+ erlang:element(3, Message),
+ erlang:element(4, Message),
+ erlang:element(5, Message),
+ erlang:element(6, Message),
+ erlang:element(7, Message)
+ )
+ end,
+ gleam_erlang_ffi:insert_selector_handler(Selector, {Tag, 7}, Handler).
+
+-spec selecting_record8(
+ selector(HAV),
+ any(),
+ fun((gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_()) -> HAV)
+) -> selector(HAV).
+selecting_record8(Selector, Tag, Transform) ->
+ Handler = fun(Message) ->
+ Transform(
+ erlang:element(2, Message),
+ erlang:element(3, Message),
+ erlang:element(4, Message),
+ erlang:element(5, Message),
+ erlang:element(6, Message),
+ erlang:element(7, Message),
+ erlang:element(8, Message)
+ )
+ end,
+ gleam_erlang_ffi:insert_selector_handler(Selector, {Tag, 8}, Handler).
+
+-spec selecting_anything(selector(HAZ), fun((gleam@dynamic:dynamic_()) -> HAZ)) -> selector(HAZ).
+selecting_anything(Selector, Handler) ->
+ gleam_erlang_ffi:insert_selector_handler(Selector, anything, Handler).
+
+-spec sleep(integer()) -> nil.
+sleep(A) ->
+ gleam_erlang_ffi:sleep(A).
+
+-spec sleep_forever() -> nil.
+sleep_forever() ->
+ gleam_erlang_ffi:sleep_forever().
+
+-spec is_alive(pid_()) -> boolean().
+is_alive(A) ->
+ erlang:is_process_alive(A).
+
+-spec monitor_process(pid_()) -> process_monitor().
+monitor_process(Pid) ->
+ _pipe = process,
+ _pipe@1 = erlang:monitor(_pipe, Pid),
+ {process_monitor, _pipe@1}.
+
+-spec selecting_process_down(
+ selector(HBH),
+ process_monitor(),
+ fun((process_down()) -> HBH)
+) -> selector(HBH).
+selecting_process_down(Selector, Monitor, Mapping) ->
+ gleam_erlang_ffi:insert_selector_handler(
+ Selector,
+ erlang:element(2, Monitor),
+ Mapping
+ ).
+
+-spec demonitor_process(process_monitor()) -> nil.
+demonitor_process(Monitor) ->
+ gleam_erlang_ffi:demonitor(Monitor).
+
+-spec try_call(subject(HBK), fun((subject(HBM)) -> HBK), integer()) -> {ok, HBM} |
+ {error, call_error(HBM)}.
+try_call(Subject, Make_request, Timeout) ->
+ Reply_subject = new_subject(),
+ Monitor = monitor_process(subject_owner(Subject)),
+ send(Subject, Make_request(Reply_subject)),
+ Result = begin
+ _pipe = gleam_erlang_ffi:new_selector(),
+ _pipe@1 = selecting(
+ _pipe,
+ Reply_subject,
+ fun(Field@0) -> {ok, Field@0} end
+ ),
+ _pipe@2 = selecting_process_down(
+ _pipe@1,
+ Monitor,
+ fun(Down) -> {error, {callee_down, erlang:element(3, Down)}} end
+ ),
+ gleam_erlang_ffi:select(_pipe@2, Timeout)
+ end,
+ gleam_erlang_ffi:demonitor(Monitor),
+ case Result of
+ {error, nil} ->
+ {error, call_timeout};
+
+ {ok, Res} ->
+ Res
+ end.
+
+-spec call(subject(HBR), fun((subject(HBT)) -> HBR), integer()) -> HBT.
+call(Subject, Make_request, Timeout) ->
+ _assert_subject = try_call(Subject, Make_request, Timeout),
+ {ok, Resp} = case _assert_subject of
+ {ok, _} -> _assert_subject;
+ _assert_fail ->
+ erlang:error(#{gleam_error => let_assert,
+ message => <<"Assertion pattern match failed"/utf8>>,
+ value => _assert_fail,
+ module => <<"gleam/erlang/process"/utf8>>,
+ function => <<"call"/utf8>>,
+ line => 593})
+ end,
+ Resp.
+
+-spec link(pid_()) -> boolean().
+link(Pid) ->
+ gleam_erlang_ffi:link(Pid).
+
+-spec unlink(pid_()) -> nil.
+unlink(Pid) ->
+ erlang:unlink(Pid),
+ nil.
+
+-spec send_after(subject(HBW), integer(), HBW) -> timer().
+send_after(Subject, Delay, Message) ->
+ erlang:send_after(
+ Delay,
+ erlang:element(2, Subject),
+ {erlang:element(3, Subject), Message}
+ ).
+
+-spec cancel_timer(timer()) -> cancelled().
+cancel_timer(Timer) ->
+ case gleam@dynamic:int(erlang:cancel_timer(Timer)) of
+ {ok, I} ->
+ {cancelled, I};
+
+ {error, _} ->
+ timer_not_found
+ end.
+
+-spec kill(pid_()) -> nil.
+kill(Pid) ->
+ erlang:exit(Pid, kill),
+ nil.
+
+-spec send_exit(pid_()) -> nil.
+send_exit(Pid) ->
+ erlang:exit(Pid, normal),
+ nil.
+
+-spec send_abnormal_exit(pid_(), binary()) -> nil.
+send_abnormal_exit(Pid, Reason) ->
+ erlang:exit(Pid, {abnormal, Reason}),
+ nil.
+
+-spec trap_exits(boolean()) -> nil.
+trap_exits(A) ->
+ gleam_erlang_ffi:trap_exits(A).
+
+-spec register(pid_(), gleam@erlang@atom:atom_()) -> {ok, nil} | {error, nil}.
+register(Pid, Name) ->
+ gleam_erlang_ffi:register_process(Pid, Name).
+
+-spec unregister(gleam@erlang@atom:atom_()) -> {ok, nil} | {error, nil}.
+unregister(Name) ->
+ gleam_erlang_ffi:unregister_process(Name).
+
+-spec named(gleam@erlang@atom:atom_()) -> {ok, pid_()} | {error, nil}.
+named(Name) ->
+ gleam_erlang_ffi:process_named(Name).
diff --git a/aoc2023/build/dev/erlang/gleam_erlang/_gleam_artefacts/gleam_erlang_ffi.erl b/aoc2023/build/dev/erlang/gleam_erlang/_gleam_artefacts/gleam_erlang_ffi.erl
new file mode 100644
index 0000000..872126f
--- /dev/null
+++ b/aoc2023/build/dev/erlang/gleam_erlang/_gleam_artefacts/gleam_erlang_ffi.erl
@@ -0,0 +1,263 @@
+-module(gleam_erlang_ffi).
+-export([
+ atom_from_dynamic/1, rescue/1, atom_from_string/1, get_line/1,
+ ensure_all_started/1, sleep/1, os_family/0, sleep_forever/0, read_file/1,
+ append_file/2, write_file/2, delete_file/1, get_all_env/0, get_env/1,
+ set_env/2, unset_env/1, delete_directory/1, recursive_delete/1,
+ list_directory/1, demonitor/1, make_directory/1, new_selector/0, link/1,
+ insert_selector_handler/3, select/1, select/2, trap_exits/1, map_selector/2,
+ merge_selector/2, flush_messages/0, file_info/1, link_info/1,
+ priv_directory/1, connect_node/1, register_process/2, unregister_process/1,
+ process_named/1, identity/1
+]).
+
+-define(is_posix_error(Error),
+ Error =:= eacces orelse Error =:= eagain orelse Error =:= ebadf orelse
+ Error =:= ebadmsg orelse Error =:= ebusy orelse Error =:= edeadlk orelse
+ Error =:= edeadlock orelse Error =:= edquot orelse Error =:= eexist orelse
+ Error =:= efault orelse Error =:= efbig orelse Error =:= eftype orelse
+ Error =:= eintr orelse Error =:= einval orelse Error =:= eio orelse
+ Error =:= eisdir orelse Error =:= eloop orelse Error =:= emfile orelse
+ Error =:= emlink orelse Error =:= emultihop orelse Error =:= enametoolong orelse
+ Error =:= enfile orelse Error =:= enobufs orelse Error =:= enodev orelse
+ Error =:= enolck orelse Error =:= enolink orelse Error =:= enoent orelse
+ Error =:= enomem orelse Error =:= enospc orelse Error =:= enosr orelse
+ Error =:= enostr orelse Error =:= enosys orelse Error =:= enotblk orelse
+ Error =:= enotdir orelse Error =:= enotsup orelse Error =:= enxio orelse
+ Error =:= eopnotsupp orelse Error =:= eoverflow orelse Error =:= eperm orelse
+ Error =:= epipe orelse Error =:= erange orelse Error =:= erofs orelse
+ Error =:= espipe orelse Error =:= esrch orelse Error =:= estale orelse
+ Error =:= etxtbsy orelse Error =:= exdev
+).
+
+-spec atom_from_string(binary()) -> {ok, atom()} | {error, atom_not_loaded}.
+atom_from_string(S) ->
+ try {ok, binary_to_existing_atom(S)}
+ catch error:badarg -> {error, atom_not_loaded}
+ end.
+
+atom_from_dynamic(Data) when is_atom(Data) ->
+ {ok, Data};
+atom_from_dynamic(Data) ->
+ {error, [{decode_error, <<"Atom">>, gleam@dynamic:classify(Data), []}]}.
+
+-spec get_line(io:prompt()) -> {ok, unicode:unicode_binary()} | {error, eof | no_data}.
+get_line(Prompt) ->
+ case io:get_line(Prompt) of
+ eof -> {error, eof};
+ {error, _} -> {error, no_data};
+ Data when is_binary(Data) -> {ok, Data};
+ Data when is_list(Data) -> {ok, unicode:characters_to_binary(Data)}
+ end.
+
+rescue(F) ->
+ try {ok, F()}
+ catch
+ throw:X -> {error, {thrown, X}};
+ error:X -> {error, {errored, X}};
+ exit:X -> {error, {exited, X}}
+ end.
+
+ensure_all_started(Application) ->
+ case application:ensure_all_started(Application) of
+ {ok, _} = Ok -> Ok;
+
+ {error, {ProblemApp, {"no such file or directory", _}}} ->
+ {error, {unknown_application, ProblemApp}}
+ end.
+
+sleep(Microseconds) ->
+ timer:sleep(Microseconds),
+ nil.
+
+sleep_forever() ->
+ timer:sleep(infinity),
+ nil.
+
+file_info_result(Result) ->
+ case Result of
+ {ok, {file_info, Size, Type, Access, Atime, Mtime, Ctime, Mode, Links, MajorDevice, MinorDevice, Inode, Uid, Gid}} when Access =:= none ->
+ {ok, {file_info, Size, Type, no_access, Atime, Mtime, Ctime, Mode, Links, MajorDevice, MinorDevice, Inode, Uid, Gid}};
+ {ok, _} ->
+ Result;
+ {error, Reason} when ?is_posix_error(Reason) ->
+ Result
+ end.
+
+file_info(Filename) ->
+ file_info_result(file:read_file_info(Filename, [{time, posix}])).
+
+link_info(Filename) ->
+ file_info_result(file:read_link_info(Filename, [{time, posix}])).
+
+posix_result(Result) ->
+ case Result of
+ ok -> {ok, nil};
+ {ok, Value} -> {ok, Value};
+ {error, Reason} when ?is_posix_error(Reason) -> {error, Reason}
+ end.
+
+read_file(Filename) ->
+ posix_result(file:read_file(Filename)).
+
+write_file(Contents, Filename) ->
+ posix_result(file:write_file(Filename, Contents)).
+
+append_file(Contents, Filename) ->
+ posix_result(file:write_file(Filename, Contents, [append])).
+
+delete_file(Filename) ->
+ posix_result(file:delete(Filename)).
+
+make_directory(Dir) ->
+ posix_result(file:make_dir(Dir)).
+
+list_directory(Dir) ->
+ case file:list_dir(Dir) of
+ {ok, Filenames} ->
+ {ok, [list_to_binary(Filename) || Filename <- Filenames]};
+ {error, Reason} when ?is_posix_error(Reason) ->
+ {error, Reason}
+ end.
+
+delete_directory(Dir) ->
+ posix_result(file:del_dir(Dir)).
+
+recursive_delete(Dir) ->
+ posix_result(file:del_dir_r(Dir)).
+
+get_all_env() ->
+ BinVars = lists:map(fun(VarString) ->
+ [VarName, VarVal] = string:split(VarString, "="),
+ {list_to_binary(VarName), list_to_binary(VarVal)}
+ end, os:getenv()),
+ maps:from_list(BinVars).
+
+get_env(Name) ->
+ case os:getenv(binary_to_list(Name)) of
+ false -> {error, nil};
+ Value -> {ok, list_to_binary(Value)}
+ end.
+
+set_env(Name, Value) ->
+ os:putenv(binary_to_list(Name), binary_to_list(Value)),
+ nil.
+
+unset_env(Name) ->
+ os:unsetenv(binary_to_list(Name)),
+ nil.
+
+os_family() ->
+ case os:type() of
+ {win32, nt} ->
+ windows_nt;
+ {unix, linux} ->
+ linux;
+ {unix, darwin} ->
+ darwin;
+ {unix, freebsd} ->
+ free_bsd;
+ {_, Other} ->
+ {other, atom_to_binary(Other, utf8)}
+ end.
+
+new_selector() ->
+ {selector, #{}}.
+
+map_selector({selector, Handlers}, Fn) ->
+ MappedHandlers = maps:map(fun(_Tag, Handler) ->
+ fun(Message) -> Fn(Handler(Message)) end
+ end, Handlers),
+ {selector, MappedHandlers}.
+
+merge_selector({selector, HandlersA}, {selector, HandlersB}) ->
+ {selector, maps:merge(HandlersA, HandlersB)}.
+
+insert_selector_handler({selector, Handlers}, Tag, Fn) ->
+ {selector, Handlers#{Tag => Fn}}.
+
+select(Selector) ->
+ {ok, Message} = select(Selector, infinity),
+ Message.
+
+select({selector, Handlers}, Timeout) ->
+ AnythingHandler = maps:get(anything, Handlers, undefined),
+ receive
+ % Monitored process down messages.
+ % This is special cased so we can selectively receive based on the
+ % reference as well as the record tag.
+ {'DOWN', Ref, process, Pid, Reason} when is_map_key(Ref, Handlers) ->
+ Fn = maps:get(Ref, Handlers),
+ {ok, Fn({process_down, Pid, Reason})};
+
+ Msg when is_map_key({element(1, Msg), tuple_size(Msg)}, Handlers) ->
+ Fn = maps:get({element(1, Msg), tuple_size(Msg)}, Handlers),
+ {ok, Fn(Msg)};
+
+ Msg when AnythingHandler =/= undefined ->
+ {ok, AnythingHandler(Msg)}
+ after Timeout ->
+ {error, nil}
+ end.
+
+demonitor({_, Reference}) ->
+ erlang:demonitor(Reference, [flush]).
+
+link(Pid) ->
+ try
+ erlang:link(Pid)
+ catch
+ error:_ -> false
+ end.
+
+trap_exits(ShouldTrap) ->
+ erlang:process_flag(trap_exit, ShouldTrap),
+ nil.
+
+flush_messages() ->
+ receive _Message -> flush_messages()
+ after 0 -> nil
+ end.
+
+priv_directory(Name) ->
+ try erlang:binary_to_existing_atom(Name) of
+ Atom ->
+ case code:priv_dir(Atom) of
+ {error, _} -> {error, nil};
+ Path -> {ok, unicode:characters_to_binary(Path)}
+ end
+ catch
+ error:badarg -> {error, nil}
+ end.
+
+connect_node(Node) ->
+ case net_kernel:connect_node(Node) of
+ true -> {ok, Node};
+ false -> {error, failed_to_connect};
+ ignored -> {error, local_node_is_not_alive}
+ end.
+
+register_process(Pid, Name) ->
+ try
+ true = erlang:register(Name, Pid),
+ {ok, nil}
+ catch
+ error:badarg -> {error, nil}
+ end.
+
+unregister_process(Name) ->
+ try
+ true = erlang:unregister(Name),
+ {ok, nil}
+ catch
+ error:badarg -> {error, nil}
+ end.
+
+process_named(Name) ->
+ case erlang:whereis(Name) of
+ Pid when is_pid(Pid) -> {ok, Pid};
+ _ -> {error, nil}
+ end.
+
+identity(X) ->
+ X.
diff --git a/aoc2023/build/dev/erlang/gleam_erlang/ebin/gleam@erlang.beam b/aoc2023/build/dev/erlang/gleam_erlang/ebin/gleam@erlang.beam
new file mode 100644
index 0000000..9f714eb
--- /dev/null
+++ b/aoc2023/build/dev/erlang/gleam_erlang/ebin/gleam@erlang.beam
Binary files differ
diff --git a/aoc2023/build/dev/erlang/gleam_erlang/ebin/gleam@erlang@atom.beam b/aoc2023/build/dev/erlang/gleam_erlang/ebin/gleam@erlang@atom.beam
new file mode 100644
index 0000000..a85b4fa
--- /dev/null
+++ b/aoc2023/build/dev/erlang/gleam_erlang/ebin/gleam@erlang@atom.beam
Binary files differ
diff --git a/aoc2023/build/dev/erlang/gleam_erlang/ebin/gleam@erlang@charlist.beam b/aoc2023/build/dev/erlang/gleam_erlang/ebin/gleam@erlang@charlist.beam
new file mode 100644
index 0000000..6d78db3
--- /dev/null
+++ b/aoc2023/build/dev/erlang/gleam_erlang/ebin/gleam@erlang@charlist.beam
Binary files differ
diff --git a/aoc2023/build/dev/erlang/gleam_erlang/ebin/gleam@erlang@file.beam b/aoc2023/build/dev/erlang/gleam_erlang/ebin/gleam@erlang@file.beam
new file mode 100644
index 0000000..7990b72
--- /dev/null
+++ b/aoc2023/build/dev/erlang/gleam_erlang/ebin/gleam@erlang@file.beam
Binary files differ
diff --git a/aoc2023/build/dev/erlang/gleam_erlang/ebin/gleam@erlang@node.beam b/aoc2023/build/dev/erlang/gleam_erlang/ebin/gleam@erlang@node.beam
new file mode 100644
index 0000000..d8ebb84
--- /dev/null
+++ b/aoc2023/build/dev/erlang/gleam_erlang/ebin/gleam@erlang@node.beam
Binary files differ
diff --git a/aoc2023/build/dev/erlang/gleam_erlang/ebin/gleam@erlang@os.beam b/aoc2023/build/dev/erlang/gleam_erlang/ebin/gleam@erlang@os.beam
new file mode 100644
index 0000000..40d121a
--- /dev/null
+++ b/aoc2023/build/dev/erlang/gleam_erlang/ebin/gleam@erlang@os.beam
Binary files differ
diff --git a/aoc2023/build/dev/erlang/gleam_erlang/ebin/gleam@erlang@process.beam b/aoc2023/build/dev/erlang/gleam_erlang/ebin/gleam@erlang@process.beam
new file mode 100644
index 0000000..8a73d73
--- /dev/null
+++ b/aoc2023/build/dev/erlang/gleam_erlang/ebin/gleam@erlang@process.beam
Binary files differ
diff --git a/aoc2023/build/dev/erlang/gleam_erlang/ebin/gleam_erlang.app b/aoc2023/build/dev/erlang/gleam_erlang/ebin/gleam_erlang.app
new file mode 100644
index 0000000..79950ab
--- /dev/null
+++ b/aoc2023/build/dev/erlang/gleam_erlang/ebin/gleam_erlang.app
@@ -0,0 +1,7 @@
+{application, gleam_erlang, [
+ {vsn, "0.23.1"},
+ {applications, [gleam_stdlib]},
+ {description, "A Gleam library for working with Erlang"},
+ {modules, []},
+ {registered, []}
+]}.
diff --git a/aoc2023/build/dev/erlang/gleam_erlang/ebin/gleam_erlang_ffi.beam b/aoc2023/build/dev/erlang/gleam_erlang/ebin/gleam_erlang_ffi.beam
new file mode 100644
index 0000000..965c70b
--- /dev/null
+++ b/aoc2023/build/dev/erlang/gleam_erlang/ebin/gleam_erlang_ffi.beam
Binary files differ
diff --git a/aoc2023/build/dev/erlang/gleam_erlang/include/gleam@erlang@file_FileInfo.hrl b/aoc2023/build/dev/erlang/gleam_erlang/include/gleam@erlang@file_FileInfo.hrl
new file mode 100644
index 0000000..b38d11e
--- /dev/null
+++ b/aoc2023/build/dev/erlang/gleam_erlang/include/gleam@erlang@file_FileInfo.hrl
@@ -0,0 +1,15 @@
+-record(file_info, {
+ size :: integer(),
+ file_type :: gleam@erlang@file:file_type(),
+ access :: gleam@erlang@file:access(),
+ atime :: integer(),
+ mtime :: integer(),
+ ctime :: integer(),
+ mode :: integer(),
+ links :: integer(),
+ major_device :: integer(),
+ minor_device :: integer(),
+ inode :: integer(),
+ user_id :: integer(),
+ group_id :: integer()
+}).
diff --git a/aoc2023/build/dev/erlang/gleam_erlang/include/gleam@erlang@process_Abnormal.hrl b/aoc2023/build/dev/erlang/gleam_erlang/include/gleam@erlang@process_Abnormal.hrl
new file mode 100644
index 0000000..4cd0452
--- /dev/null
+++ b/aoc2023/build/dev/erlang/gleam_erlang/include/gleam@erlang@process_Abnormal.hrl
@@ -0,0 +1 @@
+-record(abnormal, {reason :: binary()}).
diff --git a/aoc2023/build/dev/erlang/gleam_erlang/include/gleam@erlang@process_CalleeDown.hrl b/aoc2023/build/dev/erlang/gleam_erlang/include/gleam@erlang@process_CalleeDown.hrl
new file mode 100644
index 0000000..5dd5047
--- /dev/null
+++ b/aoc2023/build/dev/erlang/gleam_erlang/include/gleam@erlang@process_CalleeDown.hrl
@@ -0,0 +1 @@
+-record(callee_down, {reason :: gleam@dynamic:dynamic_()}).
diff --git a/aoc2023/build/dev/erlang/gleam_erlang/include/gleam@erlang@process_Cancelled.hrl b/aoc2023/build/dev/erlang/gleam_erlang/include/gleam@erlang@process_Cancelled.hrl
new file mode 100644
index 0000000..b82b49f
--- /dev/null
+++ b/aoc2023/build/dev/erlang/gleam_erlang/include/gleam@erlang@process_Cancelled.hrl
@@ -0,0 +1 @@
+-record(cancelled, {time_remaining :: integer()}).
diff --git a/aoc2023/build/dev/erlang/gleam_erlang/include/gleam@erlang@process_ExitMessage.hrl b/aoc2023/build/dev/erlang/gleam_erlang/include/gleam@erlang@process_ExitMessage.hrl
new file mode 100644
index 0000000..c476308
--- /dev/null
+++ b/aoc2023/build/dev/erlang/gleam_erlang/include/gleam@erlang@process_ExitMessage.hrl
@@ -0,0 +1,4 @@
+-record(exit_message, {
+ pid :: gleam@erlang@process:pid_(),
+ reason :: gleam@erlang@process:exit_reason()
+}).
diff --git a/aoc2023/build/dev/erlang/gleam_erlang/include/gleam@erlang@process_ProcessDown.hrl b/aoc2023/build/dev/erlang/gleam_erlang/include/gleam@erlang@process_ProcessDown.hrl
new file mode 100644
index 0000000..df0b6b7
--- /dev/null
+++ b/aoc2023/build/dev/erlang/gleam_erlang/include/gleam@erlang@process_ProcessDown.hrl
@@ -0,0 +1,4 @@
+-record(process_down, {
+ pid :: gleam@erlang@process:pid_(),
+ reason :: gleam@dynamic:dynamic_()
+}).
diff --git a/aoc2023/build/dev/erlang/gleam_erlang/include/gleam@erlang@process_ProcessMonitor.hrl b/aoc2023/build/dev/erlang/gleam_erlang/include/gleam@erlang@process_ProcessMonitor.hrl
new file mode 100644
index 0000000..ce552e2
--- /dev/null
+++ b/aoc2023/build/dev/erlang/gleam_erlang/include/gleam@erlang@process_ProcessMonitor.hrl
@@ -0,0 +1 @@
+-record(process_monitor, {tag :: gleam@erlang:reference_()}).
diff --git a/aoc2023/build/dev/erlang/gleam_erlang/include/gleam@erlang@process_Subject.hrl b/aoc2023/build/dev/erlang/gleam_erlang/include/gleam@erlang@process_Subject.hrl
new file mode 100644
index 0000000..abc46b2
--- /dev/null
+++ b/aoc2023/build/dev/erlang/gleam_erlang/include/gleam@erlang@process_Subject.hrl
@@ -0,0 +1,4 @@
+-record(subject, {
+ owner :: gleam@erlang@process:pid_(),
+ tag :: gleam@erlang:reference_()
+}).
diff --git a/aoc2023/build/dev/erlang/gleam_erlang/include/gleam@erlang_ApplicationFailedToStart.hrl b/aoc2023/build/dev/erlang/gleam_erlang/include/gleam@erlang_ApplicationFailedToStart.hrl
new file mode 100644
index 0000000..52c9896
--- /dev/null
+++ b/aoc2023/build/dev/erlang/gleam_erlang/include/gleam@erlang_ApplicationFailedToStart.hrl
@@ -0,0 +1,4 @@
+-record(application_failed_to_start, {
+ name :: gleam@erlang@atom:atom_(),
+ reason :: gleam@dynamic:dynamic_()
+}).
diff --git a/aoc2023/build/dev/erlang/gleam_erlang/include/gleam@erlang_UnknownApplication.hrl b/aoc2023/build/dev/erlang/gleam_erlang/include/gleam@erlang_UnknownApplication.hrl
new file mode 100644
index 0000000..fde3c61
--- /dev/null
+++ b/aoc2023/build/dev/erlang/gleam_erlang/include/gleam@erlang_UnknownApplication.hrl
@@ -0,0 +1 @@
+-record(unknown_application, {name :: gleam@erlang@atom:atom_()}).