Skip to main content

src/packkit@zstd.erl

-module(packkit@zstd).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/packkit/zstd.gleam").
-export([codec/0, frame_header_for_size/1, encode/1, decode_with_limits/2, decode/1]).
-export_type([huff_node/0, fse_enc_slot/0, zstd_sequence/0, block_state/0, seq_tables_state/0, compressed_literals_header/0, seq_alphabet/0, seq_context/0, fwd_bit_reader/0]).

-if(?OTP_RELEASE >= 27).
-define(MODULEDOC(Str), -moduledoc(Str)).
-define(DOC(Str), -doc(Str)).
-else.
-define(MODULEDOC(Str), -compile([])).
-define(DOC(Str), -compile([])).
-endif.

?MODULEDOC(
    " Zstandard codec — pure-Gleam decoder.\n"
    "\n"
    " The module parses the Zstandard frame envelope (magic, frame\n"
    " header descriptor, window descriptor, optional dictionary id,\n"
    " optional frame content size, optional trailing content checksum)\n"
    " and walks the block stream.  Raw and RLE blocks decode directly;\n"
    " compressed blocks (type 2) decode through the FSE tables in\n"
    " `packkit/internal/fse`.  Sequences with `Predefined_Mode`,\n"
    " `RLE_Mode`, and `FSE_Compressed_Mode` symbol descriptions all\n"
    " decode (LL, OF, ML independently).  All four literal block\n"
    " types decode: `Raw_Literals_Block`, `RLE_Literals_Block`,\n"
    " `Compressed_Literals_Block` (Huffman-coded with direct-weight\n"
    " or FSE-weight tree descriptions, 1-stream or 4-stream form),\n"
    " and `Treeless_Literals_Block` (which reuses the prior block's\n"
    " Huffman tree via the cross-block tree state threaded through\n"
    " the block loop).  A treeless block in the first position of a\n"
    " frame surfaces as a typed `CodecInvalidData`.  `Repeat_Mode`\n"
    " for sequence-symbol descriptions also threads its FSE tables\n"
    " across blocks (per RFC 8478 §3.1.1.4 the LL / OF / ML tables\n"
    " survive across blocks within a frame), and a Repeat_Mode in the\n"
    " first block of a frame surfaces as a typed `CodecInvalidData`.\n"
).

-type huff_node() :: {huff_leaf, integer()} |
    {huff_internal, huff_node(), huff_node()}.

-type fse_enc_slot() :: {fse_enc_slot,
        integer(),
        integer(),
        integer(),
        integer()}.

-type zstd_sequence() :: {zstd_sequence, integer(), integer(), integer()}.

-type block_state() :: {block_state,
        gleam@option:option(packkit@internal@huf:tree()),
        seq_tables_state(),
        list(integer()),
        {integer(), integer(), integer()}}.

-type seq_tables_state() :: {seq_tables_state,
        gleam@option:option({gleam@dict:dict(integer(), packkit@internal@fse:state_entry()),
            integer()}),
        gleam@option:option({gleam@dict:dict(integer(), packkit@internal@fse:state_entry()),
            integer()}),
        gleam@option:option({gleam@dict:dict(integer(), packkit@internal@fse:state_entry()),
            integer()})}.

-type compressed_literals_header() :: {compressed_literals_header,
        integer(),
        integer(),
        integer(),
        integer()}.

-type seq_alphabet() :: seq_alphabet_ll | seq_alphabet_of | seq_alphabet_ml.

-type seq_context() :: {seq_context,
        bitstring(),
        integer(),
        list(integer()),
        integer(),
        integer(),
        integer(),
        integer(),
        integer(),
        integer(),
        integer(),
        gleam@dict:dict(integer(), packkit@internal@fse:state_entry()),
        gleam@dict:dict(integer(), packkit@internal@fse:state_entry()),
        gleam@dict:dict(integer(), packkit@internal@fse:state_entry())}.

-type fwd_bit_reader() :: {fwd_bit_reader,
        bitstring(),
        integer(),
        integer(),
        boolean(),
        integer()}.

-file("src/packkit/zstd.gleam", 40).
?DOC(" Zstandard codec smart constructor.\n").
-spec codec() -> packkit@codec:codec().
codec() ->
    packkit@codec:zstd().

-file("src/packkit/zstd.gleam", 87).
?DOC(
    " Build the Zstandard frame header for a payload of `size` bytes.\n"
    " Exposed for tests that need to assert on the FCS layout for sizes\n"
    " too large to materialise in memory (e.g. 4 GiB+ frames where the\n"
    " header used to silently truncate the FCS field to its low 32 bits).\n"
).
-spec frame_header_for_size(integer()) -> {ok, bitstring()} |
    {error, packkit@error:codec_error()}.
frame_header_for_size(Size) ->
    case Size of
        N when N < 256 ->
            {ok, <<16#28, 16#B5, 16#2F, 16#FD, 16#20, N>>};

        N@1 when N@1 < 16#10000 ->
            {ok, <<16#28, 16#B5, 16#2F, 16#FD, 16#60, ((N@1 - 256)):16/little>>};

        N@2 when N@2 < 16#100000000 ->
            {ok, <<16#28, 16#B5, 16#2F, 16#FD, 16#A0, N@2:32/little>>};

        N@3 ->
            Lo = erlang:'band'(N@3, 16#FFFFFFFF),
            High_half = erlang:'bsr'(N@3, 32),
            gleam@bool:guard(
                High_half > 16#FFFFFFFF,
                {error,
                    {codec_limit_exceeded,
                        <<"zstd frame_content_size"/utf8>>,
                        N@3}},
                fun() ->
                    Hi = erlang:'band'(High_half, 16#FFFFFFFF),
                    {ok,
                        <<16#28,
                            16#B5,
                            16#2F,
                            16#FD,
                            16#E0,
                            Lo:32/little,
                            Hi:32/little>>}
                end
            )
    end.

-file("src/packkit/zstd.gleam", 250).
-spec pick_smallest_block(list({integer(), bitstring()})) -> bitstring().
pick_smallest_block(Candidates) ->
    case Candidates of
        [{_, Only}] ->
            Only;

        [First | Rest] ->
            erlang:element(
                2,
                gleam@list:fold(
                    Rest,
                    First,
                    fun(Acc, Item) ->
                        case erlang:element(1, Item) < erlang:element(1, Acc) of
                            true ->
                                Item;

                            false ->
                                Acc
                        end
                    end
                )
            );

        [] ->
            <<>>
    end.

-file("src/packkit/zstd.gleam", 422).
-spec split_chunk_4(bitstring(), integer()) -> {bitstring(),
    bitstring(),
    bitstring(),
    bitstring()}.
split_chunk_4(Chunk, Chunk_size) ->
    Per_stream = (Chunk_size + 3) div 4,
    S4_len = Chunk_size - (Per_stream * 3),
    P1@1 = case gleam_stdlib:bit_array_slice(Chunk, 0, Per_stream) of
        {ok, P1} -> P1;
        _assert_fail ->
            erlang:error(#{gleam_error => let_assert,
                        message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
                        file => <<?FILEPATH/utf8>>,
                        module => <<"packkit/zstd"/utf8>>,
                        function => <<"split_chunk_4"/utf8>>,
                        line => 434,
                        value => _assert_fail,
                        start => 16277,
                        'end' => 16334,
                        pattern_start => 16288,
                        pattern_end => 16294})
    end,
    P2@1 = case gleam_stdlib:bit_array_slice(Chunk, Per_stream, Per_stream) of
        {ok, P2} -> P2;
        _assert_fail@1 ->
            erlang:error(#{gleam_error => let_assert,
                        message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
                        file => <<?FILEPATH/utf8>>,
                        module => <<"packkit/zstd"/utf8>>,
                        function => <<"split_chunk_4"/utf8>>,
                        line => 435,
                        value => _assert_fail@1,
                        start => 16337,
                        'end' => 16403,
                        pattern_start => 16348,
                        pattern_end => 16354})
    end,
    P3@1 = case gleam_stdlib:bit_array_slice(Chunk, Per_stream * 2, Per_stream) of
        {ok, P3} -> P3;
        _assert_fail@2 ->
            erlang:error(#{gleam_error => let_assert,
                        message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
                        file => <<?FILEPATH/utf8>>,
                        module => <<"packkit/zstd"/utf8>>,
                        function => <<"split_chunk_4"/utf8>>,
                        line => 436,
                        value => _assert_fail@2,
                        start => 16406,
                        'end' => 16476,
                        pattern_start => 16417,
                        pattern_end => 16423})
    end,
    P4@1 = case gleam_stdlib:bit_array_slice(Chunk, Per_stream * 3, S4_len) of
        {ok, P4} -> P4;
        _assert_fail@3 ->
            erlang:error(#{gleam_error => let_assert,
                        message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
                        file => <<?FILEPATH/utf8>>,
                        module => <<"packkit/zstd"/utf8>>,
                        function => <<"split_chunk_4"/utf8>>,
                        line => 437,
                        value => _assert_fail@3,
                        start => 16479,
                        'end' => 16545,
                        pattern_start => 16490,
                        pattern_end => 16496})
    end,
    {P1@1, P2@1, P3@1, P4@1}.

-file("src/packkit/zstd.gleam", 446).
?DOC(
    " Build the 4-stream literals section: 4-byte header (size_format = 2,\n"
    " 14-bit regen / 14-bit compressed) followed by the Huffman tree,\n"
    " the 6-byte jump table (`stream1_size`, `stream2_size`,\n"
    " `stream3_size` each as LE u16; stream 4's size is derived by the\n"
    " decoder from `total - 6 - sum`), and the four sub-bitstreams.\n"
).
-spec build_compressed_literals_section_4stream(
    integer(),
    integer(),
    bitstring(),
    bitstring(),
    bitstring(),
    bitstring(),
    bitstring(),
    bitstring()
) -> bitstring().
build_compressed_literals_section_4stream(
    Regen_size,
    Comp_size,
    Tree_bytes,
    Jump_table,
    S1,
    S2,
    S3,
    S4
) ->
    B0 = erlang:'band'(
        erlang:'bor'(
            erlang:'bor'(2, erlang:'bsl'(2, 2)),
            erlang:'bsl'(erlang:'band'(Regen_size, 16#F), 4)
        ),
        16#FF
    ),
    B1 = erlang:'band'(erlang:'bsr'(Regen_size, 4), 16#FF),
    Regen_high_2 = erlang:'band'(erlang:'bsr'(Regen_size, 12), 16#3),
    Comp_low_6 = erlang:'band'(Comp_size, 16#3F),
    B2 = erlang:'band'(
        erlang:'bor'(Regen_high_2, erlang:'bsl'(Comp_low_6, 2)),
        16#FF
    ),
    B3 = erlang:'band'(erlang:'bsr'(Comp_size, 6), 16#FF),
    gleam_stdlib:bit_array_concat(
        [<<B0, B1, B2, B3>>, Tree_bytes, Jump_table, S1, S2, S3, S4]
    ).

-file("src/packkit/zstd.gleam", 496).
-spec empty_freq_dict(integer(), gleam@dict:dict(integer(), integer())) -> gleam@dict:dict(integer(), integer()).
empty_freq_dict(Symbol, Acc) ->
    case Symbol of
        256 ->
            Acc;

        _ ->
            empty_freq_dict(Symbol + 1, gleam@dict:insert(Acc, Symbol, 0))
    end.

-file("src/packkit/zstd.gleam", 503).
-spec collect_frequencies(bitstring(), gleam@dict:dict(integer(), integer())) -> gleam@dict:dict(integer(), integer()).
collect_frequencies(Chunk, Acc) ->
    case Chunk of
        <<Byte, Rest/binary>> ->
            Current = case gleam_stdlib:map_get(Acc, Byte) of
                {ok, V} ->
                    V;

                {error, _} ->
                    0
            end,
            collect_frequencies(Rest, gleam@dict:insert(Acc, Byte, Current + 1));

        _ ->
            Acc
    end.

-file("src/packkit/zstd.gleam", 519).
-spec count_freqs_to_list(
    gleam@dict:dict(integer(), integer()),
    integer(),
    list({integer(), integer()})
) -> list({integer(), integer()}).
count_freqs_to_list(Table, Symbol, Acc) ->
    case Symbol of
        256 ->
            lists:reverse(Acc);

        _ ->
            Count = case gleam_stdlib:map_get(Table, Symbol) of
                {ok, V} ->
                    V;

                {error, _} ->
                    0
            end,
            count_freqs_to_list(Table, Symbol + 1, [{Symbol, Count} | Acc])
    end.

-file("src/packkit/zstd.gleam", 490).
?DOC(
    " Count `chunk`'s byte frequencies as a list of `#(symbol, count)`\n"
    " pairs for symbols 0..255 in ascending order.  Symbols with zero\n"
    " occurrences are kept (they're filtered before tree building) so the\n"
    " caller can iterate the full 0..255 range without separate handling.\n"
).
-spec count_byte_frequencies(bitstring()) -> list({integer(), integer()}).
count_byte_frequencies(Chunk) ->
    Initial = empty_freq_dict(0, maps:new()),
    Table = collect_frequencies(Chunk, Initial),
    count_freqs_to_list(Table, 0, []).

-file("src/packkit/zstd.gleam", 590).
-spec insert_node_sorted(
    {integer(), huff_node()},
    list({integer(), huff_node()})
) -> list({integer(), huff_node()}).
insert_node_sorted(Item, Nodes) ->
    case Nodes of
        [] ->
            [Item];

        [Head | Rest] ->
            case erlang:element(1, Item) =< erlang:element(1, Head) of
                true ->
                    [Item, Head | Rest];

                false ->
                    [Head | insert_node_sorted(Item, Rest)]
            end
    end.

-file("src/packkit/zstd.gleam", 579).
-spec huffman_merge(list({integer(), huff_node()})) -> huff_node().
huffman_merge(Nodes) ->
    case Nodes of
        [{_, Single}] ->
            Single;

        [A, B | Rest] ->
            Combined = {erlang:element(1, A) + erlang:element(1, B),
                {huff_internal, erlang:element(2, A), erlang:element(2, B)}},
            huffman_merge(insert_node_sorted(Combined, Rest));

        _ ->
            {huff_leaf, 0}
    end.

-file("src/packkit/zstd.gleam", 604).
-spec extract_lengths(
    huff_node(),
    integer(),
    gleam@dict:dict(integer(), integer())
) -> gleam@dict:dict(integer(), integer()).
extract_lengths(Node, Depth, Acc) ->
    case Node of
        {huff_leaf, Sym} ->
            D = case Depth of
                0 ->
                    1;

                _ ->
                    Depth
            end,
            gleam@dict:insert(Acc, Sym, D);

        {huff_internal, L, R} ->
            Acc@1 = extract_lengths(L, Depth + 1, Acc),
            extract_lengths(R, Depth + 1, Acc@1)
    end.

-file("src/packkit/zstd.gleam", 624).
-spec max_length_in_dict(gleam@dict:dict(integer(), integer())) -> integer().
max_length_in_dict(Lengths) ->
    gleam@dict:fold(Lengths, 0, fun(Acc, _, Value) -> case Value > Acc of
                true ->
                    Value;

                false ->
                    Acc
            end end).

-file("src/packkit/zstd.gleam", 633).
-spec build_length_list(
    gleam@dict:dict(integer(), integer()),
    integer(),
    list(integer())
) -> list(integer()).
build_length_list(Lengths, Symbol, Acc) ->
    case Symbol of
        256 ->
            lists:reverse(Acc);

        _ ->
            Len = case gleam_stdlib:map_get(Lengths, Symbol) of
                {ok, V} ->
                    V;

                {error, _} ->
                    0
            end,
            build_length_list(Lengths, Symbol + 1, [Len | Acc])
    end.

-file("src/packkit/zstd.gleam", 546).
?DOC(
    " Build canonical Huffman code lengths for `freqs`, returning a list\n"
    " of 256 lengths (0 for unused symbols).  Standard Huffman tree\n"
    " construction via insertion-sort; bails out with `Error(Nil)` when\n"
    " the resulting tree exceeds the 11-bit depth limit so the caller\n"
    " can fall back to Raw / RLE.\n"
).
-spec build_canonical_lengths(list({integer(), integer()})) -> {ok,
        {list(integer()), integer()}} |
    {error, nil}.
build_canonical_lengths(Freqs) ->
    Active = gleam@list:filter_map(
        Freqs,
        fun(P) -> case erlang:element(2, P) > 0 of
                true ->
                    {ok,
                        {erlang:element(2, P),
                            {huff_leaf, erlang:element(1, P)}}};

                false ->
                    {error, nil}
            end end
    ),
    Sorted = gleam@list:sort(
        Active,
        fun(A, B) ->
            gleam@int:compare(erlang:element(1, A), erlang:element(1, B))
        end
    ),
    case Sorted of
        [] ->
            {error, nil};

        [{_, Single_node}] ->
            Single = case Single_node of
                {huff_leaf, S} ->
                    S;

                _ ->
                    0
            end,
            Lengths = build_length_list(
                gleam@dict:insert(maps:new(), Single, 1),
                0,
                []
            ),
            {ok, {Lengths, 1}};

        _ ->
            Root = huffman_merge(Sorted),
            Lengths_dict = extract_lengths(Root, 0, maps:new()),
            Max_bits = max_length_in_dict(Lengths_dict),
            Lengths@1 = build_length_list(Lengths_dict, 0, []),
            {ok, {Lengths@1, Max_bits}}
    end.

-file("src/packkit/zstd.gleam", 674).
-spec assign_codes_loop(
    list({integer(), integer()}),
    integer(),
    integer(),
    gleam@dict:dict(integer(), {integer(), integer()})
) -> gleam@dict:dict(integer(), {integer(), integer()}).
assign_codes_loop(Sorted, Max_bits, Slot, Acc) ->
    case Sorted of
        [] ->
            Acc;

        [{Sym, Len} | Rest] ->
            Span = erlang:'bsl'(1, Max_bits - Len),
            Code = erlang:'bsr'(Slot, Max_bits - Len),
            assign_codes_loop(
                Rest,
                Max_bits,
                Slot + Span,
                gleam@dict:insert(Acc, Sym, {Code, Len})
            )
    end.

-file("src/packkit/zstd.gleam", 656).
?DOC(
    " Build the encoder's `symbol → #(code_value, num_bits)` table from\n"
    " the canonical lengths.  zstd's lookup table is filled in order\n"
    " (length DESC, symbol ASC), so the encoder's code values are simply\n"
    " the table slot indices, right-shifted by `max_bits - num_bits` to\n"
    " drop the table's low-order bits (which the decoder treats as\n"
    " \"don't care\" once it has consumed `num_bits` bits).\n"
).
-spec assign_canonical_codes(list(integer()), integer()) -> gleam@dict:dict(integer(), {integer(),
    integer()}).
assign_canonical_codes(Lengths, Max_bits) ->
    With_index = begin
        _pipe = gleam@list:index_map(Lengths, fun(Len, Sym) -> {Sym, Len} end),
        gleam@list:filter(_pipe, fun(P) -> erlang:element(2, P) > 0 end)
    end,
    Sorted = gleam@list:sort(
        With_index,
        fun(A, B) ->
            case gleam@int:compare(erlang:element(2, B), erlang:element(2, A)) of
                eq ->
                    gleam@int:compare(
                        erlang:element(1, A),
                        erlang:element(1, B)
                    );

                Ord ->
                    Ord
            end
        end
    ),
    assign_codes_loop(Sorted, Max_bits, 0, maps:new()).

-file("src/packkit/zstd.gleam", 695).
-spec max_length_in_list(list(integer()), integer()) -> integer().
max_length_in_list(Lengths, Acc) ->
    case Lengths of
        [] ->
            Acc;

        [Head | Rest] ->
            case Head > Acc of
                true ->
                    max_length_in_list(Rest, Head);

                false ->
                    max_length_in_list(Rest, Acc)
            end
    end.

-file("src/packkit/zstd.gleam", 706).
-spec trim_trailing_zero_weights(list(integer()), list(integer())) -> list(integer()).
trim_trailing_zero_weights(Reversed, Acc) ->
    case {Reversed, Acc} of
        {[], _} ->
            Acc;

        {[0 | Rest], []} ->
            trim_trailing_zero_weights(Rest, []);

        {[Head | Rest@1], _} ->
            trim_trailing_zero_weights(Rest@1, [Head | Acc])
    end.

-file("src/packkit/zstd.gleam", 714).
-spec drop_last_weight(list(integer()), list(integer())) -> list(integer()).
drop_last_weight(Weights, Acc) ->
    case Weights of
        [] ->
            lists:reverse(Acc);

        [_] ->
            lists:reverse(Acc);

        [Head | Rest] ->
            drop_last_weight(Rest, [Head | Acc])
    end.

-file("src/packkit/zstd.gleam", 722).
-spec pack_weights_4bit(list(integer()), bitstring()) -> bitstring().
pack_weights_4bit(Weights, Acc) ->
    case Weights of
        [] ->
            Acc;

        [Single] ->
            Byte = erlang:'bsl'(Single, 4),
            <<Acc/bitstring, Byte>>;

        [High, Low | Rest] ->
            Byte@1 = erlang:'bor'(erlang:'bsl'(High, 4), Low),
            pack_weights_4bit(Rest, <<Acc/bitstring, Byte@1>>)
    end.

-file("src/packkit/zstd.gleam", 755).
-spec bit_array_to_list_forward(bitstring(), list(integer())) -> list(integer()).
bit_array_to_list_forward(Bytes, Acc) ->
    case Bytes of
        <<Byte, Rest/binary>> ->
            bit_array_to_list_forward(Rest, [Byte | Acc]);

        _ ->
            lists:reverse(Acc)
    end.

-file("src/packkit/zstd.gleam", 785).
-spec flush_full_bytes(integer(), integer(), bitstring()) -> {integer(),
    integer(),
    bitstring()}.
flush_full_bytes(Buf, Bits, Out) ->
    case Bits >= 8 of
        true ->
            Byte = erlang:'band'(Buf, 16#FF),
            New_buf = erlang:'bsr'(Buf, 8),
            flush_full_bytes(New_buf, Bits - 8, <<Out/bitstring, Byte>>);

        false ->
            {Buf, Bits, Out}
    end.

-file("src/packkit/zstd.gleam", 762).
-spec emit_codes_reverse(
    list(integer()),
    gleam@dict:dict(integer(), {integer(), integer()}),
    integer(),
    integer(),
    bitstring()
) -> {integer(), integer(), bitstring()}.
emit_codes_reverse(Bytes_rev, Codes, Buf, Bits, Out) ->
    case Bytes_rev of
        [] ->
            {Buf, Bits, Out};

        [Byte | Rest] ->
            {Code, Len} = case gleam_stdlib:map_get(Codes, Byte) of
                {ok, V} ->
                    V;

                {error, _} ->
                    {0, 0}
            end,
            New_buf = erlang:'bor'(Buf, erlang:'bsl'(Code, Bits)),
            New_bits = Bits + Len,
            {Flushed_buf, Flushed_bits, Flushed_out} = flush_full_bytes(
                New_buf,
                New_bits,
                Out
            ),
            emit_codes_reverse(
                Rest,
                Codes,
                Flushed_buf,
                Flushed_bits,
                Flushed_out
            )
    end.

-file("src/packkit/zstd.gleam", 796).
-spec flush_final_bits(integer(), integer(), bitstring()) -> bitstring().
flush_final_bits(Buf, Bits, Out) ->
    case Bits of
        0 ->
            Out;

        _ ->
            Byte = erlang:'band'(Buf, 16#FF),
            New_buf = erlang:'bsr'(Buf, 8),
            New_bits = case Bits > 8 of
                true ->
                    Bits - 8;

                false ->
                    0
            end,
            flush_final_bits(New_buf, New_bits, <<Out/bitstring, Byte>>)
    end.

-file("src/packkit/zstd.gleam", 742).
?DOC(
    " Build the bitstream a zstd Huffman decoder reads from the END\n"
    " backward.  We iterate input in REVERSE order, push each code into a\n"
    " shift register from the LOW end, flush low bytes when full, and\n"
    " finally append a 1-bit terminator that the decoder finds via\n"
    " \"highest set bit of the last byte\".\n"
).
-spec encode_huffman_bitstream(
    bitstring(),
    gleam@dict:dict(integer(), {integer(), integer()})
) -> bitstring().
encode_huffman_bitstream(Chunk, Codes) ->
    Bytes = bit_array_to_list_forward(Chunk, []),
    Reversed = lists:reverse(Bytes),
    {Buf, Bits, Out} = emit_codes_reverse(Reversed, Codes, 0, 0, <<>>),
    Buf2 = erlang:'bor'(Buf, erlang:'bsl'(1, Bits)),
    Bits2 = Bits + 1,
    flush_final_bits(Buf2, Bits2, Out).

-file("src/packkit/zstd.gleam", 881).
-spec tally_fse_weights(list(integer()), gleam@dict:dict(integer(), integer())) -> gleam@dict:dict(integer(), integer()).
tally_fse_weights(Weights, Acc) ->
    case Weights of
        [] ->
            Acc;

        [W | Rest] ->
            Curr = case gleam_stdlib:map_get(Acc, W) of
                {ok, V} ->
                    V;

                {error, _} ->
                    0
            end,
            tally_fse_weights(Rest, gleam@dict:insert(Acc, W, Curr + 1))
    end.

-file("src/packkit/zstd.gleam", 897).
-spec highest_used_fse_weight(gleam@dict:dict(integer(), integer())) -> integer().
highest_used_fse_weight(Counts) ->
    gleam@dict:fold(
        Counts,
        -1,
        fun(Acc, Sym, Count) -> case (Count > 0) andalso (Sym > Acc) of
                true ->
                    Sym;

                false ->
                    Acc
            end end
    ).

-file("src/packkit/zstd.gleam", 967).
-spec sum_int_list(list(integer()), integer()) -> integer().
sum_int_list(List, Acc) ->
    case List of
        [] ->
            Acc;

        [Head | Rest] ->
            sum_int_list(Rest, Acc + Head)
    end.

-file("src/packkit/zstd.gleam", 978).
-spec find_largest_loop(
    gleam@dict:dict(integer(), integer()),
    integer(),
    integer(),
    integer(),
    integer()
) -> integer().
find_largest_loop(Counts, Sym, Max_used, Best_idx, Best_count) ->
    case Sym > Max_used of
        true ->
            Best_idx;

        false ->
            Count = case gleam_stdlib:map_get(Counts, Sym) of
                {ok, V} ->
                    V;

                {error, _} ->
                    0
            end,
            case Count > Best_count of
                true ->
                    find_largest_loop(Counts, Sym + 1, Max_used, Sym, Count);

                false ->
                    find_largest_loop(
                        Counts,
                        Sym + 1,
                        Max_used,
                        Best_idx,
                        Best_count
                    )
            end
    end.

-file("src/packkit/zstd.gleam", 974).
-spec find_largest_count_index(gleam@dict:dict(integer(), integer()), integer()) -> integer().
find_largest_count_index(Counts, Max_used) ->
    find_largest_loop(Counts, 0, Max_used, -1, -1).

-file("src/packkit/zstd.gleam", 1001).
-spec adjust_normalized_at(
    list(integer()),
    integer(),
    integer(),
    integer(),
    list(integer())
) -> list(integer()).
adjust_normalized_at(Normalized, Target_idx, Diff, Cur_idx, Acc) ->
    case Normalized of
        [] ->
            lists:reverse(Acc);

        [Head | Rest] ->
            New_head = case Cur_idx =:= Target_idx of
                true ->
                    Head + Diff;

                false ->
                    Head
            end,
            adjust_normalized_at(
                Rest,
                Target_idx,
                Diff,
                Cur_idx + 1,
                [New_head | Acc]
            )
    end.

-file("src/packkit/zstd.gleam", 1060).
-spec list_to_indexed_dict(
    list(integer()),
    integer(),
    gleam@dict:dict(integer(), integer())
) -> gleam@dict:dict(integer(), integer()).
list_to_indexed_dict(List, Idx, Acc) ->
    case List of
        [] ->
            Acc;

        [Head | Rest] ->
            list_to_indexed_dict(
                Rest,
                Idx + 1,
                gleam@dict:insert(Acc, Idx, Head)
            )
    end.

-file("src/packkit/zstd.gleam", 1145).
-spec count_zero_run_from(
    gleam@dict:dict(integer(), integer()),
    integer(),
    integer(),
    integer()
) -> integer().
count_zero_run_from(Normalized, Pos, Max_used, Acc) ->
    case Pos > Max_used of
        true ->
            Acc;

        false ->
            V = case gleam_stdlib:map_get(Normalized, Pos) of
                {ok, X} ->
                    X;

                {error, _} ->
                    0
            end,
            case V =:= 0 of
                true ->
                    count_zero_run_from(Normalized, Pos + 1, Max_used, Acc + 1);

                false ->
                    Acc
            end
    end.

-file("src/packkit/zstd.gleam", 1201).
-spec fse_shrink_threshold(integer(), integer(), integer()) -> {integer(),
    integer()}.
fse_shrink_threshold(Threshold, Bit_count, Remaining) ->
    case Remaining >= Threshold of
        true ->
            {Threshold, Bit_count};

        false ->
            case Threshold =< 1 of
                true ->
                    {Threshold, Bit_count};

                false ->
                    fse_shrink_threshold(
                        Threshold div 2,
                        Bit_count - 1,
                        Remaining
                    )
            end
    end.

-file("src/packkit/zstd.gleam", 1218).
-spec push_bits_unchecked(
    integer(),
    integer(),
    bitstring(),
    integer(),
    integer()
) -> {integer(), integer(), bitstring()}.
push_bits_unchecked(Buf, Bits, Out, Value, N) ->
    New_buf = erlang:'bor'(Buf, erlang:'bsl'(Value, Bits)),
    flush_full_bytes(New_buf, Bits + N, Out).

-file("src/packkit/zstd.gleam", 1166).
-spec emit_zero_run(integer(), integer(), integer(), bitstring()) -> {integer(),
    integer(),
    bitstring()}.
emit_zero_run(Run, Buf, Bits, Out) ->
    case Run >= 3 of
        true ->
            {Buf@1, Bits@1, Out@1} = push_bits_unchecked(Buf, Bits, Out, 3, 2),
            emit_zero_run(Run - 3, Buf@1, Bits@1, Out@1);

        false ->
            push_bits_unchecked(Buf, Bits, Out, Run, 2)
    end.

-file("src/packkit/zstd.gleam", 1181).
-spec push_count_bits(
    integer(),
    integer(),
    bitstring(),
    integer(),
    integer(),
    integer(),
    integer()
) -> {integer(), integer(), bitstring()}.
push_count_bits(Buf, Bits, Out, Count_wire, Max_val, Threshold, Bit_count) ->
    case Count_wire < Max_val of
        true ->
            push_bits_unchecked(Buf, Bits, Out, Count_wire, Bit_count - 1);

        false ->
            case Count_wire < Threshold of
                true ->
                    push_bits_unchecked(Buf, Bits, Out, Count_wire, Bit_count);

                false ->
                    push_bits_unchecked(
                        Buf,
                        Bits,
                        Out,
                        Count_wire + Max_val,
                        Bit_count
                    )
            end
    end.

-file("src/packkit/zstd.gleam", 1072).
-spec write_dist_loop(
    gleam@dict:dict(integer(), integer()),
    integer(),
    integer(),
    integer(),
    integer(),
    integer(),
    boolean(),
    integer(),
    integer(),
    bitstring()
) -> {integer(), integer(), bitstring()}.
write_dist_loop(
    Normalized,
    Curr,
    Max_used,
    Remaining,
    Threshold,
    Bit_count,
    Prev_is_zero,
    Buf,
    Bits,
    Out
) ->
    case (Remaining =< 1) orelse (Curr > Max_used) of
        true ->
            {Buf, Bits, Out};

        false ->
            case Prev_is_zero of
                true ->
                    Run = count_zero_run_from(Normalized, Curr, Max_used, 0),
                    {Buf@1, Bits@1, Out@1} = emit_zero_run(Run, Buf, Bits, Out),
                    write_dist_loop(
                        Normalized,
                        Curr + Run,
                        Max_used,
                        Remaining,
                        Threshold,
                        Bit_count,
                        false,
                        Buf@1,
                        Bits@1,
                        Out@1
                    );

                false ->
                    Probability = case gleam_stdlib:map_get(Normalized, Curr) of
                        {ok, V} ->
                            V;

                        {error, _} ->
                            0
                    end,
                    Count_wire = Probability + 1,
                    Max_val = ((2 * Threshold) - 1) - Remaining,
                    {Buf@2, Bits@2, Out@2} = push_count_bits(
                        Buf,
                        Bits,
                        Out,
                        Count_wire,
                        Max_val,
                        Threshold,
                        Bit_count
                    ),
                    Abs_prob = case Probability < 0 of
                        true ->
                            - Probability;

                        false ->
                            Probability
                    end,
                    New_remaining = Remaining - Abs_prob,
                    {New_threshold, New_bit_count} = fse_shrink_threshold(
                        Threshold,
                        Bit_count,
                        New_remaining
                    ),
                    write_dist_loop(
                        Normalized,
                        Curr + 1,
                        Max_used,
                        New_remaining,
                        New_threshold,
                        New_bit_count,
                        Probability =:= 0,
                        Buf@2,
                        Bits@2,
                        Out@2
                    )
            end
    end.

-file("src/packkit/zstd.gleam", 1229).
-spec pad_to_byte_boundary(integer(), integer(), bitstring()) -> bitstring().
pad_to_byte_boundary(Buf, Bits, Out) ->
    case Bits of
        0 ->
            Out;

        _ ->
            Byte = erlang:'band'(Buf, 16#FF),
            <<Out/bitstring, Byte>>
    end.

-file("src/packkit/zstd.gleam", 1036).
?DOC(
    " Generalised distribution-header writer.  `accuracy_log` chooses\n"
    " the table size (`1 << accuracy_log`) and the 4-bit `accuracy_log\n"
    " - 5` prefix; the rest mirrors the decoder's symmetric reader\n"
    " (variable-width per-symbol counts with the 2-bit zero-run codes\n"
    " when consecutive symbols have probability 0).\n"
).
-spec encode_fse_dist_header_with_log(list(integer()), integer(), integer()) -> bitstring().
encode_fse_dist_header_with_log(Normalized, Max_used, Accuracy_log) ->
    {Buf, Bits, Out} = push_bits_unchecked(0, 0, <<>>, Accuracy_log - 5, 4),
    Table_size = erlang:'bsl'(1, Accuracy_log),
    Normalized_dict = list_to_indexed_dict(Normalized, 0, maps:new()),
    {Buf@1, Bits@1, Out@1} = write_dist_loop(
        Normalized_dict,
        0,
        Max_used,
        Table_size + 1,
        Table_size,
        Accuracy_log + 1,
        false,
        Buf,
        Bits,
        Out
    ),
    pad_to_byte_boundary(Buf@1, Bits@1, Out@1).

-file("src/packkit/zstd.gleam", 1253).
-spec build_fse_enc_slots_loop(
    gleam@dict:dict(integer(), packkit@internal@fse:state_entry()),
    integer(),
    integer(),
    gleam@dict:dict(integer(), list(fse_enc_slot()))
) -> gleam@dict:dict(integer(), list(fse_enc_slot())).
build_fse_enc_slots_loop(State_table, S_idx, Table_size, Acc) ->
    case S_idx >= Table_size of
        true ->
            Acc;

        false ->
            Entry = case gleam_stdlib:map_get(State_table, S_idx) of
                {ok, E} ->
                    E;

                {error, _} ->
                    {state_entry, 0, 0, 0}
            end,
            Span = erlang:'bsl'(1, erlang:element(3, Entry)),
            Slot = {fse_enc_slot,
                S_idx,
                erlang:element(4, Entry),
                erlang:element(4, Entry) + Span,
                erlang:element(3, Entry)},
            Existing = case gleam_stdlib:map_get(Acc, erlang:element(2, Entry)) of
                {ok, L} ->
                    L;

                {error, _} ->
                    []
            end,
            build_fse_enc_slots_loop(
                State_table,
                S_idx + 1,
                Table_size,
                gleam@dict:insert(
                    Acc,
                    erlang:element(2, Entry),
                    [Slot | Existing]
                )
            )
    end.

-file("src/packkit/zstd.gleam", 1299).
-spec smallest_state_idx_loop(list(fse_enc_slot()), integer()) -> integer().
smallest_state_idx_loop(List, Best) ->
    case List of
        [] ->
            Best;

        [Slot | Rest] ->
            case erlang:element(2, Slot) < Best of
                true ->
                    smallest_state_idx_loop(Rest, erlang:element(2, Slot));

                false ->
                    smallest_state_idx_loop(Rest, Best)
            end
    end.

-file("src/packkit/zstd.gleam", 1321).
-spec find_slot_in_list(list(fse_enc_slot()), integer()) -> {ok, fse_enc_slot()} |
    {error, nil}.
find_slot_in_list(List, State) ->
    case List of
        [] ->
            {error, nil};

        [Slot | Rest] ->
            case (State >= erlang:element(3, Slot)) andalso (State < erlang:element(
                4,
                Slot
            )) of
                true ->
                    {ok, Slot};

                false ->
                    find_slot_in_list(Rest, State)
            end
    end.

-file("src/packkit/zstd.gleam", 1310).
-spec find_slot_for(
    gleam@dict:dict(integer(), list(fse_enc_slot())),
    integer(),
    integer()
) -> {ok, fse_enc_slot()} | {error, nil}.
find_slot_for(Slots, Symbol, Current_state) ->
    case gleam_stdlib:map_get(Slots, Symbol) of
        {error, _} ->
            {error, nil};

        {ok, List} ->
            find_slot_in_list(List, Current_state)
    end.

-file("src/packkit/zstd.gleam", 1389).
-spec dict_index_or_zero(gleam@dict:dict(integer(), integer()), integer()) -> integer().
dict_index_or_zero(D, Idx) ->
    case gleam_stdlib:map_get(D, Idx) of
        {ok, V} ->
            V;

        {error, _} ->
            0
    end.

-file("src/packkit/zstd.gleam", 1396).
-spec fse_encode_transitions(
    gleam@dict:dict(integer(), integer()),
    integer(),
    integer(),
    integer(),
    gleam@dict:dict(integer(), list(fse_enc_slot())),
    integer(),
    integer(),
    bitstring()
) -> {integer(), integer(), integer(), integer(), bitstring()}.
fse_encode_transitions(Weights, I, State_a, State_b, Slots, Buf, Bits, Out) ->
    case I < 0 of
        true ->
            {Buf, Bits, State_a, State_b, Out};

        false ->
            W = dict_index_or_zero(Weights, I),
            Use_state_a = erlang:'band'(I, 1) =:= 0,
            Curr_state = case Use_state_a of
                true ->
                    State_a;

                false ->
                    State_b
            end,
            case find_slot_for(Slots, W, Curr_state) of
                {error, _} ->
                    fse_encode_transitions(
                        Weights,
                        I - 1,
                        State_a,
                        State_b,
                        Slots,
                        Buf,
                        Bits,
                        Out
                    );

                {ok, Slot} ->
                    Emit_value = Curr_state - erlang:element(3, Slot),
                    {Buf@1, Bits@1, Out@1} = push_bits_unchecked(
                        Buf,
                        Bits,
                        Out,
                        Emit_value,
                        erlang:element(5, Slot)
                    ),
                    Prev_state = erlang:element(2, Slot),
                    {New_a, New_b} = case Use_state_a of
                        true ->
                            {Prev_state, State_b};

                        false ->
                            {State_a, Prev_state}
                    end,
                    fse_encode_transitions(
                        Weights,
                        I - 1,
                        New_a,
                        New_b,
                        Slots,
                        Buf@1,
                        Bits@1,
                        Out@1
                    )
            end
    end.

-file("src/packkit/zstd.gleam", 1486).
?DOC(
    " Pack the Literals_Section_Header for the 1-stream Compressed form\n"
    " (`size_format = 0`): 3 bytes carrying block_type=2, size_format=0,\n"
    " 10-bit regenerated_size, and 10-bit compressed_size; followed by\n"
    " the Huffman tree description and the bitstream.\n"
).
-spec build_compressed_literals_section(
    integer(),
    integer(),
    bitstring(),
    bitstring()
) -> bitstring().
build_compressed_literals_section(
    Regenerated_size,
    Compressed_size,
    Tree_bytes,
    Bitstream
) ->
    B0 = erlang:'band'(
        erlang:'bor'(
            erlang:'bor'(2, 0),
            erlang:'bsl'(erlang:'band'(Regenerated_size, 16#F), 4)
        ),
        16#FF
    ),
    Regen_high = erlang:'bsr'(Regenerated_size, 4),
    Comp_low = erlang:'band'(Compressed_size, 16#3F),
    B1 = erlang:'band'(
        erlang:'bor'(
            erlang:'band'(Regen_high, 16#3F),
            erlang:'bsl'(Comp_low, 6)
        ),
        16#FF
    ),
    B2 = erlang:'band'(erlang:'bsr'(Compressed_size, 2), 16#FF),
    gleam_stdlib:bit_array_concat([<<B0, B1, B2>>, Tree_bytes, Bitstream]).

-file("src/packkit/zstd.gleam", 1528).
-spec uniform_byte_loop(integer(), bitstring()) -> {ok, integer()} |
    {error, nil}.
uniform_byte_loop(Byte, Rest) ->
    case Rest of
        <<>> ->
            {ok, Byte};

        <<B, More/binary>> when B =:= Byte ->
            uniform_byte_loop(Byte, More);

        _ ->
            {error, nil}
    end.

-file("src/packkit/zstd.gleam", 1521).
?DOC(
    " Returns the single byte the whole chunk repeats, or Error if the\n"
    " chunk has more than one distinct value.\n"
).
-spec peek_uniform_byte(bitstring()) -> {ok, integer()} | {error, nil}.
peek_uniform_byte(Bytes) ->
    case Bytes of
        <<First, Rest/binary>> ->
            uniform_byte_loop(First, Rest);

        _ ->
            {error, nil}
    end.

-file("src/packkit/zstd.gleam", 1536).
-spec block_header(integer(), integer(), boolean()) -> bitstring().
block_header(Block_size, Block_type, Is_last) ->
    Last_bit = case Is_last of
        true ->
            1;

        false ->
            0
    end,
    Block_header_value = erlang:'bor'(
        erlang:'bor'(erlang:'bsl'(Block_size, 3), erlang:'bsl'(Block_type, 1)),
        Last_bit
    ),
    Bh0 = erlang:'band'(Block_header_value, 16#FF),
    Bh1 = erlang:'band'(erlang:'bsr'(Block_header_value, 8), 16#FF),
    Bh2 = erlang:'band'(erlang:'bsr'(Block_header_value, 16), 16#FF),
    <<Bh0, Bh1, Bh2>>.

-file("src/packkit/zstd.gleam", 1710).
-spec zstd_hash3(integer(), integer(), integer()) -> integer().
zstd_hash3(B0, B1, B2) ->
    erlang:'band'(
        erlang:'bxor'(
            erlang:'bxor'(B0 * 2654435761, B1 * 40503),
            B2 * 2246822519
        ),
        16#FFFF
    ).

-file("src/packkit/zstd.gleam", 1720).
-spec zstd_byte_at(bitstring(), integer()) -> integer().
zstd_byte_at(Bytes, Pos) ->
    case gleam_stdlib:bit_array_slice(Bytes, Pos, 1) of
        {ok, <<B>>} ->
            B;

        _ ->
            0
    end.

-file("src/packkit/zstd.gleam", 1727).
-spec zstd_byte_slice(bitstring(), integer(), integer()) -> bitstring().
zstd_byte_slice(Bytes, Offset, Length) ->
    case gleam_stdlib:bit_array_slice(Bytes, Offset, Length) of
        {ok, V} ->
            V;

        {error, _} ->
            <<>>
    end.

-file("src/packkit/zstd.gleam", 1734).
-spec zstd_match_len(bitstring(), integer(), integer(), integer(), integer()) -> integer().
zstd_match_len(Bytes, Base, Cursor, Cap, Acc) ->
    case Acc >= Cap of
        true ->
            Acc;

        false ->
            case zstd_byte_at(Bytes, Base + Acc) =:= zstd_byte_at(
                Bytes,
                Cursor + Acc
            ) of
                true ->
                    zstd_match_len(Bytes, Base, Cursor, Cap, Acc + 1);

                false ->
                    Acc
            end
    end.

-file("src/packkit/zstd.gleam", 1784).
-spec ll_to_code(integer()) -> integer().
ll_to_code(Length) ->
    case Length of
        N when (N >= 0) andalso (N =< 15) ->
            N;

        N@1 when N@1 < 18 ->
            16;

        N@2 when N@2 < 20 ->
            17;

        N@3 when N@3 < 22 ->
            18;

        N@4 when N@4 < 24 ->
            19;

        N@5 when N@5 < 28 ->
            20;

        N@6 when N@6 < 32 ->
            21;

        N@7 when N@7 < 40 ->
            22;

        N@8 when N@8 < 48 ->
            23;

        N@9 when N@9 < 64 ->
            24;

        N@10 when N@10 < 128 ->
            25;

        N@11 when N@11 < 256 ->
            26;

        N@12 when N@12 < 512 ->
            27;

        N@13 when N@13 < 1024 ->
            28;

        N@14 when N@14 < 2048 ->
            29;

        N@15 when N@15 < 4096 ->
            30;

        N@16 when N@16 < 8192 ->
            31;

        N@17 when N@17 < 16384 ->
            32;

        N@18 when N@18 < 32768 ->
            33;

        N@19 when N@19 < 65536 ->
            34;

        _ ->
            35
    end.

-file("src/packkit/zstd.gleam", 1812).
-spec ml_to_code(integer()) -> integer().
ml_to_code(Length) ->
    case Length of
        N when (N >= 3) andalso (N =< 34) ->
            N - 3;

        N@1 when N@1 < 37 ->
            32;

        N@2 when N@2 < 39 ->
            33;

        N@3 when N@3 < 41 ->
            34;

        N@4 when N@4 < 43 ->
            35;

        N@5 when N@5 < 47 ->
            36;

        N@6 when N@6 < 51 ->
            37;

        N@7 when N@7 < 59 ->
            38;

        N@8 when N@8 < 67 ->
            39;

        N@9 when N@9 < 83 ->
            40;

        N@10 when N@10 < 99 ->
            41;

        N@11 when N@11 < 131 ->
            42;

        N@12 when N@12 < 259 ->
            43;

        N@13 when N@13 < 515 ->
            44;

        N@14 when N@14 < 1027 ->
            45;

        N@15 when N@15 < 2051 ->
            46;

        N@16 when N@16 < 4099 ->
            47;

        N@17 when N@17 < 8195 ->
            48;

        N@18 when N@18 < 16387 ->
            49;

        N@19 when N@19 < 32771 ->
            50;

        N@20 when N@20 < 65539 ->
            51;

        _ ->
            52
    end.

-file("src/packkit/zstd.gleam", 1842).
-spec of_to_code(integer()) -> integer().
of_to_code(Raw_offset) ->
    packkit@internal@fse:high_bit_position(Raw_offset).

-file("src/packkit/zstd.gleam", 1884).
-spec rep_aware_raw_offset(
    integer(),
    integer(),
    {integer(), integer(), integer()}
) -> {integer(), {integer(), integer(), integer()}}.
rep_aware_raw_offset(Distance, Literal_length, Rep) ->
    {R0, R1, R2} = Rep,
    case Literal_length > 0 of
        true ->
            case Distance of
                D when D =:= R0 ->
                    {1, {R0, R1, R2}};

                D@1 when D@1 =:= R1 ->
                    {2, {R1, R0, R2}};

                D@2 when D@2 =:= R2 ->
                    {3, {R2, R0, R1}};

                D@3 ->
                    {D@3 + 3, {D@3, R0, R1}}
            end;

        false ->
            case Distance of
                D@4 when D@4 =:= R1 ->
                    {1, {R1, R0, R2}};

                D@5 when D@5 =:= R2 ->
                    {2, {R2, R0, R1}};

                D@6 when (R0 > 1) andalso (D@6 =:= (R0 - 1)) ->
                    {3, {R0 - 1, R0, R1}};

                D@7 ->
                    {D@7 + 3, {D@7, R0, R1}}
            end
    end.

-file("src/packkit/zstd.gleam", 1856).
-spec compute_seq_codes(
    list(zstd_sequence()),
    {integer(), integer(), integer()},
    list({integer(), integer(), integer(), integer(), integer(), integer()})
) -> list({integer(), integer(), integer(), integer(), integer(), integer()}).
compute_seq_codes(Sequences, Rep, Acc) ->
    case Sequences of
        [] ->
            lists:reverse(Acc);

        [Seq | Rest] ->
            Ll_code = ll_to_code(erlang:element(2, Seq)),
            Ml_code = ml_to_code(erlang:element(3, Seq)),
            {Raw_offset, Next_rep} = rep_aware_raw_offset(
                erlang:element(4, Seq),
                erlang:element(2, Seq),
                Rep
            ),
            Of_code = of_to_code(Raw_offset),
            Ll_extra_val = erlang:element(2, Seq) - packkit@internal@fse:ll_base(
                Ll_code
            ),
            Ml_extra_val = erlang:element(3, Seq) - packkit@internal@fse:ml_base(
                Ml_code
            ),
            Of_extra_val = Raw_offset - erlang:'bsl'(1, Of_code),
            compute_seq_codes(
                Rest,
                Next_rep,
                [{Ll_code,
                        Ml_code,
                        Of_code,
                        Ll_extra_val,
                        Ml_extra_val,
                        Of_extra_val} |
                    Acc]
            )
    end.

-file("src/packkit/zstd.gleam", 1917).
-spec build_seq_enc_slots_loop(
    gleam@dict:dict(integer(), packkit@internal@fse:state_entry()),
    integer(),
    integer(),
    gleam@dict:dict(integer(), list(fse_enc_slot()))
) -> gleam@dict:dict(integer(), list(fse_enc_slot())).
build_seq_enc_slots_loop(Table, S_idx, Table_size, Acc) ->
    case S_idx >= Table_size of
        true ->
            Acc;

        false ->
            Entry = case gleam_stdlib:map_get(Table, S_idx) of
                {ok, E} ->
                    E;

                {error, _} ->
                    {state_entry, 0, 0, 0}
            end,
            Span = erlang:'bsl'(1, erlang:element(3, Entry)),
            Slot = {fse_enc_slot,
                S_idx,
                erlang:element(4, Entry),
                erlang:element(4, Entry) + Span,
                erlang:element(3, Entry)},
            Existing = case gleam_stdlib:map_get(Acc, erlang:element(2, Entry)) of
                {ok, L} ->
                    L;

                {error, _} ->
                    []
            end,
            build_seq_enc_slots_loop(
                Table,
                S_idx + 1,
                Table_size,
                gleam@dict:insert(
                    Acc,
                    erlang:element(2, Entry),
                    [Slot | Existing]
                )
            )
    end.

-file("src/packkit/zstd.gleam", 1910).
-spec build_seq_enc_slots(
    gleam@dict:dict(integer(), packkit@internal@fse:state_entry()),
    integer()
) -> gleam@dict:dict(integer(), list(fse_enc_slot())).
build_seq_enc_slots(Table, Table_size) ->
    build_seq_enc_slots_loop(Table, 0, Table_size, maps:new()).

-file("src/packkit/zstd.gleam", 1952).
-spec smallest_state_in(
    gleam@dict:dict(integer(), list(fse_enc_slot())),
    integer(),
    integer()
) -> integer().
smallest_state_in(Slots, Symbol, Table_size) ->
    case gleam_stdlib:map_get(Slots, Symbol) of
        {error, _} ->
            0;

        {ok, []} ->
            0;

        {ok, List} ->
            smallest_state_idx_loop(List, Table_size)
    end.

-file("src/packkit/zstd.gleam", 2168).
-spec bump_count(gleam@dict:dict(integer(), integer()), integer()) -> integer().
bump_count(D, Key) ->
    case gleam_stdlib:map_get(D, Key) of
        {ok, V} ->
            V + 1;

        {error, _} ->
            1
    end.

-file("src/packkit/zstd.gleam", 2151).
-spec tally_seq_alphabets(
    list({integer(), integer(), integer(), integer(), integer(), integer()}),
    gleam@dict:dict(integer(), integer()),
    gleam@dict:dict(integer(), integer()),
    gleam@dict:dict(integer(), integer())
) -> {gleam@dict:dict(integer(), integer()),
    gleam@dict:dict(integer(), integer()),
    gleam@dict:dict(integer(), integer())}.
tally_seq_alphabets(Seq_codes, Ll, Of_acc, Ml) ->
    case Seq_codes of
        [] ->
            {Ll, Of_acc, Ml};

        [{Ll_c, Ml_c, Of_c, _, _, _} | Rest] ->
            Ll@1 = gleam@dict:insert(Ll, Ll_c, bump_count(Ll, Ll_c)),
            Of_acc@1 = gleam@dict:insert(Of_acc, Of_c, bump_count(Of_acc, Of_c)),
            Ml@1 = gleam@dict:insert(Ml, Ml_c, bump_count(Ml, Ml_c)),
            tally_seq_alphabets(Rest, Ll@1, Of_acc@1, Ml@1)
    end.

-file("src/packkit/zstd.gleam", 2211).
-spec highest_used_seq_code(gleam@dict:dict(integer(), integer()), integer()) -> integer().
highest_used_seq_code(Counts, Max_symbol) ->
    gleam@dict:fold(
        Counts,
        -1,
        fun(Acc, Sym, Count) ->
            case ((Count > 0) andalso (Sym > Acc)) andalso (Sym =< Max_symbol) of
                true ->
                    Sym;

                false ->
                    Acc
            end
        end
    ).

-file("src/packkit/zstd.gleam", 2224).
-spec pick_accuracy_log_loop(integer(), integer(), integer()) -> integer().
pick_accuracy_log_loop(Log, Target, Cap) ->
    case Log >= Cap of
        true ->
            Cap;

        false ->
            case erlang:'bsl'(1, Log) >= Target of
                true ->
                    Log;

                false ->
                    pick_accuracy_log_loop(Log + 1, Target, Cap)
            end
    end.

-file("src/packkit/zstd.gleam", 2220).
-spec pick_accuracy_log(integer(), integer()) -> integer().
pick_accuracy_log(Num_used_symbols, Cap) ->
    pick_accuracy_log_loop(5, Num_used_symbols, Cap).

-file("src/packkit/zstd.gleam", 2263).
-spec build_floor_normalized_seq(
    gleam@dict:dict(integer(), integer()),
    integer(),
    integer(),
    integer(),
    integer(),
    list(integer())
) -> list(integer()).
build_floor_normalized_seq(Counts, Total, Table_size, Sym, Max_used, Acc) ->
    case Sym > Max_used of
        true ->
            lists:reverse(Acc);

        false ->
            Count = case gleam_stdlib:map_get(Counts, Sym) of
                {ok, V} ->
                    V;

                {error, _} ->
                    0
            end,
            Normalized = case Count of
                0 ->
                    0;

                _ ->
                    Scaled = case Total of
                        0 -> 0;
                        Gleam@denominator -> Count * Table_size div Gleam@denominator
                    end,
                    case Scaled of
                        0 ->
                            1;

                        V@1 ->
                            V@1
                    end
            end,
            build_floor_normalized_seq(
                Counts,
                Total,
                Table_size,
                Sym + 1,
                Max_used,
                [Normalized | Acc]
            )
    end.

-file("src/packkit/zstd.gleam", 2235).
-spec normalize_seq_counts(
    gleam@dict:dict(integer(), integer()),
    integer(),
    integer(),
    integer(),
    integer()
) -> {ok, list(integer())} | {error, nil}.
normalize_seq_counts(Counts, Total, Max_used, Table_size, _) ->
    case Total of
        0 ->
            {error, nil};

        _ ->
            Raw = build_floor_normalized_seq(
                Counts,
                Total,
                Table_size,
                0,
                Max_used,
                []
            ),
            Sum = sum_int_list(Raw, 0),
            Diff = Table_size - Sum,
            case Diff of
                0 ->
                    {ok, Raw};

                _ ->
                    Idx = find_largest_count_index(Counts, Max_used),
                    case Idx < 0 of
                        true ->
                            {error, nil};

                        false ->
                            {ok, adjust_normalized_at(Raw, Idx, Diff, 0, [])}
                    end
            end
    end.

-file("src/packkit/zstd.gleam", 2181).
-spec prep_alphabet(
    gleam@dict:dict(integer(), integer()),
    integer(),
    integer(),
    integer()
) -> {ok, {list(integer()), integer(), integer(), bitstring()}} | {error, nil}.
prep_alphabet(Counts, Total, Max_symbol, Max_log) ->
    Max_used = highest_used_seq_code(Counts, Max_symbol),
    case Max_used < 0 of
        true ->
            {error, nil};

        false ->
            Log = pick_accuracy_log(Max_used + 1, Max_log),
            Table_size = erlang:'bsl'(1, Log),
            case normalize_seq_counts(Counts, Total, Max_used, Table_size, Log) of
                {error, _} ->
                    {error, nil};

                {ok, Norm} ->
                    Desc = encode_fse_dist_header_with_log(Norm, Max_used, Log),
                    {ok, {Norm, Max_used, Log, Desc}}
            end
    end.

-file("src/packkit/zstd.gleam", 2341).
-spec push_state_update(
    gleam@dict:dict(integer(), list(fse_enc_slot())),
    integer(),
    integer(),
    integer(),
    integer(),
    bitstring()
) -> {integer(), integer(), bitstring(), integer()}.
push_state_update(Slots, Symbol, Current_state, Buf, Bits, Out) ->
    case find_slot_for(Slots, Symbol, Current_state) of
        {error, _} ->
            {Buf, Bits, Out, Current_state};

        {ok, Slot} ->
            Emit_value = Current_state - erlang:element(3, Slot),
            {Buf@1, Bits@1, Out@1} = push_bits_unchecked(
                Buf,
                Bits,
                Out,
                Emit_value,
                erlang:element(5, Slot)
            ),
            {Buf@1, Bits@1, Out@1, erlang:element(2, Slot)}
    end.

-file("src/packkit/zstd.gleam", 2296).
-spec seq_encode_loop(
    list({integer(), integer(), integer(), integer(), integer(), integer()}),
    gleam@dict:dict(integer(), list(fse_enc_slot())),
    gleam@dict:dict(integer(), list(fse_enc_slot())),
    gleam@dict:dict(integer(), list(fse_enc_slot())),
    integer(),
    integer(),
    integer(),
    integer(),
    integer(),
    bitstring()
) -> {integer(), integer(), bitstring(), integer(), integer(), integer()}.
seq_encode_loop(
    Remaining,
    Ll_slots,
    Of_slots,
    Ml_slots,
    Ll_state,
    Of_state,
    Ml_state,
    Buf,
    Bits,
    Out
) ->
    case Remaining of
        [] ->
            {Buf, Bits, Out, Ll_state, Of_state, Ml_state};

        [{Ll_c, Ml_c, Of_c, Ll_e, Ml_e, Of_e} | Rest] ->
            {Buf@1, Bits@1, Out@1, Of_prev} = push_state_update(
                Of_slots,
                Of_c,
                Of_state,
                Buf,
                Bits,
                Out
            ),
            {Buf@2, Bits@2, Out@2, Ml_prev} = push_state_update(
                Ml_slots,
                Ml_c,
                Ml_state,
                Buf@1,
                Bits@1,
                Out@1
            ),
            {Buf@3, Bits@3, Out@3, Ll_prev} = push_state_update(
                Ll_slots,
                Ll_c,
                Ll_state,
                Buf@2,
                Bits@2,
                Out@2
            ),
            {Buf@4, Bits@4, Out@4} = push_bits_unchecked(
                Buf@3,
                Bits@3,
                Out@3,
                Ll_e,
                packkit@internal@fse:ll_extra_bits(Ll_c)
            ),
            {Buf@5, Bits@5, Out@5} = push_bits_unchecked(
                Buf@4,
                Bits@4,
                Out@4,
                Ml_e,
                packkit@internal@fse:ml_extra_bits(Ml_c)
            ),
            {Buf@6, Bits@6, Out@6} = push_bits_unchecked(
                Buf@5,
                Bits@5,
                Out@5,
                Of_e,
                Of_c
            ),
            seq_encode_loop(
                Rest,
                Ll_slots,
                Of_slots,
                Ml_slots,
                Ll_prev,
                Of_prev,
                Ml_prev,
                Buf@6,
                Bits@6,
                Out@6
            )
    end.

-file("src/packkit/zstd.gleam", 1974).
?DOC(
    " Encode the FSE sequence bitstream using the supplied per-alphabet\n"
    " encoder lookups and accuracy logs.  Emits the bits in reverse\n"
    " decoder-read order so the resulting backward bitstream finalises\n"
    " with the standard \"highest-set-bit of the last byte\" marker.\n"
    " `seq_codes` is the forward-order list produced by\n"
    " `compute_seq_codes` (which already integrates rep-offset\n"
    " collapsing).\n"
).
-spec encode_seq_fse_with_tables(
    list({integer(), integer(), integer(), integer(), integer(), integer()}),
    gleam@dict:dict(integer(), list(fse_enc_slot())),
    gleam@dict:dict(integer(), list(fse_enc_slot())),
    gleam@dict:dict(integer(), list(fse_enc_slot())),
    integer(),
    integer(),
    integer()
) -> bitstring().
encode_seq_fse_with_tables(
    Seq_codes,
    Ll_slots,
    Of_slots,
    Ml_slots,
    Ll_log,
    Of_log,
    Ml_log
) ->
    Ll_size = erlang:'bsl'(1, Ll_log),
    Of_size = erlang:'bsl'(1, Of_log),
    Ml_size = erlang:'bsl'(1, Ml_log),
    Reversed = lists:reverse(Seq_codes),
    case Reversed of
        [] ->
            <<>>;

        [First | Rest] ->
            {Ll0_c, Ml0_c, Of0_c, Ll0_e, Ml0_e, Of0_e} = First,
            Ll_state = smallest_state_in(Ll_slots, Ll0_c, Ll_size),
            Of_state = smallest_state_in(Of_slots, Of0_c, Of_size),
            Ml_state = smallest_state_in(Ml_slots, Ml0_c, Ml_size),
            {Buf, Bits, Out} = {0, 0, <<>>},
            {Buf@1, Bits@1, Out@1} = push_bits_unchecked(
                Buf,
                Bits,
                Out,
                Ll0_e,
                packkit@internal@fse:ll_extra_bits(Ll0_c)
            ),
            {Buf@2, Bits@2, Out@2} = push_bits_unchecked(
                Buf@1,
                Bits@1,
                Out@1,
                Ml0_e,
                packkit@internal@fse:ml_extra_bits(Ml0_c)
            ),
            {Buf@3, Bits@3, Out@3} = push_bits_unchecked(
                Buf@2,
                Bits@2,
                Out@2,
                Of0_e,
                Of0_c
            ),
            {Buf@4, Bits@4, Out@4, Ll_state@1, Of_state@1, Ml_state@1} = seq_encode_loop(
                Rest,
                Ll_slots,
                Of_slots,
                Ml_slots,
                Ll_state,
                Of_state,
                Ml_state,
                Buf@3,
                Bits@3,
                Out@3
            ),
            {Buf@5, Bits@5, Out@5} = push_bits_unchecked(
                Buf@4,
                Bits@4,
                Out@4,
                Ml_state@1,
                Ml_log
            ),
            {Buf@6, Bits@6, Out@6} = push_bits_unchecked(
                Buf@5,
                Bits@5,
                Out@5,
                Of_state@1,
                Of_log
            ),
            {Buf@7, Bits@7, Out@7} = push_bits_unchecked(
                Buf@6,
                Bits@6,
                Out@6,
                Ll_state@1,
                Ll_log
            ),
            Buf2 = erlang:'bor'(Buf@7, erlang:'bsl'(1, Bits@7)),
            Bits2 = Bits@7 + 1,
            flush_final_bits(Buf2, Bits2, Out@7)
    end.

-file("src/packkit/zstd.gleam", 2036).
?DOC(
    " Predefined_Mode sequence section: count bytes, mode byte 0x00,\n"
    " FSE bitstream against the three predefined distributions.\n"
).
-spec build_seq_section_predefined(
    bitstring(),
    list({integer(), integer(), integer(), integer(), integer(), integer()})
) -> bitstring().
build_seq_section_predefined(Count_bytes, Seq_codes) ->
    Ll_table = packkit@internal@fse:predefined_literal_length_table(),
    Of_table = packkit@internal@fse:predefined_offset_table(),
    Ml_table = packkit@internal@fse:predefined_match_length_table(),
    Ll_log = packkit@internal@fse:predefined_literal_length_log(),
    Of_log = packkit@internal@fse:predefined_offset_log(),
    Ml_log = packkit@internal@fse:predefined_match_length_log(),
    Ll_slots = build_seq_enc_slots(Ll_table, erlang:'bsl'(1, Ll_log)),
    Of_slots = build_seq_enc_slots(Of_table, erlang:'bsl'(1, Of_log)),
    Ml_slots = build_seq_enc_slots(Ml_table, erlang:'bsl'(1, Ml_log)),
    Seq_bitstream = encode_seq_fse_with_tables(
        Seq_codes,
        Ll_slots,
        Of_slots,
        Ml_slots,
        Ll_log,
        Of_log,
        Ml_log
    ),
    gleam_stdlib:bit_array_concat([Count_bytes, <<16#00>>, Seq_bitstream]).

-file("src/packkit/zstd.gleam", 2362).
-spec encode_sequences_count(integer()) -> bitstring().
encode_sequences_count(Num) ->
    case Num of
        N when N < 128 ->
            <<N>>;

        N@1 when N@1 < 16#7F00 ->
            High = erlang:'bsr'(N@1, 8) + 128,
            Low = erlang:'band'(N@1, 16#FF),
            <<High, Low>>;

        N@2 ->
            Value = N@2 - 16#7F00,
            Lo = erlang:'band'(Value, 16#FF),
            Hi = erlang:'band'(erlang:'bsr'(Value, 8), 16#FF),
            <<255, Lo, Hi>>
    end.

-file("src/packkit/zstd.gleam", 2483).
-spec build_raw_literals_section(bitstring(), integer()) -> bitstring().
build_raw_literals_section(Literals, Size) ->
    B0 = erlang:'bor'(16#00, erlang:'bsl'(erlang:'band'(Size, 16#0F), 4)),
    B0@1 = erlang:'bor'(B0, erlang:'bsl'(3, 2)),
    B1 = erlang:'band'(erlang:'bsr'(Size, 4), 16#FF),
    B2 = erlang:'band'(erlang:'bsr'(Size, 12), 16#FF),
    gleam_stdlib:bit_array_concat([<<B0@1, B1, B2>>, Literals]).

-file("src/packkit/zstd.gleam", 2494).
-spec build_rle_literals_section(integer(), integer()) -> bitstring().
build_rle_literals_section(Byte, Size) ->
    B0 = erlang:'bor'(16#01, erlang:'bsl'(erlang:'band'(Size, 16#0F), 4)),
    B0@1 = erlang:'bor'(B0, erlang:'bsl'(3, 2)),
    B1 = erlang:'band'(erlang:'bsr'(Size, 4), 16#FF),
    B2 = erlang:'band'(erlang:'bsr'(Size, 12), 16#FF),
    gleam_stdlib:bit_array_concat([<<B0@1, B1, B2>>, <<Byte>>]).

-file("src/packkit/zstd.gleam", 2660).
-spec consume_checksum_returning_rest(bitstring(), boolean()) -> {ok,
        bitstring()} |
    {error, packkit@error:codec_error()}.
consume_checksum_returning_rest(Bytes, Checksum_flag) ->
    case Checksum_flag of
        false ->
            {ok, Bytes};

        true ->
            case Bytes of
                <<_:4/binary, Rest/binary>> ->
                    {ok, Rest};

                _ ->
                    {error,
                        {codec_invalid_data,
                            <<"zstd content checksum is shorter than 4 bytes"/utf8>>}}
            end
    end.

-file("src/packkit/zstd.gleam", 2721).
-spec skip_window_descriptor(bitstring()) -> {ok, bitstring()} |
    {error, packkit@error:codec_error()}.
skip_window_descriptor(Bytes) ->
    case Bytes of
        <<_, Rest/binary>> ->
            {ok, Rest};

        _ ->
            {error,
                {codec_invalid_data,
                    <<"truncated zstd window descriptor"/utf8>>}}
    end.

-file("src/packkit/zstd.gleam", 3085).
-spec huf_error_to_codec(packkit@internal@huf:huf_error()) -> packkit@error:codec_error().
huf_error_to_codec(Err) ->
    case Err of
        {huf_truncated, Message} ->
            {codec_invalid_data, Message};

        {huf_invalid_weights, Message@1} ->
            {codec_invalid_data, Message@1};

        {huf_bitstream_error, _} ->
            {codec_invalid_data, <<"zstd Huffman bitstream truncated"/utf8>>};

        {huf_unsupported, Feature} ->
            {codec_not_implemented, Feature}
    end.

-file("src/packkit/zstd.gleam", 3070).
-spec decode_huffman_streams(
    packkit@internal@huf:tree(),
    bitstring(),
    compressed_literals_header()
) -> {ok, bitstring()} | {error, packkit@error:codec_error()}.
decode_huffman_streams(Tree, Bitstream_bytes, Header) ->
    case erlang:element(4, Header) of
        1 ->
            _pipe = packkit@internal@huf:decode_stream(
                Tree,
                Bitstream_bytes,
                erlang:element(2, Header)
            ),
            gleam@result:map_error(_pipe, fun huf_error_to_codec/1);

        _ ->
            _pipe@1 = packkit@internal@huf:decode_four_streams(
                Tree,
                Bitstream_bytes,
                erlang:element(2, Header)
            ),
            gleam@result:map_error(_pipe@1, fun huf_error_to_codec/1)
    end.

-file("src/packkit/zstd.gleam", 3095).
-spec parse_compressed_literals_header(bitstring(), integer(), integer()) -> {ok,
        compressed_literals_header()} |
    {error, packkit@error:codec_error()}.
parse_compressed_literals_header(Bytes, Header_byte, Size_format) ->
    case Size_format of
        0 ->
            case Bytes of
                <<_, B1, B2, _/binary>> ->
                    High_bits_of_header_byte = erlang:'bsr'(Header_byte, 4),
                    Regenerated_size = erlang:'bor'(
                        High_bits_of_header_byte,
                        erlang:'bsl'(erlang:'band'(B1, 16#3F), 4)
                    ),
                    Compressed_size = erlang:'bor'(
                        erlang:'bsr'(B1, 6),
                        erlang:'bsl'(B2, 2)
                    ),
                    {ok,
                        {compressed_literals_header,
                            Regenerated_size,
                            Compressed_size,
                            1,
                            3}};

                _ ->
                    {error,
                        {codec_invalid_data,
                            <<"truncated zstd compressed-literals 3-byte header"/utf8>>}}
            end;

        1 ->
            case Bytes of
                <<_, B1@1, B2@1, _/binary>> ->
                    High_bits_of_header_byte@1 = erlang:'bsr'(Header_byte, 4),
                    Regenerated_size@1 = erlang:'bor'(
                        High_bits_of_header_byte@1,
                        erlang:'bsl'(erlang:'band'(B1@1, 16#3F), 4)
                    ),
                    Compressed_size@1 = erlang:'bor'(
                        erlang:'bsr'(B1@1, 6),
                        erlang:'bsl'(B2@1, 2)
                    ),
                    {ok,
                        {compressed_literals_header,
                            Regenerated_size@1,
                            Compressed_size@1,
                            4,
                            3}};

                _ ->
                    {error,
                        {codec_invalid_data,
                            <<"truncated zstd compressed-literals 3-byte header"/utf8>>}}
            end;

        2 ->
            case Bytes of
                <<_, B1@2, B2@2, B3, _/binary>> ->
                    High_bits_of_header_byte@2 = erlang:'bsr'(Header_byte, 4),
                    Regenerated_size@2 = erlang:'bor'(
                        High_bits_of_header_byte@2,
                        erlang:'bor'(
                            erlang:'bsl'(B1@2, 4),
                            erlang:'bsl'(erlang:'band'(B2@2, 16#3), 12)
                        )
                    ),
                    Compressed_size@2 = erlang:'bor'(
                        erlang:'bsr'(B2@2, 2),
                        erlang:'bsl'(B3, 6)
                    ),
                    {ok,
                        {compressed_literals_header,
                            Regenerated_size@2,
                            Compressed_size@2,
                            4,
                            4}};

                _ ->
                    {error,
                        {codec_invalid_data,
                            <<"truncated zstd compressed-literals 4-byte header"/utf8>>}}
            end;

        _ ->
            case Bytes of
                <<_, B1@3, B2@3, B3@1, B4, _/binary>> ->
                    High_bits_of_header_byte@3 = erlang:'bsr'(Header_byte, 4),
                    Regenerated_size@3 = erlang:'bor'(
                        High_bits_of_header_byte@3,
                        erlang:'bor'(
                            erlang:'bsl'(B1@3, 4),
                            erlang:'bsl'(erlang:'band'(B2@3, 16#3F), 12)
                        )
                    ),
                    Compressed_size@3 = erlang:'bor'(
                        erlang:'bsr'(B2@3, 6),
                        erlang:'bor'(
                            erlang:'bsl'(B3@1, 2),
                            erlang:'bsl'(B4, 10)
                        )
                    ),
                    {ok,
                        {compressed_literals_header,
                            Regenerated_size@3,
                            Compressed_size@3,
                            4,
                            5}};

                _ ->
                    {error,
                        {codec_invalid_data,
                            <<"truncated zstd compressed-literals 5-byte header"/utf8>>}}
            end
    end.

-file("src/packkit/zstd.gleam", 3306).
-spec zstd_repeat_byte(integer(), integer(), bitstring()) -> bitstring().
zstd_repeat_byte(Byte, Count, Acc) ->
    case Count of
        0 ->
            Acc;

        _ ->
            zstd_repeat_byte(Byte, Count - 1, <<Acc/bitstring, Byte>>)
    end.

-file("src/packkit/zstd.gleam", 3455).
-spec alphabet_max_log(seq_alphabet()) -> integer().
alphabet_max_log(Alphabet) ->
    case Alphabet of
        seq_alphabet_ll ->
            9;

        seq_alphabet_of ->
            8;

        seq_alphabet_ml ->
            9
    end.

-file("src/packkit/zstd.gleam", 3463).
-spec alphabet_max_symbol(seq_alphabet()) -> integer().
alphabet_max_symbol(Alphabet) ->
    case Alphabet of
        seq_alphabet_ll ->
            35;

        seq_alphabet_of ->
            31;

        seq_alphabet_ml ->
            52
    end.

-file("src/packkit/zstd.gleam", 3474).
-spec predefined_for(seq_alphabet()) -> {gleam@dict:dict(integer(), packkit@internal@fse:state_entry()),
    integer()}.
predefined_for(Alphabet) ->
    case Alphabet of
        seq_alphabet_ll ->
            {packkit@internal@fse:predefined_literal_length_table(),
                packkit@internal@fse:predefined_literal_length_log()};

        seq_alphabet_of ->
            {packkit@internal@fse:predefined_offset_table(),
                packkit@internal@fse:predefined_offset_log()};

        seq_alphabet_ml ->
            {packkit@internal@fse:predefined_match_length_table(),
                packkit@internal@fse:predefined_match_length_log()}
    end.

-file("src/packkit/zstd.gleam", 3493).
-spec alphabet_label(seq_alphabet()) -> binary().
alphabet_label(Alphabet) ->
    case Alphabet of
        seq_alphabet_ll ->
            <<"literal_length"/utf8>>;

        seq_alphabet_of ->
            <<"offset"/utf8>>;

        seq_alphabet_ml ->
            <<"match_length"/utf8>>
    end.

-file("src/packkit/zstd.gleam", 3663).
-spec new_fwd_reader(bitstring()) -> fwd_bit_reader().
new_fwd_reader(Bytes) ->
    {fwd_bit_reader, Bytes, 0, 0, false, 0}.

-file("src/packkit/zstd.gleam", 3673).
-spec fwd_refill(fwd_bit_reader(), integer()) -> fwd_bit_reader().
fwd_refill(Reader, Needed) ->
    case (erlang:element(4, Reader) >= Needed) orelse erlang:element(5, Reader) of
        true ->
            Reader;

        false ->
            case erlang:element(2, Reader) of
                <<B, Rest/binary>> ->
                    fwd_refill(
                        {fwd_bit_reader,
                            Rest,
                            erlang:'bor'(
                                erlang:element(3, Reader),
                                erlang:'bsl'(B, erlang:element(4, Reader))
                            ),
                            erlang:element(4, Reader) + 8,
                            false,
                            erlang:element(6, Reader)},
                        Needed
                    );

                _ ->
                    {fwd_bit_reader,
                        erlang:element(2, Reader),
                        erlang:element(3, Reader),
                        erlang:element(4, Reader),
                        true,
                        erlang:element(6, Reader)}
            end
    end.

-file("src/packkit/zstd.gleam", 3697).
-spec fwd_peek(fwd_bit_reader(), integer()) -> {integer(), fwd_bit_reader()}.
fwd_peek(Reader, Count) ->
    Reader@1 = fwd_refill(Reader, Count),
    Mask = erlang:'bsl'(1, Count) - 1,
    {erlang:'band'(erlang:element(3, Reader@1), Mask), Reader@1}.

-file("src/packkit/zstd.gleam", 3703).
-spec fwd_drop(fwd_bit_reader(), integer()) -> fwd_bit_reader().
fwd_drop(Reader, Count) ->
    Reader@1 = fwd_refill(Reader, Count),
    {fwd_bit_reader,
        erlang:element(2, Reader@1),
        erlang:'bsr'(erlang:element(3, Reader@1), Count),
        erlang:element(4, Reader@1) - Count,
        erlang:element(5, Reader@1),
        erlang:element(6, Reader@1) + Count}.

-file("src/packkit/zstd.gleam", 3714).
-spec fwd_read(fwd_bit_reader(), integer(), binary()) -> {ok,
        {integer(), fwd_bit_reader()}} |
    {error, packkit@error:codec_error()}.
fwd_read(Reader, Count, Label) ->
    Reader@1 = fwd_refill(Reader, Count),
    case erlang:element(4, Reader@1) < Count of
        true ->
            {error,
                {codec_invalid_data, <<"truncated zstd "/utf8, Label/binary>>}};

        false ->
            {Value, Reader@2} = fwd_peek(Reader@1, Count),
            {ok, {Value, fwd_drop(Reader@2, Count)}}
    end.

-file("src/packkit/zstd.gleam", 3842).
?DOC(
    " Split out of `decode_fse_distribution` so the dominant case (short\n"
    " form) doesn't dominate the inner block's indentation budget.\n"
).
-spec decode_count_bits(integer(), integer(), integer(), integer()) -> {integer(),
    integer()}.
decode_count_bits(Value, Threshold, Remaining, Bit_count) ->
    Max_val = ((2 * Threshold) - 1) - Remaining,
    case erlang:'band'(Value, Threshold - 1) < Max_val of
        true ->
            {erlang:'band'(Value, Threshold - 1), Bit_count - 1};

        false ->
            Raw = erlang:'band'(Value, (2 * Threshold) - 1),
            Adjusted = case Raw >= Threshold of
                true ->
                    Raw - Max_val;

                false ->
                    Raw
            end,
            {Adjusted, Bit_count}
    end.

-file("src/packkit/zstd.gleam", 3869).
-spec read_zero_rle_loop(fwd_bit_reader(), integer(), binary()) -> {ok,
        {integer(), fwd_bit_reader()}} |
    {error, packkit@error:codec_error()}.
read_zero_rle_loop(Reader, Acc, Label) ->
    gleam@result:'try'(
        fwd_read(
            Reader,
            2,
            <<Label/binary, " FSE distribution zero-RLE flag"/utf8>>
        ),
        fun(_use0) ->
            {Value, Reader@1} = _use0,
            case Value of
                3 ->
                    read_zero_rle_loop(Reader@1, Acc + 3, Label);

                N ->
                    {ok, {Acc + N, Reader@1}}
            end
        end
    ).

-file("src/packkit/zstd.gleam", 3862).
-spec read_zero_rle(fwd_bit_reader(), binary()) -> {ok,
        {integer(), fwd_bit_reader()}} |
    {error, packkit@error:codec_error()}.
read_zero_rle(Reader, Label) ->
    read_zero_rle_loop(Reader, 0, Label).

-file("src/packkit/zstd.gleam", 3885).
-spec shrink_threshold(integer(), integer(), integer()) -> {integer(),
    integer()}.
shrink_threshold(Threshold, Bit_count, Remaining) ->
    case Remaining < Threshold of
        true ->
            shrink_threshold(Threshold div 2, Bit_count - 1, Remaining);

        false ->
            {Threshold, Bit_count}
    end.

-file("src/packkit/zstd.gleam", 3896).
-spec prepend_zeros(integer(), list(integer())) -> list(integer()).
prepend_zeros(Count, Acc) ->
    case Count of
        N when N =< 0 ->
            Acc;

        _ ->
            prepend_zeros(Count - 1, [0 | Acc])
    end.

-file("src/packkit/zstd.gleam", 3777).
-spec decode_fse_distribution(
    fwd_bit_reader(),
    integer(),
    integer(),
    integer(),
    integer(),
    boolean(),
    integer(),
    integer(),
    list(integer()),
    binary()
) -> {ok, {list(integer()), fwd_bit_reader()}} |
    {error, packkit@error:codec_error()}.
decode_fse_distribution(
    Reader,
    _,
    Remaining,
    Threshold,
    Bit_count,
    Previous_is_zero,
    Charnum,
    Max_symbol,
    Acc,
    Label
) ->
    case (Remaining > 1) andalso (Charnum =< Max_symbol) of
        false ->
            {ok, {lists:reverse(Acc), Reader}};

        true ->
            case Previous_is_zero of
                true ->
                    gleam@result:'try'(
                        read_zero_rle(Reader, Label),
                        fun(_use0) ->
                            {Extra, Reader@1} = _use0,
                            Acc@1 = prepend_zeros(Extra, Acc),
                            decode_fse_distribution(
                                Reader@1,
                                0,
                                Remaining,
                                Threshold,
                                Bit_count,
                                false,
                                Charnum + Extra,
                                Max_symbol,
                                Acc@1,
                                Label
                            )
                        end
                    );

                false ->
                    {Value, Reader@2} = fwd_peek(Reader, Bit_count),
                    {Count, Bits_consumed} = decode_count_bits(
                        Value,
                        Threshold,
                        Remaining,
                        Bit_count
                    ),
                    Reader@3 = fwd_drop(Reader@2, Bits_consumed),
                    Probability = Count - 1,
                    Abs_prob = case Probability < 0 of
                        true ->
                            - Probability;

                        false ->
                            Probability
                    end,
                    Remaining@1 = Remaining - Abs_prob,
                    Previous_is_zero@1 = Probability =:= 0,
                    {Threshold@1, Bit_count@1} = shrink_threshold(
                        Threshold,
                        Bit_count,
                        Remaining@1
                    ),
                    decode_fse_distribution(
                        Reader@3,
                        0,
                        Remaining@1,
                        Threshold@1,
                        Bit_count@1,
                        Previous_is_zero@1,
                        Charnum + 1,
                        Max_symbol,
                        [Probability | Acc],
                        Label
                    )
            end
    end.

-file("src/packkit/zstd.gleam", 3903).
-spec pad_distribution(list(integer()), integer()) -> list(integer()).
pad_distribution(Counts, Target) ->
    Current = erlang:length(Counts),
    case Current >= Target of
        true ->
            Counts;

        false ->
            lists:append(Counts, gleam@list:repeat(0, Target - Current))
    end.

-file("src/packkit/zstd.gleam", 3729).
-spec read_fse_distribution(bitstring(), integer(), integer(), binary()) -> {ok,
        {list(integer()), integer(), bitstring()}} |
    {error, packkit@error:codec_error()}.
read_fse_distribution(Bytes, Max_accuracy_log, Max_symbol, Label) ->
    Reader = new_fwd_reader(Bytes),
    gleam@result:'try'(
        fwd_read(Reader, 4, <<Label/binary, " distribution accuracy_log"/utf8>>),
        fun(_use0) ->
            {Accuracy_minus_5, Reader@1} = _use0,
            Accuracy_log = Accuracy_minus_5 + 5,
            gleam@bool:guard(
                Accuracy_log > Max_accuracy_log,
                {error,
                    {codec_invalid_data,
                        <<<<"zstd "/utf8, Label/binary>>/binary,
                            " FSE accuracy_log exceeds the alphabet's maximum"/utf8>>}},
                fun() ->
                    Table_size = erlang:'bsl'(1, Accuracy_log),
                    gleam@result:'try'(
                        decode_fse_distribution(
                            Reader@1,
                            Accuracy_log,
                            Table_size + 1,
                            Table_size,
                            Accuracy_log + 1,
                            false,
                            0,
                            Max_symbol,
                            [],
                            Label
                        ),
                        fun(_use0@1) ->
                            {Counts, Reader@2} = _use0@1,
                            Bytes_consumed = (erlang:element(6, Reader@2) + 7)
                            div 8,
                            Total = erlang:byte_size(Bytes),
                            case gleam_stdlib:bit_array_slice(
                                Bytes,
                                Bytes_consumed,
                                Total - Bytes_consumed
                            ) of
                                {ok, Rest} ->
                                    {ok,
                                        {pad_distribution(
                                                Counts,
                                                Max_symbol + 1
                                            ),
                                            Accuracy_log,
                                            Rest}};

                                {error, _} ->
                                    {error,
                                        {codec_invalid_data,
                                            <<<<"truncated zstd "/utf8,
                                                    Label/binary>>/binary,
                                                " FSE distribution tail"/utf8>>}}
                            end
                        end
                    )
                end
            )
        end
    ).

-file("src/packkit/zstd.gleam", 3507).
?DOC(
    " Read the table description for one sequence alphabet, honouring the\n"
    " Predefined / RLE / FSE_Compressed / Repeat selector encoded in the\n"
    " modes byte.  Returns the materialised state table, its accuracy_log\n"
    " (so the sequence decoder knows how many bits to read for the\n"
    " initial state), and the byte slice that immediately follows the\n"
    " table description.\n"
).
-spec load_sequence_table(
    bitstring(),
    integer(),
    seq_alphabet(),
    gleam@option:option({gleam@dict:dict(integer(), packkit@internal@fse:state_entry()),
        integer()})
) -> {ok,
        {gleam@dict:dict(integer(), packkit@internal@fse:state_entry()),
            integer(),
            bitstring()}} |
    {error, packkit@error:codec_error()}.
load_sequence_table(Bytes, Mode, Alphabet, Prev) ->
    case Mode of
        0 ->
            {Table, Accuracy_log} = predefined_for(Alphabet),
            {ok, {Table, Accuracy_log, Bytes}};

        1 ->
            case Bytes of
                <<Symbol, Rest/binary>> ->
                    Table@1 = maps:from_list([{0, {state_entry, Symbol, 0, 0}}]),
                    {ok, {Table@1, 0, Rest}};

                _ ->
                    {error,
                        {codec_invalid_data,
                            <<<<"truncated zstd "/utf8,
                                    (alphabet_label(Alphabet))/binary>>/binary,
                                " RLE mode symbol"/utf8>>}}
            end;

        2 ->
            gleam@result:'try'(
                read_fse_distribution(
                    Bytes,
                    alphabet_max_log(Alphabet),
                    alphabet_max_symbol(Alphabet),
                    alphabet_label(Alphabet)
                ),
                fun(_use0) ->
                    {Distribution, Accuracy_log@1, Rest@1} = _use0,
                    Table@2 = packkit@internal@fse:build_state_table(
                        Distribution,
                        Accuracy_log@1
                    ),
                    {ok, {Table@2, Accuracy_log@1, Rest@1}}
                end
            );

        _ ->
            case Prev of
                {some, {Table@3, Accuracy_log@2}} ->
                    {ok, {Table@3, Accuracy_log@2, Bytes}};

                none ->
                    {error,
                        {codec_invalid_data,
                            <<<<"zstd "/utf8,
                                    (alphabet_label(Alphabet))/binary>>/binary,
                                " Repeat_Mode without a prior FSE table"/utf8>>}}
            end
    end.

-file("src/packkit/zstd.gleam", 3911).
-spec read_state_init(
    packkit@internal@fse:backward_reader(),
    integer(),
    binary()
) -> {ok, {integer(), packkit@internal@fse:backward_reader()}} |
    {error, packkit@error:codec_error()}.
read_state_init(Reader, Bits, Label) ->
    case packkit@internal@fse:read_backward_bits(Reader, Bits) of
        {ok, {V, R}} ->
            {ok, {V, R}};

        {error, _} ->
            {error,
                {codec_invalid_data,
                    <<<<"truncated zstd "/utf8, Label/binary>>/binary,
                        " initial state"/utf8>>}}
    end.

-file("src/packkit/zstd.gleam", 4008).
-spec state_symbol(
    gleam@dict:dict(integer(), packkit@internal@fse:state_entry()),
    integer()
) -> integer().
state_symbol(Table, State) ->
    case gleam_stdlib:map_get(Table, State) of
        {ok, Entry} ->
            erlang:element(2, Entry);

        {error, _} ->
            0
    end.

-file("src/packkit/zstd.gleam", 4015).
-spec update_state(
    packkit@internal@fse:backward_reader(),
    gleam@dict:dict(integer(), packkit@internal@fse:state_entry()),
    integer(),
    binary()
) -> {ok, {packkit@internal@fse:backward_reader(), integer()}} |
    {error, packkit@error:codec_error()}.
update_state(Reader, Table, State, Label) ->
    Entry = case gleam_stdlib:map_get(Table, State) of
        {ok, E} ->
            E;

        {error, _} ->
            {state_entry, 0, 0, 0}
    end,
    case packkit@internal@fse:read_backward_bits(
        Reader,
        erlang:element(3, Entry)
    ) of
        {ok, {Extra, R}} ->
            {ok, {R, erlang:element(4, Entry) + Extra}};

        {error, _} ->
            {error,
                {codec_invalid_data,
                    <<<<"truncated zstd "/utf8, Label/binary>>/binary,
                        " state-update bits"/utf8>>}}
    end.

-file("src/packkit/zstd.gleam", 4034).
-spec read_bits_for(packkit@internal@fse:backward_reader(), integer(), binary()) -> {ok,
        {integer(), packkit@internal@fse:backward_reader()}} |
    {error, packkit@error:codec_error()}.
read_bits_for(Reader, Count, Label) ->
    case packkit@internal@fse:read_backward_bits(Reader, Count) of
        {ok, P} ->
            {ok, P};

        {error, _} ->
            {error,
                {codec_invalid_data, <<"truncated zstd "/utf8, Label/binary>>}}
    end.

-file("src/packkit/zstd.gleam", 4046).
-spec resolve_offset(seq_context(), integer(), integer(), integer()) -> {integer(),
    seq_context()}.
resolve_offset(Ctx, _, Raw_offset, Literal_length) ->
    case Raw_offset of
        1 ->
            case Literal_length of
                0 ->
                    Actual = erlang:element(7, Ctx),
                    {Actual,
                        {seq_context,
                            erlang:element(2, Ctx),
                            erlang:element(3, Ctx),
                            erlang:element(4, Ctx),
                            erlang:element(5, Ctx),
                            erlang:element(7, Ctx),
                            erlang:element(6, Ctx),
                            erlang:element(8, Ctx),
                            erlang:element(9, Ctx),
                            erlang:element(10, Ctx),
                            erlang:element(11, Ctx),
                            erlang:element(12, Ctx),
                            erlang:element(13, Ctx),
                            erlang:element(14, Ctx)}};

                _ ->
                    {erlang:element(6, Ctx), Ctx}
            end;

        2 ->
            case Literal_length of
                0 ->
                    Actual@1 = erlang:element(8, Ctx),
                    {Actual@1,
                        {seq_context,
                            erlang:element(2, Ctx),
                            erlang:element(3, Ctx),
                            erlang:element(4, Ctx),
                            erlang:element(5, Ctx),
                            Actual@1,
                            erlang:element(6, Ctx),
                            erlang:element(7, Ctx),
                            erlang:element(9, Ctx),
                            erlang:element(10, Ctx),
                            erlang:element(11, Ctx),
                            erlang:element(12, Ctx),
                            erlang:element(13, Ctx),
                            erlang:element(14, Ctx)}};

                _ ->
                    Actual@2 = erlang:element(7, Ctx),
                    {Actual@2,
                        {seq_context,
                            erlang:element(2, Ctx),
                            erlang:element(3, Ctx),
                            erlang:element(4, Ctx),
                            erlang:element(5, Ctx),
                            erlang:element(7, Ctx),
                            erlang:element(6, Ctx),
                            erlang:element(8, Ctx),
                            erlang:element(9, Ctx),
                            erlang:element(10, Ctx),
                            erlang:element(11, Ctx),
                            erlang:element(12, Ctx),
                            erlang:element(13, Ctx),
                            erlang:element(14, Ctx)}}
            end;

        3 ->
            case Literal_length of
                0 ->
                    Actual@3 = case erlang:element(6, Ctx) - 1 of
                        N when N =< 0 ->
                            1;

                        N@1 ->
                            N@1
                    end,
                    {Actual@3,
                        {seq_context,
                            erlang:element(2, Ctx),
                            erlang:element(3, Ctx),
                            erlang:element(4, Ctx),
                            erlang:element(5, Ctx),
                            Actual@3,
                            erlang:element(6, Ctx),
                            erlang:element(7, Ctx),
                            erlang:element(9, Ctx),
                            erlang:element(10, Ctx),
                            erlang:element(11, Ctx),
                            erlang:element(12, Ctx),
                            erlang:element(13, Ctx),
                            erlang:element(14, Ctx)}};

                _ ->
                    Actual@4 = erlang:element(8, Ctx),
                    {Actual@4,
                        {seq_context,
                            erlang:element(2, Ctx),
                            erlang:element(3, Ctx),
                            erlang:element(4, Ctx),
                            erlang:element(5, Ctx),
                            Actual@4,
                            erlang:element(6, Ctx),
                            erlang:element(7, Ctx),
                            erlang:element(9, Ctx),
                            erlang:element(10, Ctx),
                            erlang:element(11, Ctx),
                            erlang:element(12, Ctx),
                            erlang:element(13, Ctx),
                            erlang:element(14, Ctx)}}
            end;

        _ ->
            Actual@5 = Raw_offset - 3,
            {Actual@5,
                {seq_context,
                    erlang:element(2, Ctx),
                    erlang:element(3, Ctx),
                    erlang:element(4, Ctx),
                    erlang:element(5, Ctx),
                    Actual@5,
                    erlang:element(6, Ctx),
                    erlang:element(7, Ctx),
                    erlang:element(9, Ctx),
                    erlang:element(10, Ctx),
                    erlang:element(11, Ctx),
                    erlang:element(12, Ctx),
                    erlang:element(13, Ctx),
                    erlang:element(14, Ctx)}}
    end.

-file("src/packkit/zstd.gleam", 4181).
-spec nth_from_back(list(integer()), integer()) -> {ok, integer()} |
    {error, nil}.
nth_from_back(Values, N) ->
    case {Values, N} of
        {[Head | _], 0} ->
            {ok, Head};

        {[_ | Rest], _} ->
            nth_from_back(Rest, N - 1);

        {[], _} ->
            {error, nil}
    end.

-file("src/packkit/zstd.gleam", 4157).
-spec copy_match_loop(seq_context(), integer(), integer()) -> {ok,
        seq_context()} |
    {error, packkit@error:codec_error()}.
copy_match_loop(Ctx, Offset, Remaining) ->
    case Remaining of
        0 ->
            {ok, Ctx};

        _ ->
            case nth_from_back(erlang:element(4, Ctx), Offset - 1) of
                {ok, Byte} ->
                    copy_match_loop(
                        {seq_context,
                            erlang:element(2, Ctx),
                            erlang:element(3, Ctx),
                            [Byte | erlang:element(4, Ctx)],
                            erlang:element(5, Ctx),
                            erlang:element(6, Ctx),
                            erlang:element(7, Ctx),
                            erlang:element(8, Ctx),
                            erlang:element(9, Ctx),
                            erlang:element(10, Ctx),
                            erlang:element(11, Ctx),
                            erlang:element(12, Ctx),
                            erlang:element(13, Ctx),
                            erlang:element(14, Ctx)},
                        Offset,
                        Remaining - 1
                    );

                {error, _} ->
                    {error,
                        {codec_invalid_data,
                            <<"zstd match offset exceeds emitted output"/utf8>>}}
            end
    end.

-file("src/packkit/zstd.gleam", 4149).
-spec copy_match(seq_context(), integer(), integer()) -> {ok, seq_context()} |
    {error, packkit@error:codec_error()}.
copy_match(Ctx, Offset, Length) ->
    copy_match_loop(Ctx, Offset, Length).

-file("src/packkit/zstd.gleam", 4189).
-spec prepend_bytes(bitstring(), list(integer())) -> list(integer()).
prepend_bytes(Chunk, Acc) ->
    case Chunk of
        <<B, Rest/binary>> ->
            prepend_bytes(Rest, [B | Acc]);

        _ ->
            Acc
    end.

-file("src/packkit/zstd.gleam", 2859).
?DOC(
    " Prepend this block's output bytes to the running per-frame\n"
    " reversed output so the next block's matches can reach back.\n"
).
-spec append_block_output(block_state(), bitstring()) -> block_state().
append_block_output(State, Plain) ->
    {block_state,
        erlang:element(2, State),
        erlang:element(3, State),
        prepend_bytes(Plain, erlang:element(4, State)),
        erlang:element(5, State)}.

-file("src/packkit/zstd.gleam", 4124).
-spec copy_literals(seq_context(), integer()) -> {ok, seq_context()} |
    {error, packkit@error:codec_error()}.
copy_literals(Ctx, Count) ->
    case Count of
        0 ->
            {ok, Ctx};

        _ ->
            case gleam_stdlib:bit_array_slice(
                erlang:element(2, Ctx),
                erlang:element(3, Ctx),
                Count
            ) of
                {ok, Chunk} ->
                    {ok,
                        {seq_context,
                            erlang:element(2, Ctx),
                            erlang:element(3, Ctx) + Count,
                            prepend_bytes(Chunk, erlang:element(4, Ctx)),
                            erlang:element(5, Ctx),
                            erlang:element(6, Ctx),
                            erlang:element(7, Ctx),
                            erlang:element(8, Ctx),
                            erlang:element(9, Ctx),
                            erlang:element(10, Ctx),
                            erlang:element(11, Ctx),
                            erlang:element(12, Ctx),
                            erlang:element(13, Ctx),
                            erlang:element(14, Ctx)}};

                {error, _} ->
                    {error,
                        {codec_invalid_data,
                            <<"zstd literal copy exceeds literals section"/utf8>>}}
            end
    end.

-file("src/packkit/zstd.gleam", 3925).
-spec decode_sequence_loop(
    integer(),
    seq_context(),
    packkit@internal@fse:backward_reader()
) -> {ok, seq_context()} | {error, packkit@error:codec_error()}.
decode_sequence_loop(Remaining, Ctx, Reader) ->
    case Remaining of
        0 ->
            {ok, Ctx};

        _ ->
            Ll_code = state_symbol(
                erlang:element(12, Ctx),
                erlang:element(9, Ctx)
            ),
            Of_code = state_symbol(
                erlang:element(13, Ctx),
                erlang:element(10, Ctx)
            ),
            Ml_code = state_symbol(
                erlang:element(14, Ctx),
                erlang:element(11, Ctx)
            ),
            gleam@result:'try'(
                read_bits_for(Reader, Of_code, <<"offset extra"/utf8>>),
                fun(_use0) ->
                    {Offset_value, Reader@1} = _use0,
                    gleam@result:'try'(
                        read_bits_for(
                            Reader@1,
                            packkit@internal@fse:ml_extra_bits(Ml_code),
                            <<"match-length extra"/utf8>>
                        ),
                        fun(_use0@1) ->
                            {Match_extra, Reader@2} = _use0@1,
                            gleam@result:'try'(
                                read_bits_for(
                                    Reader@2,
                                    packkit@internal@fse:ll_extra_bits(Ll_code),
                                    <<"literal-length extra"/utf8>>
                                ),
                                fun(_use0@2) ->
                                    {Lit_extra, Reader@3} = _use0@2,
                                    Literal_length = packkit@internal@fse:ll_base(
                                        Ll_code
                                    )
                                    + Lit_extra,
                                    Match_length = packkit@internal@fse:ml_base(
                                        Ml_code
                                    )
                                    + Match_extra,
                                    Raw_offset = erlang:'bsl'(1, Of_code) + Offset_value,
                                    {Actual_offset, Ctx_after_offset} = resolve_offset(
                                        Ctx,
                                        Of_code,
                                        Raw_offset,
                                        Literal_length
                                    ),
                                    gleam@result:'try'(
                                        copy_literals(
                                            Ctx_after_offset,
                                            Literal_length
                                        ),
                                        fun(Ctx_after_lit) ->
                                            gleam@result:'try'(
                                                copy_match(
                                                    Ctx_after_lit,
                                                    Actual_offset,
                                                    Match_length
                                                ),
                                                fun(Ctx_after_match) ->
                                                    case Remaining of
                                                        1 ->
                                                            {ok,
                                                                Ctx_after_match};

                                                        _ ->
                                                            gleam@result:'try'(
                                                                update_state(
                                                                    Reader@3,
                                                                    erlang:element(
                                                                        12,
                                                                        Ctx
                                                                    ),
                                                                    erlang:element(
                                                                        9,
                                                                        Ctx
                                                                    ),
                                                                    <<"literal_length"/utf8>>
                                                                ),
                                                                fun(_use0@3) ->
                                                                    {Reader@4,
                                                                        Ll_state} = _use0@3,
                                                                    gleam@result:'try'(
                                                                        update_state(
                                                                            Reader@4,
                                                                            erlang:element(
                                                                                14,
                                                                                Ctx
                                                                            ),
                                                                            erlang:element(
                                                                                11,
                                                                                Ctx
                                                                            ),
                                                                            <<"match_length"/utf8>>
                                                                        ),
                                                                        fun(
                                                                            _use0@4
                                                                        ) ->
                                                                            {Reader@5,
                                                                                Ml_state} = _use0@4,
                                                                            gleam@result:'try'(
                                                                                update_state(
                                                                                    Reader@5,
                                                                                    erlang:element(
                                                                                        13,
                                                                                        Ctx
                                                                                    ),
                                                                                    erlang:element(
                                                                                        10,
                                                                                        Ctx
                                                                                    ),
                                                                                    <<"offset"/utf8>>
                                                                                ),
                                                                                fun(
                                                                                    _use0@5
                                                                                ) ->
                                                                                    {Reader@6,
                                                                                        Of_state} = _use0@5,
                                                                                    decode_sequence_loop(
                                                                                        Remaining
                                                                                        - 1,
                                                                                        {seq_context,
                                                                                            erlang:element(
                                                                                                2,
                                                                                                Ctx_after_match
                                                                                            ),
                                                                                            erlang:element(
                                                                                                3,
                                                                                                Ctx_after_match
                                                                                            ),
                                                                                            erlang:element(
                                                                                                4,
                                                                                                Ctx_after_match
                                                                                            ),
                                                                                            erlang:element(
                                                                                                5,
                                                                                                Ctx_after_match
                                                                                            ),
                                                                                            erlang:element(
                                                                                                6,
                                                                                                Ctx_after_match
                                                                                            ),
                                                                                            erlang:element(
                                                                                                7,
                                                                                                Ctx_after_match
                                                                                            ),
                                                                                            erlang:element(
                                                                                                8,
                                                                                                Ctx_after_match
                                                                                            ),
                                                                                            Ll_state,
                                                                                            Of_state,
                                                                                            Ml_state,
                                                                                            erlang:element(
                                                                                                12,
                                                                                                Ctx_after_match
                                                                                            ),
                                                                                            erlang:element(
                                                                                                13,
                                                                                                Ctx_after_match
                                                                                            ),
                                                                                            erlang:element(
                                                                                                14,
                                                                                                Ctx_after_match
                                                                                            )},
                                                                                        Reader@6
                                                                                    )
                                                                                end
                                                                            )
                                                                        end
                                                                    )
                                                                end
                                                            )
                                                    end
                                                end
                                            )
                                        end
                                    )
                                end
                            )
                        end
                    )
                end
            )
    end.

-file("src/packkit/zstd.gleam", 4212).
?DOC(
    " Drop the `n` trailing elements from a list.  Used to strip the\n"
    " previous-blocks suffix off the running output buffer so only the\n"
    " current block's payload is returned.\n"
).
-spec list_drop_tail(list(integer()), integer()) -> list(integer()).
list_drop_tail(Items, N) ->
    Total = erlang:length(Items),
    case Total - N of
        Keep when Keep =< 0 ->
            [];

        Keep@1 ->
            gleam@list:take(Items, Keep@1)
    end.

-file("src/packkit/zstd.gleam", 4220).
-spec reverse_list_to_bit_array(list(integer()), bitstring()) -> bitstring().
reverse_list_to_bit_array(Values, Acc) ->
    case Values of
        [] ->
            Acc;

        [Head | Rest] ->
            reverse_list_to_bit_array(Rest, <<Head, Acc/bitstring>>)
    end.

-file("src/packkit/zstd.gleam", 4196).
-spec append_remaining_literals(seq_context()) -> bitstring().
append_remaining_literals(Ctx) ->
    Remaining = erlang:byte_size(erlang:element(2, Ctx)) - erlang:element(
        3,
        Ctx
    ),
    Tail@1 = case gleam_stdlib:bit_array_slice(
        erlang:element(2, Ctx),
        erlang:element(3, Ctx),
        Remaining
    ) of
        {ok, Tail} -> Tail;
        _assert_fail ->
            erlang:error(#{gleam_error => let_assert,
                        message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
                        file => <<?FILEPATH/utf8>>,
                        module => <<"packkit/zstd"/utf8>>,
                        function => <<"append_remaining_literals"/utf8>>,
                        line => 4198,
                        value => _assert_fail,
                        start => 127265,
                        'end' => 127348,
                        pattern_start => 127276,
                        pattern_end => 127284})
    end,
    This_block_rev = list_drop_tail(
        erlang:element(4, Ctx),
        erlang:element(5, Ctx)
    ),
    Prefix = reverse_list_to_bit_array(This_block_rev, <<>>),
    gleam_stdlib:bit_array_concat([Prefix, Tail@1]).

-file("src/packkit/zstd.gleam", 3566).
-spec apply_sequences_with_tables(
    integer(),
    bitstring(),
    bitstring(),
    gleam@dict:dict(integer(), packkit@internal@fse:state_entry()),
    integer(),
    gleam@dict:dict(integer(), packkit@internal@fse:state_entry()),
    integer(),
    gleam@dict:dict(integer(), packkit@internal@fse:state_entry()),
    integer(),
    list(integer()),
    {integer(), integer(), integer()}
) -> {ok, {bitstring(), {integer(), integer(), integer()}}} |
    {error, packkit@error:codec_error()}.
apply_sequences_with_tables(
    Num_sequences,
    Bitstream,
    Literals,
    Ll_table,
    Ll_log,
    Of_table,
    Of_log,
    Ml_table,
    Ml_log,
    Previous_output_rev,
    Reps
) ->
    case packkit@internal@fse:new_backward_reader(Bitstream) of
        {error, _} ->
            {error,
                {codec_invalid_data,
                    <<"zstd sequences bitstream is empty or missing marker"/utf8>>}};

        {ok, Reader} ->
            gleam@result:'try'(
                read_state_init(Reader, Ll_log, <<"literal_length"/utf8>>),
                fun(_use0) ->
                    {Ll_state, Reader@1} = _use0,
                    gleam@result:'try'(
                        read_state_init(Reader@1, Of_log, <<"offset"/utf8>>),
                        fun(_use0@1) ->
                            {Of_state, Reader@2} = _use0@1,
                            gleam@result:'try'(
                                read_state_init(
                                    Reader@2,
                                    Ml_log,
                                    <<"match_length"/utf8>>
                                ),
                                fun(_use0@2) ->
                                    {Ml_state, Reader@3} = _use0@2,
                                    Prev_size = erlang:length(
                                        Previous_output_rev
                                    ),
                                    {Rep0, Rep1, Rep2} = Reps,
                                    Ctx = {seq_context,
                                        Literals,
                                        0,
                                        Previous_output_rev,
                                        Prev_size,
                                        Rep0,
                                        Rep1,
                                        Rep2,
                                        Ll_state,
                                        Of_state,
                                        Ml_state,
                                        Ll_table,
                                        Of_table,
                                        Ml_table},
                                    gleam@result:'try'(
                                        decode_sequence_loop(
                                            Num_sequences,
                                            Ctx,
                                            Reader@3
                                        ),
                                        fun(Ctx@1) ->
                                            {ok,
                                                {append_remaining_literals(
                                                        Ctx@1
                                                    ),
                                                    {erlang:element(6, Ctx@1),
                                                        erlang:element(7, Ctx@1),
                                                        erlang:element(8, Ctx@1)}}}
                                        end
                                    )
                                end
                            )
                        end
                    )
                end
            )
    end.

-file("src/packkit/zstd.gleam", 4227).
-spec slice_or_error(bitstring(), integer(), integer(), binary()) -> {ok,
        bitstring()} |
    {error, packkit@error:codec_error()}.
slice_or_error(Bytes, Offset, Length, Label) ->
    case gleam_stdlib:bit_array_slice(Bytes, Offset, Length) of
        {ok, V} ->
            {ok, V};

        {error, _} ->
            {error, {codec_invalid_data, <<"truncated "/utf8, Label/binary>>}}
    end.

-file("src/packkit/zstd.gleam", 2982).
-spec decode_huffman_literals_block(bitstring(), compressed_literals_header()) -> {ok,
        {bitstring(),
            bitstring(),
            gleam@option:option(packkit@internal@huf:tree())}} |
    {error, packkit@error:codec_error()}.
decode_huffman_literals_block(Bytes, Header) ->
    Section_total = erlang:element(5, Header) + erlang:element(3, Header),
    gleam@result:'try'(
        slice_or_error(
            Bytes,
            0,
            Section_total,
            <<"zstd compressed literals section body"/utf8>>
        ),
        fun(Section) ->
            After_section@1 = case gleam_stdlib:bit_array_slice(
                Bytes,
                Section_total,
                erlang:byte_size(Bytes) - Section_total
            ) of
                {ok, After_section} -> After_section;
                _assert_fail ->
                    erlang:error(#{gleam_error => let_assert,
                                message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
                                file => <<?FILEPATH/utf8>>,
                                module => <<"packkit/zstd"/utf8>>,
                                function => <<"decode_huffman_literals_block"/utf8>>,
                                line => 2995,
                                value => _assert_fail,
                                start => 92763,
                                'end' => 92904,
                                pattern_start => 92774,
                                pattern_end => 92791})
            end,
            Tree_bytes@1 = case gleam_stdlib:bit_array_slice(
                Section,
                erlang:element(5, Header),
                Section_total - erlang:element(5, Header)
            ) of
                {ok, Tree_bytes} -> Tree_bytes;
                _assert_fail@1 ->
                    erlang:error(#{gleam_error => let_assert,
                                message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
                                file => <<?FILEPATH/utf8>>,
                                module => <<"packkit/zstd"/utf8>>,
                                function => <<"decode_huffman_literals_block"/utf8>>,
                                line => 3002,
                                value => _assert_fail@1,
                                start => 92908,
                                'end' => 93047,
                                pattern_start => 92919,
                                pattern_end => 92933})
            end,
            case packkit@internal@huf:read_tree(Tree_bytes@1) of
                {error, Reason} ->
                    {error, huf_error_to_codec(Reason)};

                {ok, {Tree, Tree_consumed}} ->
                    Bitstream_size = erlang:element(3, Header) - Tree_consumed,
                    gleam@result:'try'(
                        slice_or_error(
                            Section,
                            erlang:element(5, Header) + Tree_consumed,
                            Bitstream_size,
                            <<"zstd Huffman literal bitstream"/utf8>>
                        ),
                        fun(Bitstream_bytes) ->
                            gleam@result:'try'(
                                decode_huffman_streams(
                                    Tree,
                                    Bitstream_bytes,
                                    Header
                                ),
                                fun(Literals) ->
                                    {ok,
                                        {Literals,
                                            After_section@1,
                                            {some, Tree}}}
                                end
                            )
                        end
                    )
            end
        end
    ).

-file("src/packkit/zstd.gleam", 3028).
-spec decode_treeless_literals_block(
    bitstring(),
    compressed_literals_header(),
    gleam@option:option(packkit@internal@huf:tree())
) -> {ok,
        {bitstring(),
            bitstring(),
            gleam@option:option(packkit@internal@huf:tree())}} |
    {error, packkit@error:codec_error()}.
decode_treeless_literals_block(Bytes, Header, Prev_tree) ->
    case Prev_tree of
        none ->
            {error,
                {codec_invalid_data,
                    <<"zstd treeless literals without a prior Huffman tree"/utf8>>}};

        {some, Tree} ->
            Section_total = erlang:element(5, Header) + erlang:element(
                3,
                Header
            ),
            gleam@result:'try'(
                slice_or_error(
                    Bytes,
                    0,
                    Section_total,
                    <<"zstd treeless literals section body"/utf8>>
                ),
                fun(Section) ->
                    After_section@1 = case gleam_stdlib:bit_array_slice(
                        Bytes,
                        Section_total,
                        erlang:byte_size(Bytes) - Section_total
                    ) of
                        {ok, After_section} -> After_section;
                        _assert_fail ->
                            erlang:error(#{gleam_error => let_assert,
                                        message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
                                        file => <<?FILEPATH/utf8>>,
                                        module => <<"packkit/zstd"/utf8>>,
                                        function => <<"decode_treeless_literals_block"/utf8>>,
                                        line => 3046,
                                        value => _assert_fail,
                                        start => 94208,
                                        'end' => 94369,
                                        pattern_start => 94219,
                                        pattern_end => 94236})
                    end,
                    gleam@result:'try'(
                        slice_or_error(
                            Section,
                            erlang:element(5, Header),
                            erlang:element(3, Header),
                            <<"zstd treeless literal bitstream"/utf8>>
                        ),
                        fun(Bitstream_bytes) ->
                            gleam@result:'try'(
                                decode_huffman_streams(
                                    Tree,
                                    Bitstream_bytes,
                                    Header
                                ),
                                fun(Literals) ->
                                    {ok, {Literals, After_section@1, Prev_tree}}
                                end
                            )
                        end
                    )
                end
            )
    end.

-file("src/packkit/zstd.gleam", 2964).
-spec parse_compressed_literals(
    bitstring(),
    integer(),
    integer(),
    boolean(),
    gleam@option:option(packkit@internal@huf:tree())
) -> {ok,
        {bitstring(),
            bitstring(),
            gleam@option:option(packkit@internal@huf:tree())}} |
    {error, packkit@error:codec_error()}.
parse_compressed_literals(Bytes, Header_byte, Size_format, Treeless, Prev_tree) ->
    gleam@result:'try'(
        parse_compressed_literals_header(Bytes, Header_byte, Size_format),
        fun(Header) -> case Treeless of
                true ->
                    decode_treeless_literals_block(Bytes, Header, Prev_tree);

                false ->
                    decode_huffman_literals_block(Bytes, Header)
            end end
    ).

-file("src/packkit/zstd.gleam", 3280).
-spec finalize_literals(bitstring(), integer(), boolean()) -> {ok,
        {bitstring(), bitstring()}} |
    {error, packkit@error:codec_error()}.
finalize_literals(Bytes, Size, Is_rle) ->
    case Is_rle of
        true ->
            case Bytes of
                <<Byte, Rest/binary>> ->
                    {ok, {zstd_repeat_byte(Byte, Size, <<>>), Rest}};

                _ ->
                    {error,
                        {codec_invalid_data,
                            <<"truncated zstd RLE literals"/utf8>>}}
            end;

        false ->
            gleam@result:'try'(
                slice_or_error(
                    Bytes,
                    0,
                    Size,
                    <<"zstd raw literals body"/utf8>>
                ),
                fun(Chunk) ->
                    Rest@2 = case gleam_stdlib:bit_array_slice(
                        Bytes,
                        Size,
                        erlang:byte_size(Bytes) - Size
                    ) of
                        {ok, Rest@1} -> Rest@1;
                        _assert_fail ->
                            erlang:error(#{gleam_error => let_assert,
                                        message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
                                        file => <<?FILEPATH/utf8>>,
                                        module => <<"packkit/zstd"/utf8>>,
                                        function => <<"finalize_literals"/utf8>>,
                                        line => 3299,
                                        value => _assert_fail,
                                        start => 102339,
                                        'end' => 102432,
                                        pattern_start => 102350,
                                        pattern_end => 102358})
                    end,
                    {ok, {Chunk, Rest@2}}
                end
            )
    end.

-file("src/packkit/zstd.gleam", 3221).
-spec parse_raw_or_rle_literals(bitstring(), integer(), integer(), boolean()) -> {ok,
        {bitstring(), bitstring()}} |
    {error, packkit@error:codec_error()}.
parse_raw_or_rle_literals(Bytes, Header_byte, Size_format, Is_rle) ->
    case Size_format of
        0 ->
            Regenerated_size = erlang:'bsr'(Header_byte, 3),
            After_header@1 = case gleam_stdlib:bit_array_slice(
                Bytes,
                1,
                erlang:byte_size(Bytes) - 1
            ) of
                {ok, After_header} -> After_header;
                _assert_fail ->
                    erlang:error(#{gleam_error => let_assert,
                                message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
                                file => <<?FILEPATH/utf8>>,
                                module => <<"packkit/zstd"/utf8>>,
                                function => <<"parse_raw_or_rle_literals"/utf8>>,
                                line => 3231,
                                value => _assert_fail,
                                start => 100228,
                                'end' => 100323,
                                pattern_start => 100239,
                                pattern_end => 100255})
            end,
            finalize_literals(After_header@1, Regenerated_size, Is_rle);

        2 ->
            Regenerated_size = erlang:'bsr'(Header_byte, 3),
            After_header@1 = case gleam_stdlib:bit_array_slice(
                Bytes,
                1,
                erlang:byte_size(Bytes) - 1
            ) of
                {ok, After_header} -> After_header;
                _assert_fail ->
                    erlang:error(#{gleam_error => let_assert,
                                message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
                                file => <<?FILEPATH/utf8>>,
                                module => <<"packkit/zstd"/utf8>>,
                                function => <<"parse_raw_or_rle_literals"/utf8>>,
                                line => 3231,
                                value => _assert_fail,
                                start => 100228,
                                'end' => 100323,
                                pattern_start => 100239,
                                pattern_end => 100255})
            end,
            finalize_literals(After_header@1, Regenerated_size, Is_rle);

        1 ->
            case Bytes of
                <<_, B1, _/binary>> ->
                    Regenerated_size@1 = erlang:'bor'(
                        erlang:'bsr'(Header_byte, 4),
                        erlang:'bsl'(B1, 4)
                    ),
                    After_header@3 = case gleam_stdlib:bit_array_slice(
                        Bytes,
                        2,
                        erlang:byte_size(Bytes) - 2
                    ) of
                        {ok, After_header@2} -> After_header@2;
                        _assert_fail@1 ->
                            erlang:error(#{gleam_error => let_assert,
                                        message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
                                        file => <<?FILEPATH/utf8>>,
                                        module => <<"packkit/zstd"/utf8>>,
                                        function => <<"parse_raw_or_rle_literals"/utf8>>,
                                        line => 3244,
                                        value => _assert_fail@1,
                                        start => 100716,
                                        'end' => 100815,
                                        pattern_start => 100727,
                                        pattern_end => 100743})
                    end,
                    finalize_literals(
                        After_header@3,
                        Regenerated_size@1,
                        Is_rle
                    );

                _ ->
                    {error,
                        {codec_invalid_data,
                            <<"truncated zstd literals 2-byte header"/utf8>>}}
            end;

        _ ->
            case Bytes of
                <<_, B1@1, B2, _/binary>> ->
                    Regenerated_size@2 = erlang:'bor'(
                        erlang:'bsr'(Header_byte, 4),
                        erlang:'bor'(
                            erlang:'bsl'(B1@1, 4),
                            erlang:'bsl'(B2, 12)
                        )
                    ),
                    After_header@5 = case gleam_stdlib:bit_array_slice(
                        Bytes,
                        3,
                        erlang:byte_size(Bytes) - 3
                    ) of
                        {ok, After_header@4} -> After_header@4;
                        _assert_fail@2 ->
                            erlang:error(#{gleam_error => let_assert,
                                        message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
                                        file => <<?FILEPATH/utf8>>,
                                        module => <<"packkit/zstd"/utf8>>,
                                        function => <<"parse_raw_or_rle_literals"/utf8>>,
                                        line => 3267,
                                        value => _assert_fail@2,
                                        start => 101509,
                                        'end' => 101608,
                                        pattern_start => 101520,
                                        pattern_end => 101536})
                    end,
                    finalize_literals(
                        After_header@5,
                        Regenerated_size@2,
                        Is_rle
                    );

                _ ->
                    {error,
                        {codec_invalid_data,
                            <<"truncated zstd literals 3-byte header"/utf8>>}}
            end
    end.

-file("src/packkit/zstd.gleam", 2908).
-spec parse_literals_section(
    bitstring(),
    gleam@option:option(packkit@internal@huf:tree())
) -> {ok,
        {bitstring(),
            bitstring(),
            gleam@option:option(packkit@internal@huf:tree())}} |
    {error, packkit@error:codec_error()}.
parse_literals_section(Bytes, Prev_tree) ->
    case Bytes of
        <<Header_byte, _/binary>> ->
            Literals_block_type = erlang:'band'(Header_byte, 16#3),
            Size_format = erlang:'band'(erlang:'bsr'(Header_byte, 2), 16#3),
            case Literals_block_type of
                0 ->
                    _pipe = parse_raw_or_rle_literals(
                        Bytes,
                        Header_byte,
                        Size_format,
                        false
                    ),
                    gleam@result:map(
                        _pipe,
                        fun(Pair) ->
                            {erlang:element(1, Pair),
                                erlang:element(2, Pair),
                                Prev_tree}
                        end
                    );

                1 ->
                    _pipe@1 = parse_raw_or_rle_literals(
                        Bytes,
                        Header_byte,
                        Size_format,
                        true
                    ),
                    gleam@result:map(
                        _pipe@1,
                        fun(Pair@1) ->
                            {erlang:element(1, Pair@1),
                                erlang:element(2, Pair@1),
                                Prev_tree}
                        end
                    );

                2 ->
                    parse_compressed_literals(
                        Bytes,
                        Header_byte,
                        Size_format,
                        false,
                        Prev_tree
                    );

                _ ->
                    parse_compressed_literals(
                        Bytes,
                        Header_byte,
                        Size_format,
                        true,
                        Prev_tree
                    )
            end;

        _ ->
            {error,
                {codec_invalid_data, <<"truncated zstd literals header"/utf8>>}}
    end.

-file("src/packkit/zstd.gleam", 4239).
-spec slice_after(bitstring(), integer(), binary()) -> {ok, bitstring()} |
    {error, packkit@error:codec_error()}.
slice_after(Bytes, Offset, Label) ->
    case gleam_stdlib:bit_array_slice(
        Bytes,
        Offset,
        erlang:byte_size(Bytes) - Offset
    ) of
        {ok, V} ->
            {ok, V};

        {error, _} ->
            {error, {codec_invalid_data, <<"truncated "/utf8, Label/binary>>}}
    end.

-file("src/packkit/zstd.gleam", 3364).
-spec parse_sequences(
    bitstring(),
    integer(),
    integer(),
    bitstring(),
    seq_tables_state(),
    list(integer()),
    {integer(), integer(), integer()}
) -> {ok, {bitstring(), seq_tables_state(), {integer(), integer(), integer()}}} |
    {error, packkit@error:codec_error()}.
parse_sequences(
    Bytes,
    Count_size,
    Num_sequences,
    Literals,
    Prev_tables,
    Previous_output_rev,
    Reps
) ->
    gleam@result:'try'(
        slice_after(Bytes, Count_size, <<"zstd sequences count"/utf8>>),
        fun(After_count) -> case After_count of
                <<Modes, _/binary>> ->
                    Literal_lengths_mode = erlang:'band'(
                        erlang:'bsr'(Modes, 6),
                        16#3
                    ),
                    Offsets_mode = erlang:'band'(erlang:'bsr'(Modes, 4), 16#3),
                    Match_lengths_mode = erlang:'band'(
                        erlang:'bsr'(Modes, 2),
                        16#3
                    ),
                    Reserved = erlang:'band'(Modes, 16#3),
                    gleam@bool:guard(
                        Reserved /= 0,
                        {error,
                            {codec_invalid_data,
                                <<"zstd sequences mode byte has reserved bits set"/utf8>>}},
                        fun() ->
                            gleam@result:'try'(
                                slice_after(
                                    After_count,
                                    1,
                                    <<"zstd sequences mode byte"/utf8>>
                                ),
                                fun(After_modes) ->
                                    gleam@result:'try'(
                                        load_sequence_table(
                                            After_modes,
                                            Literal_lengths_mode,
                                            seq_alphabet_ll,
                                            erlang:element(2, Prev_tables)
                                        ),
                                        fun(_use0) ->
                                            {Ll_table, Ll_log, After_ll} = _use0,
                                            gleam@result:'try'(
                                                load_sequence_table(
                                                    After_ll,
                                                    Offsets_mode,
                                                    seq_alphabet_of,
                                                    erlang:element(
                                                        3,
                                                        Prev_tables
                                                    )
                                                ),
                                                fun(_use0@1) ->
                                                    {Of_table, Of_log, After_of} = _use0@1,
                                                    gleam@result:'try'(
                                                        load_sequence_table(
                                                            After_of,
                                                            Match_lengths_mode,
                                                            seq_alphabet_ml,
                                                            erlang:element(
                                                                4,
                                                                Prev_tables
                                                            )
                                                        ),
                                                        fun(_use0@2) ->
                                                            {Ml_table,
                                                                Ml_log,
                                                                Bitstream} = _use0@2,
                                                            gleam@result:'try'(
                                                                apply_sequences_with_tables(
                                                                    Num_sequences,
                                                                    Bitstream,
                                                                    Literals,
                                                                    Ll_table,
                                                                    Ll_log,
                                                                    Of_table,
                                                                    Of_log,
                                                                    Ml_table,
                                                                    Ml_log,
                                                                    Previous_output_rev,
                                                                    Reps
                                                                ),
                                                                fun(_use0@3) ->
                                                                    {Plain,
                                                                        New_reps} = _use0@3,
                                                                    {ok,
                                                                        {Plain,
                                                                            {seq_tables_state,
                                                                                {some,
                                                                                    {Ll_table,
                                                                                        Ll_log}},
                                                                                {some,
                                                                                    {Of_table,
                                                                                        Of_log}},
                                                                                {some,
                                                                                    {Ml_table,
                                                                                        Ml_log}}},
                                                                            New_reps}}
                                                                end
                                                            )
                                                        end
                                                    )
                                                end
                                            )
                                        end
                                    )
                                end
                            )
                        end
                    );

                _ ->
                    {error,
                        {codec_invalid_data,
                            <<"truncated zstd sequences modes byte"/utf8>>}}
            end end
    ).

-file("src/packkit/zstd.gleam", 3315).
-spec parse_and_apply_sequences(
    bitstring(),
    bitstring(),
    seq_tables_state(),
    list(integer()),
    {integer(), integer(), integer()}
) -> {ok, {bitstring(), seq_tables_state(), {integer(), integer(), integer()}}} |
    {error, packkit@error:codec_error()}.
parse_and_apply_sequences(
    Bytes,
    Literals,
    Prev_tables,
    Previous_output_rev,
    Reps
) ->
    case Bytes of
        <<>> ->
            {ok, {Literals, Prev_tables, Reps}};

        <<Num_byte, _/binary>> when Num_byte =:= 0 ->
            {ok, {Literals, Prev_tables, Reps}};

        <<Num_byte@1, _/binary>> when Num_byte@1 < 128 ->
            parse_sequences(
                Bytes,
                1,
                Num_byte@1,
                Literals,
                Prev_tables,
                Previous_output_rev,
                Reps
            );

        <<Num_byte@2, B1, _/binary>> when Num_byte@2 < 255 ->
            N = ((Num_byte@2 - 128) * 256) + B1,
            parse_sequences(
                Bytes,
                2,
                N,
                Literals,
                Prev_tables,
                Previous_output_rev,
                Reps
            );

        <<255, B1@1, B2, _/binary>> ->
            N@1 = (B1@1 + (B2 * 256)) + 16#7F00,
            parse_sequences(
                Bytes,
                3,
                N@1,
                Literals,
                Prev_tables,
                Previous_output_rev,
                Reps
            );

        _ ->
            {error,
                {codec_invalid_data, <<"truncated zstd sequences header"/utf8>>}}
    end.

-file("src/packkit/zstd.gleam", 2868).
-spec decode_compressed_block(bitstring(), integer(), block_state()) -> {ok,
        {bitstring(), bitstring(), block_state()}} |
    {error, packkit@error:codec_error()}.
decode_compressed_block(Bytes, Block_size, State) ->
    gleam@result:'try'(
        slice_or_error(
            Bytes,
            0,
            Block_size,
            <<"zstd compressed block payload"/utf8>>
        ),
        fun(Payload) ->
            Rest@1 = case gleam_stdlib:bit_array_slice(
                Bytes,
                Block_size,
                erlang:byte_size(Bytes) - Block_size
            ) of
                {ok, Rest} -> Rest;
                _assert_fail ->
                    erlang:error(#{gleam_error => let_assert,
                                message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
                                file => <<?FILEPATH/utf8>>,
                                module => <<"packkit/zstd"/utf8>>,
                                function => <<"decode_compressed_block"/utf8>>,
                                line => 2879,
                                value => _assert_fail,
                                start => 89271,
                                'end' => 89372,
                                pattern_start => 89282,
                                pattern_end => 89290})
            end,
            gleam@result:'try'(
                parse_literals_section(Payload, erlang:element(2, State)),
                fun(_use0) ->
                    {Literals, After_literals, Next_huffman} = _use0,
                    gleam@result:'try'(
                        parse_and_apply_sequences(
                            After_literals,
                            Literals,
                            erlang:element(3, State),
                            erlang:element(4, State),
                            erlang:element(5, State)
                        ),
                        fun(_use0@1) ->
                            {Plain, Next_sequences, Next_reps} = _use0@1,
                            {ok,
                                {Plain,
                                    Rest@1,
                                    {block_state,
                                        Next_huffman,
                                        Next_sequences,
                                        prepend_bytes(
                                            Plain,
                                            erlang:element(4, State)
                                        ),
                                        Next_reps}}}
                        end
                    )
                end
            )
        end
    ).

-file("src/packkit/zstd.gleam", 4250).
-spec decode_raw_block(bitstring(), integer()) -> {ok,
        {bitstring(), bitstring()}} |
    {error, packkit@error:codec_error()}.
decode_raw_block(Bytes, Block_size) ->
    case gleam_stdlib:bit_array_slice(Bytes, 0, Block_size) of
        {ok, Chunk} ->
            case gleam_stdlib:bit_array_slice(
                Bytes,
                Block_size,
                erlang:byte_size(Bytes) - Block_size
            ) of
                {ok, Rest} ->
                    {ok, {Chunk, Rest}};

                {error, _} ->
                    {error,
                        {codec_invalid_data,
                            <<"truncated zstd raw block tail"/utf8>>}}
            end;

        {error, _} ->
            {error, {codec_invalid_data, <<"truncated zstd raw block"/utf8>>}}
    end.

-file("src/packkit/zstd.gleam", 4282).
-spec repeat_byte(integer(), integer(), bitstring()) -> bitstring().
repeat_byte(Byte, Count, Acc) ->
    case Count of
        0 ->
            Acc;

        _ ->
            repeat_byte(Byte, Count - 1, <<Acc/bitstring, Byte>>)
    end.

-file("src/packkit/zstd.gleam", 4272).
-spec decode_rle_block(bitstring(), integer()) -> {ok,
        {bitstring(), bitstring()}} |
    {error, packkit@error:codec_error()}.
decode_rle_block(Bytes, Block_size) ->
    case Bytes of
        <<Byte, Rest/binary>> ->
            {ok, {repeat_byte(Byte, Block_size, <<>>), Rest}};

        _ ->
            {error, {codec_invalid_data, <<"truncated zstd RLE block"/utf8>>}}
    end.

-file("src/packkit/zstd.gleam", 2833).
-spec decode_one_block(bitstring(), integer(), integer(), block_state()) -> {ok,
        {bitstring(), bitstring(), block_state()}} |
    {error, packkit@error:codec_error()}.
decode_one_block(Bytes, Block_type, Block_size, State) ->
    case Block_type of
        0 ->
            _pipe = decode_raw_block(Bytes, Block_size),
            gleam@result:map(
                _pipe,
                fun(Pair) ->
                    {Plain, Rest} = Pair,
                    {Plain, Rest, append_block_output(State, Plain)}
                end
            );

        1 ->
            _pipe@1 = decode_rle_block(Bytes, Block_size),
            gleam@result:map(
                _pipe@1,
                fun(Pair@1) ->
                    {Plain@1, Rest@1} = Pair@1,
                    {Plain@1, Rest@1, append_block_output(State, Plain@1)}
                end
            );

        2 ->
            decode_compressed_block(Bytes, Block_size, State);

        _ ->
            {error, {codec_invalid_data, <<"zstd reserved block type 3"/utf8>>}}
    end.

-file("src/packkit/zstd.gleam", 4291).
-spec drop_bytes(bitstring(), integer(), binary()) -> {ok, bitstring()} |
    {error, packkit@error:codec_error()}.
drop_bytes(Bytes, Count, Label) ->
    case Count of
        0 ->
            {ok, Bytes};

        _ ->
            case gleam_stdlib:bit_array_slice(
                Bytes,
                Count,
                erlang:byte_size(Bytes) - Count
            ) of
                {ok, Rest} ->
                    {ok, Rest};

                {error, _} ->
                    {error,
                        {codec_invalid_data,
                            <<"truncated "/utf8, Label/binary>>}}
            end
    end.

-file("src/packkit/zstd.gleam", 2729).
-spec skip_dictionary_id(bitstring(), integer()) -> {ok, bitstring()} |
    {error, packkit@error:codec_error()}.
skip_dictionary_id(Bytes, Flag) ->
    Size = case Flag of
        0 ->
            0;

        1 ->
            1;

        2 ->
            2;

        3 ->
            4;

        _ ->
            0
    end,
    drop_bytes(Bytes, Size, <<"zstd dictionary id"/utf8>>).

-file("src/packkit/zstd.gleam", 2743).
-spec skip_frame_content_size(bitstring(), integer(), boolean()) -> {ok,
        bitstring()} |
    {error, packkit@error:codec_error()}.
skip_frame_content_size(Bytes, Flag, Single_segment) ->
    Size = case Flag of
        0 ->
            case Single_segment of
                true ->
                    1;

                false ->
                    0
            end;

        1 ->
            2;

        2 ->
            4;

        3 ->
            8;

        _ ->
            0
    end,
    drop_bytes(Bytes, Size, <<"zstd frame content size"/utf8>>).

-file("src/packkit/zstd.gleam", 2689).
-spec parse_frame_descriptor(bitstring()) -> {ok, {boolean(), bitstring()}} |
    {error, packkit@error:codec_error()}.
parse_frame_descriptor(Bytes) ->
    case Bytes of
        <<Descriptor, Rest/binary>> ->
            Fcs_flag = erlang:'bsr'(Descriptor, 6),
            Single_segment = erlang:'band'(Descriptor, 16#20) /= 0,
            Reserved_bit = erlang:'band'(Descriptor, 16#08) /= 0,
            Checksum_flag = erlang:'band'(Descriptor, 16#04) /= 0,
            Dict_id_flag = erlang:'band'(Descriptor, 16#03),
            gleam@bool:guard(
                Reserved_bit,
                {error,
                    {codec_invalid_data,
                        <<"zstd reserved descriptor bit must be zero"/utf8>>}},
                fun() -> gleam@result:'try'(case Single_segment of
                            true ->
                                {ok, Rest};

                            false ->
                                skip_window_descriptor(Rest)
                        end, fun(Rest@1) ->
                            gleam@result:'try'(
                                skip_dictionary_id(Rest@1, Dict_id_flag),
                                fun(Rest@2) ->
                                    gleam@result:'try'(
                                        skip_frame_content_size(
                                            Rest@2,
                                            Fcs_flag,
                                            Single_segment
                                        ),
                                        fun(Rest@3) ->
                                            {ok, {Checksum_flag, Rest@3}}
                                        end
                                    )
                                end
                            )
                        end) end
            );

        _ ->
            {error,
                {codec_invalid_data, <<"truncated zstd frame header"/utf8>>}}
    end.

-file("src/packkit/zstd.gleam", 4307).
-spec append_with_limit(bitstring(), bitstring(), packkit@limit:limits()) -> {ok,
        bitstring()} |
    {error, packkit@error:codec_error()}.
append_with_limit(Output, Chunk, Limits) ->
    Projected = erlang:byte_size(Output) + erlang:byte_size(Chunk),
    case Projected > packkit@limit:max_output_bytes(Limits) of
        true ->
            {error,
                {codec_limit_exceeded, <<"max_output_bytes"/utf8>>, Projected}};

        false ->
            {ok, gleam_stdlib:bit_array_concat([Output, Chunk])}
    end.

-file("src/packkit/zstd.gleam", 2798).
-spec decode_blocks(
    bitstring(),
    bitstring(),
    packkit@limit:limits(),
    block_state()
) -> {ok, {bitstring(), bitstring()}} | {error, packkit@error:codec_error()}.
decode_blocks(Bytes, Output, Limits, State) ->
    case Bytes of
        <<B0, B1, B2, Rest/binary>> ->
            Header = erlang:'bor'(
                B0,
                erlang:'bor'(erlang:'bsl'(B1, 8), erlang:'bsl'(B2, 16))
            ),
            Last = erlang:'band'(Header, 16#1) =:= 1,
            Block_type = erlang:'band'(erlang:'bsr'(Header, 1), 16#3),
            Block_size = erlang:'bsr'(Header, 3),
            gleam@result:'try'(
                decode_one_block(Rest, Block_type, Block_size, State),
                fun(_use0) ->
                    {Plain, Rest@1, Next_state} = _use0,
                    gleam@result:'try'(
                        append_with_limit(Output, Plain, Limits),
                        fun(New_output) -> case Last of
                                true ->
                                    {ok, {New_output, Rest@1}};

                                false ->
                                    decode_blocks(
                                        Rest@1,
                                        New_output,
                                        Limits,
                                        Next_state
                                    )
                            end end
                    )
                end
            );

        _ ->
            {error,
                {codec_invalid_data, <<"truncated zstd block header"/utf8>>}}
    end.

-file("src/packkit/zstd.gleam", 2679).
-spec parse_frame_header(bitstring()) -> {ok, {boolean(), bitstring()}} |
    {error, packkit@error:codec_error()}.
parse_frame_header(Bytes) ->
    case Bytes of
        <<M:32/little-unsigned, Rest/binary>> when M =:= 16#FD2FB528 ->
            parse_frame_descriptor(Rest);

        _ ->
            {error, {codec_invalid_data, <<"missing zstd frame magic"/utf8>>}}
    end.

-file("src/packkit/zstd.gleam", 1027).
-spec encode_fse_dist_header(list(integer()), integer()) -> bitstring().
encode_fse_dist_header(Normalized, Max_used) ->
    encode_fse_dist_header_with_log(Normalized, Max_used, 6).

-file("src/packkit/zstd.gleam", 935).
-spec build_floor_normalized(
    gleam@dict:dict(integer(), integer()),
    integer(),
    integer(),
    integer(),
    list(integer())
) -> list(integer()).
build_floor_normalized(Counts, Total, Sym, Max_used, Acc) ->
    case Sym > Max_used of
        true ->
            lists:reverse(Acc);

        false ->
            Count = case gleam_stdlib:map_get(Counts, Sym) of
                {ok, V} ->
                    V;

                {error, _} ->
                    0
            end,
            Normalized = case Count of
                0 ->
                    0;

                _ ->
                    Scaled = case Total of
                        0 -> 0;
                        Gleam@denominator -> Count * 64 div Gleam@denominator
                    end,
                    case Scaled of
                        0 ->
                            1;

                        V@1 ->
                            V@1
                    end
            end,
            build_floor_normalized(
                Counts,
                Total,
                Sym + 1,
                Max_used,
                [Normalized | Acc]
            )
    end.

-file("src/packkit/zstd.gleam", 910).
-spec normalize_fse_weight_counts(
    gleam@dict:dict(integer(), integer()),
    integer(),
    integer()
) -> {ok, list(integer())} | {error, nil}.
normalize_fse_weight_counts(Counts, Total, Max_used) ->
    case Total of
        0 ->
            {error, nil};

        _ ->
            Raw = build_floor_normalized(Counts, Total, 0, Max_used, []),
            Sum = sum_int_list(Raw, 0),
            Diff = 64 - Sum,
            case Diff of
                0 ->
                    {ok, Raw};

                _ ->
                    Idx = find_largest_count_index(Counts, Max_used),
                    case Idx < 0 of
                        true ->
                            {error, nil};

                        false ->
                            {ok, adjust_normalized_at(Raw, Idx, Diff, 0, [])}
                    end
            end
    end.

-file("src/packkit/zstd.gleam", 1247).
-spec build_fse_enc_slots(
    gleam@dict:dict(integer(), packkit@internal@fse:state_entry())
) -> gleam@dict:dict(integer(), list(fse_enc_slot())).
build_fse_enc_slots(State_table) ->
    build_fse_enc_slots_loop(State_table, 0, 64, maps:new()).

-file("src/packkit/zstd.gleam", 1288).
-spec smallest_state_for_symbol(
    gleam@dict:dict(integer(), list(fse_enc_slot())),
    integer()
) -> {ok, integer()} | {error, nil}.
smallest_state_for_symbol(Slots, Symbol) ->
    case gleam_stdlib:map_get(Slots, Symbol) of
        {error, _} ->
            {error, nil};

        {ok, []} ->
            {error, nil};

        {ok, List} ->
            {ok, smallest_state_idx_loop(List, 64)}
    end.

-file("src/packkit/zstd.gleam", 1335).
-spec encode_fse_weight_bitstream(
    list(integer()),
    gleam@dict:dict(integer(), packkit@internal@fse:state_entry())
) -> bitstring().
encode_fse_weight_bitstream(Weights, State_table) ->
    N = erlang:length(Weights),
    Slots = build_fse_enc_slots(State_table),
    Weights_dict = list_to_indexed_dict(Weights, 0, maps:new()),
    {Target_a_sym, Target_b_sym} = case erlang:'band'(N, 1) of
        0 ->
            {dict_index_or_zero(Weights_dict, N - 2),
                dict_index_or_zero(Weights_dict, N - 1)};

        _ ->
            {dict_index_or_zero(Weights_dict, N - 1),
                dict_index_or_zero(Weights_dict, N - 2)}
    end,
    State_a_init = case smallest_state_for_symbol(Slots, Target_a_sym) of
        {ok, S} ->
            S;

        {error, _} ->
            0
    end,
    State_b_init = case smallest_state_for_symbol(Slots, Target_b_sym) of
        {ok, S@1} ->
            S@1;

        {error, _} ->
            0
    end,
    {Buf, Bits, State_a, State_b, Out} = fse_encode_transitions(
        Weights_dict,
        N - 3,
        State_a_init,
        State_b_init,
        Slots,
        0,
        0,
        <<>>
    ),
    {Buf@1, Bits@1, Out@1} = push_bits_unchecked(Buf, Bits, Out, State_b, 6),
    {Buf@2, Bits@2, Out@2} = push_bits_unchecked(
        Buf@1,
        Bits@1,
        Out@1,
        State_a,
        6
    ),
    Buf2 = erlang:'bor'(Buf@2, erlang:'bsl'(1, Bits@2)),
    Bits2 = Bits@2 + 1,
    flush_final_bits(Buf2, Bits2, Out@2).

-file("src/packkit/zstd.gleam", 861).
-spec fse_encode_weight_stream(list(integer())) -> {ok, bitstring()} |
    {error, nil}.
fse_encode_weight_stream(Weights) ->
    Total = erlang:length(Weights),
    Counts = tally_fse_weights(Weights, maps:new()),
    Max_used = highest_used_fse_weight(Counts),
    case Max_used < 0 of
        true ->
            {error, nil};

        false ->
            case normalize_fse_weight_counts(Counts, Total, Max_used) of
                {error, _} ->
                    {error, nil};

                {ok, Normalized} ->
                    Header = encode_fse_dist_header(Normalized, Max_used),
                    State_table = packkit@internal@fse:build_state_table(
                        Normalized,
                        6
                    ),
                    Bitstream = encode_fse_weight_bitstream(
                        Weights,
                        State_table
                    ),
                    {ok, gleam_stdlib:bit_array_concat([Header, Bitstream])}
            end
    end.

-file("src/packkit/zstd.gleam", 844).
?DOC(
    " Try to serialize the Huffman tree as an FSE-compressed weight\n"
    " stream.  Returns `None` when the FSE body wouldn't fit the 127-byte\n"
    " cap imposed by the 1-byte tree-description header (so the chunk\n"
    " will fall back to Raw / RLE).\n"
).
-spec try_serialize_huffman_tree_fse(list(integer())) -> gleam@option:option(bitstring()).
try_serialize_huffman_tree_fse(Serialized) ->
    case erlang:length(Serialized) < 2 of
        true ->
            none;

        false ->
            case fse_encode_weight_stream(Serialized) of
                {error, _} ->
                    none;

                {ok, Body} ->
                    Body_size = erlang:byte_size(Body),
                    case (Body_size =:= 0) orelse (Body_size > 127) of
                        true ->
                            none;

                        false ->
                            {some, <<Body_size, Body/bitstring>>}
                    end
            end
    end.

-file("src/packkit/zstd.gleam", 1460).
?DOC(
    " Unified Huffman tree-description serializer.  Picks the direct-\n"
    " weight form when the alphabet fits (≤ 127 streamed weights) and\n"
    " otherwise falls back to the FSE-compressed form.  Returns `None`\n"
    " when neither form fits — the caller drops Huffman for the chunk\n"
    " and emits a Raw / RLE block instead.\n"
).
-spec serialize_huffman_tree_unified(list(integer())) -> gleam@option:option(bitstring()).
serialize_huffman_tree_unified(Lengths) ->
    Max_bits = max_length_in_list(Lengths, 0),
    Weights = gleam@list:map(Lengths, fun(L) -> case L of
                0 ->
                    0;

                _ ->
                    (Max_bits + 1) - L
            end end),
    Trimmed = trim_trailing_zero_weights(lists:reverse(Weights), []),
    Serialized = drop_last_weight(Trimmed, []),
    Num_serialized = erlang:length(Serialized),
    case Num_serialized =< 127 of
        true ->
            Header_byte = 127 + Num_serialized,
            Packed = pack_weights_4bit(Serialized, <<>>),
            {some, <<Header_byte, Packed/bitstring>>};

        false ->
            try_serialize_huffman_tree_fse(Serialized)
    end.

-file("src/packkit/zstd.gleam", 269).
?DOC(
    " Try to encode `chunk` as a Huffman-compressed literals block.\n"
    " Returns None when the chunk has fewer than two distinct bytes (a\n"
    " trivial RLE case), when the resulting code would exceed zstd's\n"
    " 11-bit tree-depth limit, or when the encoded form would not fit in\n"
    " the 10-bit compressed-size field of the 1-stream literals header.\n"
).
-spec try_huffman_block(bitstring(), integer(), boolean()) -> gleam@option:option(bitstring()).
try_huffman_block(Chunk, Chunk_size, Is_last) ->
    Freqs = count_byte_frequencies(Chunk),
    Distinct = erlang:length(
        gleam@list:filter(Freqs, fun(P) -> erlang:element(2, P) > 0 end)
    ),
    case Distinct < 2 of
        true ->
            none;

        false ->
            case build_canonical_lengths(Freqs) of
                {error, _} ->
                    none;

                {ok, {Lengths, Max_bits}} ->
                    case Max_bits > 11 of
                        true ->
                            none;

                        false ->
                            case serialize_huffman_tree_unified(Lengths) of
                                none ->
                                    none;

                                {some, Tree_bytes} ->
                                    Code_table = assign_canonical_codes(
                                        Lengths,
                                        Max_bits
                                    ),
                                    Bitstream = encode_huffman_bitstream(
                                        Chunk,
                                        Code_table
                                    ),
                                    Comp_size = erlang:byte_size(Tree_bytes) + erlang:byte_size(
                                        Bitstream
                                    ),
                                    case Comp_size >= 1024 of
                                        true ->
                                            none;

                                        false ->
                                            Literals_section = build_compressed_literals_section(
                                                Chunk_size,
                                                Comp_size,
                                                Tree_bytes,
                                                Bitstream
                                            ),
                                            Block_body = gleam_stdlib:bit_array_concat(
                                                [Literals_section, <<16#00>>]
                                            ),
                                            Block_body_size = erlang:byte_size(
                                                Block_body
                                            ),
                                            {some,
                                                gleam_stdlib:bit_array_concat(
                                                    [block_header(
                                                            Block_body_size,
                                                            2,
                                                            Is_last
                                                        ),
                                                        Block_body]
                                                )}
                                    end
                            end
                    end
            end
    end.

-file("src/packkit/zstd.gleam", 339).
?DOC(
    " Same as `try_huffman_block`, but uses the 4-stream form (literals\n"
    " header `size_format = 2`, 4-byte header, 14-bit regen / compressed\n"
    " fields, 6-byte jump table before the four sub-bitstreams).  Lets\n"
    " the encoder Huffman-code blocks above the 1-stream 1023-byte cap,\n"
    " up to 16 383 bytes per block.  Splits the chunk into four parts\n"
    " using zstd's `(N+3)/4, (N+2)/4, (N+1)/4, N/4` formula and runs the\n"
    " existing 1-stream bitstream encoder once per part with the shared\n"
    " Huffman code table.\n"
).
-spec try_huffman_block_4stream(bitstring(), integer(), boolean()) -> gleam@option:option(bitstring()).
try_huffman_block_4stream(Chunk, Chunk_size, Is_last) ->
    Freqs = count_byte_frequencies(Chunk),
    Distinct = erlang:length(
        gleam@list:filter(Freqs, fun(P) -> erlang:element(2, P) > 0 end)
    ),
    case Distinct < 2 of
        true ->
            none;

        false ->
            case build_canonical_lengths(Freqs) of
                {error, _} ->
                    none;

                {ok, {Lengths, Max_bits}} ->
                    case Max_bits > 11 of
                        true ->
                            none;

                        false ->
                            case serialize_huffman_tree_unified(Lengths) of
                                none ->
                                    none;

                                {some, Tree_bytes} ->
                                    Code_table = assign_canonical_codes(
                                        Lengths,
                                        Max_bits
                                    ),
                                    Parts = split_chunk_4(Chunk, Chunk_size),
                                    {P1, P2, P3, P4} = Parts,
                                    S1 = encode_huffman_bitstream(
                                        P1,
                                        Code_table
                                    ),
                                    S2 = encode_huffman_bitstream(
                                        P2,
                                        Code_table
                                    ),
                                    S3 = encode_huffman_bitstream(
                                        P3,
                                        Code_table
                                    ),
                                    S4 = encode_huffman_bitstream(
                                        P4,
                                        Code_table
                                    ),
                                    S1_size = erlang:byte_size(S1),
                                    S2_size = erlang:byte_size(S2),
                                    S3_size = erlang:byte_size(S3),
                                    S4_size = erlang:byte_size(S4),
                                    case ((S1_size > 16#FFFF) orelse (S2_size > 16#FFFF))
                                    orelse (S3_size > 16#FFFF) of
                                        true ->
                                            none;

                                        false ->
                                            Jump_table = <<S1_size:16/little,
                                                S2_size:16/little,
                                                S3_size:16/little>>,
                                            Comp_size = ((((erlang:byte_size(
                                                Tree_bytes
                                            )
                                            + 6)
                                            + S1_size)
                                            + S2_size)
                                            + S3_size)
                                            + S4_size,
                                            case Comp_size > 16383 of
                                                true ->
                                                    none;

                                                false ->
                                                    Literals_section = build_compressed_literals_section_4stream(
                                                        Chunk_size,
                                                        Comp_size,
                                                        Tree_bytes,
                                                        Jump_table,
                                                        S1,
                                                        S2,
                                                        S3,
                                                        S4
                                                    ),
                                                    Block_body = gleam_stdlib:bit_array_concat(
                                                        [Literals_section,
                                                            <<16#00>>]
                                                    ),
                                                    Block_body_size = erlang:byte_size(
                                                        Block_body
                                                    ),
                                                    {some,
                                                        gleam_stdlib:bit_array_concat(
                                                            [block_header(
                                                                    Block_body_size,
                                                                    2,
                                                                    Is_last
                                                                ),
                                                                Block_body]
                                                        )}
                                            end
                                    end
                            end
                    end
            end
    end.

-file("src/packkit/zstd.gleam", 2507).
?DOC(
    " Same Huffman 1-stream literals section the existing\n"
    " `try_huffman_block` builds — exposed here without the surrounding\n"
    " Sequences_Section so a sequences-encoding block can reuse it as\n"
    " just the literals portion.\n"
).
-spec build_huffman_literals_section_only(bitstring(), integer()) -> gleam@option:option(bitstring()).
build_huffman_literals_section_only(Chunk, Chunk_size) ->
    Freqs = count_byte_frequencies(Chunk),
    Distinct = erlang:length(
        gleam@list:filter(Freqs, fun(P) -> erlang:element(2, P) > 0 end)
    ),
    case Distinct < 2 of
        true ->
            none;

        false ->
            case build_canonical_lengths(Freqs) of
                {error, _} ->
                    none;

                {ok, {Lengths, Max_bits}} ->
                    case Max_bits > 11 of
                        true ->
                            none;

                        false ->
                            case serialize_huffman_tree_unified(Lengths) of
                                none ->
                                    none;

                                {some, Tree_bytes} ->
                                    Code_table = assign_canonical_codes(
                                        Lengths,
                                        Max_bits
                                    ),
                                    Bitstream = encode_huffman_bitstream(
                                        Chunk,
                                        Code_table
                                    ),
                                    Comp_size = erlang:byte_size(Tree_bytes) + erlang:byte_size(
                                        Bitstream
                                    ),
                                    case Comp_size >= 1024 of
                                        true ->
                                            none;

                                        false ->
                                            {some,
                                                build_compressed_literals_section(
                                                    Chunk_size,
                                                    Comp_size,
                                                    Tree_bytes,
                                                    Bitstream
                                                )}
                                    end
                            end
                    end
            end
    end.

-file("src/packkit/zstd.gleam", 2441).
-spec encode_literals_section_choice(bitstring(), integer()) -> bitstring().
encode_literals_section_choice(Literals, Literals_size) ->
    Raw_section = build_raw_literals_section(Literals, Literals_size),
    Rle_section = case {Literals_size >= 1, peek_uniform_byte(Literals)} of
        {true, {ok, Byte}} ->
            {some, build_rle_literals_section(Byte, Literals_size)};

        {_, _} ->
            none
    end,
    Candidates = case Rle_section of
        {some, R} ->
            [{erlang:byte_size(R), R},
                {erlang:byte_size(Raw_section), Raw_section}];

        none ->
            [{erlang:byte_size(Raw_section), Raw_section}]
    end,
    Huff = case (Literals_size >= 64) andalso (Literals_size =< 1023) of
        true ->
            build_huffman_literals_section_only(Literals, Literals_size);

        false ->
            none
    end,
    Candidates@1 = case Huff of
        {some, H} ->
            [{erlang:byte_size(H), H} | Candidates];

        none ->
            Candidates
    end,
    case Candidates@1 of
        [First | Rest] ->
            erlang:element(
                2,
                gleam@list:fold(
                    Rest,
                    First,
                    fun(Acc, Item) ->
                        case erlang:element(1, Item) < erlang:element(1, Acc) of
                            true ->
                                Item;

                            false ->
                                Acc
                        end
                    end
                )
            );

        [] ->
            Raw_section
    end.

-file("src/packkit/zstd.gleam", 1753).
-spec zstd_update_hashes_range(
    bitstring(),
    gleam@dict:dict(integer(), integer()),
    integer(),
    integer(),
    integer()
) -> gleam@dict:dict(integer(), integer()).
zstd_update_hashes_range(Bytes, Hashes, From, To, Size) ->
    case (From >= To) orelse ((From + 3) > Size) of
        true ->
            Hashes;

        false ->
            Key = zstd_hash3(
                zstd_byte_at(Bytes, From),
                zstd_byte_at(Bytes, From + 1),
                zstd_byte_at(Bytes, From + 2)
            ),
            zstd_update_hashes_range(
                Bytes,
                gleam@dict:insert(Hashes, Key, From),
                From + 1,
                To,
                Size
            )
    end.

-file("src/packkit/zstd.gleam", 1599).
-spec zstd_lz77_loop(
    bitstring(),
    integer(),
    integer(),
    integer(),
    gleam@dict:dict(integer(), integer()),
    list(zstd_sequence()),
    bitstring()
) -> {list(zstd_sequence()), bitstring(), integer()}.
zstd_lz77_loop(Bytes, Pos, Size, Last_emit, Hashes, Seqs_rev, Literals) ->
    case Pos >= Size of
        true ->
            Trailing = zstd_byte_slice(Bytes, Last_emit, Size - Last_emit),
            Final_literals = gleam_stdlib:bit_array_concat([Literals, Trailing]),
            {Seqs_rev, Final_literals, Pos};

        false ->
            case (Pos + 3) > Size of
                true ->
                    zstd_lz77_loop(
                        Bytes,
                        Pos + 1,
                        Size,
                        Last_emit,
                        Hashes,
                        Seqs_rev,
                        Literals
                    );

                false ->
                    B0 = zstd_byte_at(Bytes, Pos),
                    B1 = zstd_byte_at(Bytes, Pos + 1),
                    B2 = zstd_byte_at(Bytes, Pos + 2),
                    Key = zstd_hash3(B0, B1, B2),
                    case gleam_stdlib:map_get(Hashes, Key) of
                        {error, _} ->
                            zstd_lz77_loop(
                                Bytes,
                                Pos + 1,
                                Size,
                                Last_emit,
                                gleam@dict:insert(Hashes, Key, Pos),
                                Seqs_rev,
                                Literals
                            );

                        {ok, Prev} ->
                            Distance = Pos - Prev,
                            case (Distance =< 0) orelse (Distance > 16#8000) of
                                true ->
                                    zstd_lz77_loop(
                                        Bytes,
                                        Pos + 1,
                                        Size,
                                        Last_emit,
                                        gleam@dict:insert(Hashes, Key, Pos),
                                        Seqs_rev,
                                        Literals
                                    );

                                false ->
                                    Cap = case (Size - Pos) < 131074 of
                                        true ->
                                            Size - Pos;

                                        false ->
                                            131074
                                    end,
                                    M_len = zstd_match_len(
                                        Bytes,
                                        Prev,
                                        Pos,
                                        Cap,
                                        0
                                    ),
                                    case M_len >= 3 of
                                        true ->
                                            Lit_len = Pos - Last_emit,
                                            Lit_bytes = zstd_byte_slice(
                                                Bytes,
                                                Last_emit,
                                                Lit_len
                                            ),
                                            Seq = {zstd_sequence,
                                                Lit_len,
                                                M_len,
                                                Distance},
                                            Hashes@1 = zstd_update_hashes_range(
                                                Bytes,
                                                gleam@dict:insert(
                                                    Hashes,
                                                    Key,
                                                    Pos
                                                ),
                                                Pos + 1,
                                                Pos + M_len,
                                                Size
                                            ),
                                            zstd_lz77_loop(
                                                Bytes,
                                                Pos + M_len,
                                                Size,
                                                Pos + M_len,
                                                Hashes@1,
                                                [Seq | Seqs_rev],
                                                gleam_stdlib:bit_array_concat(
                                                    [Literals, Lit_bytes]
                                                )
                                            );

                                        false ->
                                            zstd_lz77_loop(
                                                Bytes,
                                                Pos + 1,
                                                Size,
                                                Last_emit,
                                                gleam@dict:insert(
                                                    Hashes,
                                                    Key,
                                                    Pos
                                                ),
                                                Seqs_rev,
                                                Literals
                                            )
                                    end
                            end
                    end
            end
    end.

-file("src/packkit/zstd.gleam", 1590).
?DOC(
    " Run a greedy LZ77 match finder over `chunk` and return the list of\n"
    " emitted sequences (in input order) plus the concatenated literal\n"
    " buffer (every byte not covered by a match).  Lengths and offsets\n"
    " are real values — converting them to the LL/OF/ML wire symbols is\n"
    " the next stage's job.\n"
).
-spec build_zstd_sequences(bitstring(), integer()) -> {list(zstd_sequence()),
    bitstring()}.
build_zstd_sequences(Chunk, Chunk_size) ->
    {Sequences_rev, Literals_acc, _} = zstd_lz77_loop(
        Chunk,
        0,
        Chunk_size,
        0,
        maps:new(),
        [],
        <<>>
    ),
    {lists:reverse(Sequences_rev), Literals_acc}.

-file("src/packkit/zstd.gleam", 2082).
?DOC(
    " Try to encode the sequence section using FSE_Compressed_Mode for\n"
    " LL/OF/ML.  Returns `None` when normalisation fails for any of the\n"
    " three alphabets — the caller falls back to Predefined_Mode.\n"
).
-spec build_seq_section_fse_compressed(
    bitstring(),
    list({integer(), integer(), integer(), integer(), integer(), integer()})
) -> gleam@option:option(bitstring()).
build_seq_section_fse_compressed(Count_bytes, Seq_codes) ->
    {Ll_counts, Of_counts, Ml_counts} = tally_seq_alphabets(
        Seq_codes,
        maps:new(),
        maps:new(),
        maps:new()
    ),
    Total = erlang:length(Seq_codes),
    case {prep_alphabet(Ll_counts, Total, 35, 9),
        prep_alphabet(Of_counts, Total, 31, 8),
        prep_alphabet(Ml_counts, Total, 52, 9)} of
        {{ok, {Ll_norm, _, Ll_log, Ll_desc}},
            {ok, {Of_norm, _, Of_log, Of_desc}},
            {ok, {Ml_norm, _, Ml_log, Ml_desc}}} ->
            Ll_table = packkit@internal@fse:build_state_table(Ll_norm, Ll_log),
            Of_table = packkit@internal@fse:build_state_table(Of_norm, Of_log),
            Ml_table = packkit@internal@fse:build_state_table(Ml_norm, Ml_log),
            Ll_slots = build_seq_enc_slots(Ll_table, erlang:'bsl'(1, Ll_log)),
            Of_slots = build_seq_enc_slots(Of_table, erlang:'bsl'(1, Of_log)),
            Ml_slots = build_seq_enc_slots(Ml_table, erlang:'bsl'(1, Ml_log)),
            Bitstream = encode_seq_fse_with_tables(
                Seq_codes,
                Ll_slots,
                Of_slots,
                Ml_slots,
                Ll_log,
                Of_log,
                Ml_log
            ),
            Mode_byte = <<16#A8>>,
            {some,
                gleam_stdlib:bit_array_concat(
                    [Count_bytes,
                        Mode_byte,
                        Ll_desc,
                        Of_desc,
                        Ml_desc,
                        Bitstream]
                )};

        {_, _, _} ->
            none
    end.

-file("src/packkit/zstd.gleam", 2383).
?DOC(
    " Try emitting `chunk` as a Compressed_Block with LZ77 sequences.\n"
    " Returns None when sequences would not improve over the literals-\n"
    " only (Huffman) path — i.e. when the match finder finds no matches\n"
    " or when the resulting block grows past `huffman_max_block_compressed`.\n"
).
-spec try_sequences_block(bitstring(), integer(), boolean()) -> gleam@option:option(bitstring()).
try_sequences_block(Chunk, Chunk_size, Is_last) ->
    {Sequences, Literals} = build_zstd_sequences(Chunk, Chunk_size),
    Num_sequences = erlang:length(Sequences),
    case Num_sequences of
        0 ->
            none;

        _ ->
            Literals_size = erlang:byte_size(Literals),
            Literals_section = encode_literals_section_choice(
                Literals,
                Literals_size
            ),
            Count_bytes = encode_sequences_count(Num_sequences),
            Seq_codes = compute_seq_codes(Sequences, {1, 4, 8}, []),
            Pre_section = build_seq_section_predefined(Count_bytes, Seq_codes),
            Sequence_section = case Num_sequences >= 32 of
                true ->
                    case build_seq_section_fse_compressed(
                        Count_bytes,
                        Seq_codes
                    ) of
                        {some, Fse_section} ->
                            case erlang:byte_size(Fse_section) < erlang:byte_size(
                                Pre_section
                            ) of
                                true ->
                                    Fse_section;

                                false ->
                                    Pre_section
                            end;

                        none ->
                            Pre_section
                    end;

                false ->
                    Pre_section
            end,
            Block_body = gleam_stdlib:bit_array_concat(
                [Literals_section, Sequence_section]
            ),
            Block_body_size = erlang:byte_size(Block_body),
            case Block_body_size >= erlang:'bsl'(1, 20) of
                true ->
                    none;

                false ->
                    {some,
                        gleam_stdlib:bit_array_concat(
                            [block_header(Block_body_size, 2, Is_last),
                                Block_body]
                        )}
            end
    end.

-file("src/packkit/zstd.gleam", 191).
?DOC(
    " Encode one ≤ 1 KiB chunk and return whichever block representation\n"
    " is the smallest: Raw, RLE (when the chunk is one repeating byte),\n"
    " or a Compressed_Block whose Literals_Section is Huffman-coded.\n"
    " The Sequences_Section always carries `Number_of_Sequences = 0` so\n"
    " literals ARE the output — no LZ77, no sequences.  Picking the\n"
    " smallest of the three keeps the encoder strictly non-regressing on\n"
    " uncompressible payloads.\n"
).
-spec pick_best_block(bitstring(), integer(), boolean()) -> bitstring().
pick_best_block(Chunk, Chunk_size, Is_last) ->
    Raw_block = gleam_stdlib:bit_array_concat(
        [block_header(Chunk_size, 0, Is_last), Chunk]
    ),
    Raw_size = erlang:byte_size(Raw_block),
    Rle_block = case {Chunk_size >= 2, peek_uniform_byte(Chunk)} of
        {true, {ok, Byte}} ->
            {some,
                gleam_stdlib:bit_array_concat(
                    [block_header(Chunk_size, 1, Is_last), <<Byte>>]
                )};

        {_, _} ->
            none
    end,
    Huff_block = case (Chunk_size >= 64) andalso (Chunk_size =< 1023) of
        true ->
            try_huffman_block(Chunk, Chunk_size, Is_last);

        false ->
            none
    end,
    Huff_4stream_block = case (Chunk_size > 1023) andalso (Chunk_size >= 4) of
        true ->
            try_huffman_block_4stream(Chunk, Chunk_size, Is_last);

        false ->
            none
    end,
    Seq_block = case Chunk_size >= 4 of
        true ->
            try_sequences_block(Chunk, Chunk_size, Is_last);

        false ->
            none
    end,
    Candidates = [{Raw_size, Raw_block} | case Rle_block of
            {some, Rle} ->
                [{erlang:byte_size(Rle), Rle}];

            none ->
                []
        end],
    Candidates@1 = case Huff_block of
        {some, H} ->
            [{erlang:byte_size(H), H} | Candidates];

        none ->
            Candidates
    end,
    Candidates@2 = case Huff_4stream_block of
        {some, H@1} ->
            [{erlang:byte_size(H@1), H@1} | Candidates@1];

        none ->
            Candidates@1
    end,
    Candidates@3 = case Seq_block of
        {some, S} ->
            [{erlang:byte_size(S), S} | Candidates@2];

        none ->
            Candidates@2
    end,
    pick_smallest_block(Candidates@3).

-file("src/packkit/zstd.gleam", 151).
-spec emit_raw_blocks_loop(bitstring(), integer(), bitstring()) -> bitstring().
emit_raw_blocks_loop(Remaining_bytes, Remaining_size, Acc) ->
    case Remaining_size of
        0 ->
            Acc;

        N ->
            Chunk_size = case N > 16383 of
                true ->
                    16383;

                false ->
                    N
            end,
            Is_last = Chunk_size =:= N,
            Chunk@1 = case gleam_stdlib:bit_array_slice(
                Remaining_bytes,
                0,
                Chunk_size
            ) of
                {ok, Chunk} -> Chunk;
                _assert_fail ->
                    erlang:error(#{gleam_error => let_assert,
                                message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
                                file => <<?FILEPATH/utf8>>,
                                module => <<"packkit/zstd"/utf8>>,
                                function => <<"emit_raw_blocks_loop"/utf8>>,
                                line => 167,
                                value => _assert_fail,
                                start => 6261,
                                'end' => 6331,
                                pattern_start => 6272,
                                pattern_end => 6281})
            end,
            Rest@1 = case gleam_stdlib:bit_array_slice(
                Remaining_bytes,
                Chunk_size,
                erlang:byte_size(Remaining_bytes) - Chunk_size
            ) of
                {ok, Rest} -> Rest;
                _assert_fail@1 ->
                    erlang:error(#{gleam_error => let_assert,
                                message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
                                file => <<?FILEPATH/utf8>>,
                                module => <<"packkit/zstd"/utf8>>,
                                function => <<"emit_raw_blocks_loop"/utf8>>,
                                line => 168,
                                value => _assert_fail@1,
                                start => 6338,
                                'end' => 6504,
                                pattern_start => 6349,
                                pattern_end => 6357})
            end,
            Chunk_block = pick_best_block(Chunk@1, Chunk_size, Is_last),
            emit_raw_blocks_loop(
                Rest@1,
                Remaining_size - Chunk_size,
                gleam_stdlib:bit_array_concat([Acc, Chunk_block])
            )
    end.

-file("src/packkit/zstd.gleam", 144).
-spec build_raw_blocks(bitstring(), integer()) -> bitstring().
build_raw_blocks(Bytes, Total) ->
    case Total of
        0 ->
            block_header(0, 0, true);

        _ ->
            emit_raw_blocks_loop(Bytes, Total, <<>>)
    end.

-file("src/packkit/zstd.gleam", 76).
?DOC(
    " Encode `bytes` as a Zstandard frame.  The encoder picks the\n"
    " cheapest of `Raw_Block` and `RLE_Block` per chunk — a chunk that\n"
    " repeats a single byte collapses to a 1-byte RLE payload — so\n"
    " inputs like `repeat('A', N)` compress, but mixed input still\n"
    " passes through as raw bytes.  No LZ77 or Huffman compression yet,\n"
    " no content checksum.  Output is a valid Zstandard frame any\n"
    " conforming decoder can read.\n"
).
-spec encode(bitstring()) -> {ok, bitstring()} |
    {error, packkit@error:codec_error()}.
encode(Bytes) ->
    Size = erlang:byte_size(Bytes),
    gleam@result:'try'(
        frame_header_for_size(Size),
        fun(Header) ->
            Blocks = build_raw_blocks(Bytes, Size),
            {ok, gleam_stdlib:bit_array_concat([Header, Blocks])}
        end
    ).

-file("src/packkit/zstd.gleam", 2589).
-spec decode_data_frame(
    bitstring(),
    bitstring(),
    integer(),
    packkit@limit:limits()
) -> {ok, bitstring()} | {error, packkit@error:codec_error()}.
decode_data_frame(Bytes, Acc, Accumulated_size, Limits) ->
    gleam@result:'try'(
        parse_frame_header(Bytes),
        fun(_use0) ->
            {Checksum_flag, Rest} = _use0,
            gleam@result:'try'(
                decode_blocks(
                    Rest,
                    <<>>,
                    Limits,
                    {block_state,
                        none,
                        {seq_tables_state, none, none, none},
                        [],
                        {1, 4, 8}}
                ),
                fun(_use0@1) ->
                    {Output, Rest@1} = _use0@1,
                    gleam@result:'try'(
                        consume_checksum_returning_rest(Rest@1, Checksum_flag),
                        fun(Rest@2) ->
                            Next_size = Accumulated_size + erlang:byte_size(
                                Output
                            ),
                            case Next_size > packkit@limit:max_output_bytes(
                                Limits
                            ) of
                                true ->
                                    {error,
                                        {codec_limit_exceeded,
                                            <<"max_output_bytes"/utf8>>,
                                            Next_size}};

                                false ->
                                    Acc@1 = gleam_stdlib:bit_array_concat(
                                        [Acc, Output]
                                    ),
                                    case erlang:byte_size(Rest@2) of
                                        0 ->
                                            {ok, Acc@1};

                                        _ ->
                                            decode_frames_loop(
                                                Rest@2,
                                                Acc@1,
                                                Next_size,
                                                Limits
                                            )
                                    end
                            end
                        end
                    )
                end
            )
        end
    ).

-file("src/packkit/zstd.gleam", 2571).
-spec decode_frames_loop(
    bitstring(),
    bitstring(),
    integer(),
    packkit@limit:limits()
) -> {ok, bitstring()} | {error, packkit@error:codec_error()}.
decode_frames_loop(Bytes, Acc, Accumulated_size, Limits) ->
    case Bytes of
        <<M:32/little-unsigned, _/binary>> when (M >= 16#184D2A50) andalso (M =< 16#184D2A5F) ->
            skip_skippable_frame(Bytes, Acc, Accumulated_size, Limits);

        _ ->
            decode_data_frame(Bytes, Acc, Accumulated_size, Limits)
    end.

-file("src/packkit/zstd.gleam", 2556).
?DOC(
    " Decode a Zstandard frame using explicit limits.  Per RFC 8478 §3,\n"
    " a zstd \"byte stream\" is one or more frames concatenated; the\n"
    " decoder walks the entire input, appending each frame's payload to\n"
    " the result.\n"
).
-spec decode_with_limits(bitstring(), packkit@limit:limits()) -> {ok,
        bitstring()} |
    {error, packkit@error:codec_error()}.
decode_with_limits(Bytes, Limits) ->
    gleam@bool:guard(
        erlang:byte_size(Bytes) > packkit@limit:max_input_bytes(Limits),
        {error,
            {codec_limit_exceeded,
                <<"max_input_bytes"/utf8>>,
                erlang:byte_size(Bytes)}},
        fun() -> decode_frames_loop(Bytes, <<>>, 0, Limits) end
    ).

-file("src/packkit/zstd.gleam", 2548).
?DOC(" Decode a Zstandard frame using default limits.\n").
-spec decode(bitstring()) -> {ok, bitstring()} |
    {error, packkit@error:codec_error()}.
decode(Bytes) ->
    decode_with_limits(Bytes, packkit@limit:default()).

-file("src/packkit/zstd.gleam", 2620).
-spec skip_skippable_frame(
    bitstring(),
    bitstring(),
    integer(),
    packkit@limit:limits()
) -> {ok, bitstring()} | {error, packkit@error:codec_error()}.
skip_skippable_frame(Bytes, Acc, Accumulated_size, Limits) ->
    case Bytes of
        <<_:4/binary, Frame_size:32/little-unsigned, Rest/binary>> ->
            case erlang:byte_size(Rest) >= Frame_size of
                false ->
                    {error,
                        {codec_invalid_data,
                            <<"zstd skippable frame body is shorter than the declared Frame_Size"/utf8>>}};

                true ->
                    case gleam_stdlib:bit_array_slice(
                        Rest,
                        Frame_size,
                        erlang:byte_size(Rest) - Frame_size
                    ) of
                        {ok, After_skip} ->
                            case erlang:byte_size(After_skip) of
                                0 ->
                                    {ok, Acc};

                                _ ->
                                    decode_frames_loop(
                                        After_skip,
                                        Acc,
                                        Accumulated_size,
                                        Limits
                                    )
                            end;

                        {error, _} ->
                            {error,
                                {codec_invalid_data,
                                    <<"zstd skippable frame slice failed"/utf8>>}}
                    end
            end;

        _ ->
            {error,
                {codec_invalid_data,
                    <<"zstd skippable frame header is shorter than 8 bytes"/utf8>>}}
    end.