anchor.diff:          Result ->
               Result
       end.
  +
  +-spec raw_decode(list()|binary()) -> list() | binary() | uri_string:error().
  +raw_decode(Cs) ->
  +    raw_decode(Cs, <<>>).
  +%%
  +raw_decode(L, Acc) when is_list(L) ->
  +    try
  +        B0 = unicode:characters_to_binary(L),
  +        B1 = raw_decode(B0, Acc),
  +        unicode:characters_to_list(B1)
  +    catch
  +        throw:{error, Atom, RestData} ->
  +            {error, Atom, RestData}
  +    end;
  +raw_decode(<<$%,C0,C1,Cs/binary>>, Acc) ->
  +    case is_hex_digit(C0) andalso is_hex_digit(C1) of
  +        true ->
  +            B = ?HEX2DEC(C0)*16+?HEX2DEC(C1),
  +            raw_decode(Cs, <<Acc/binary, B>>);
  +        false ->
  +            throw({error,invalid_percent_encoding,<<$%,C0,C1>>})
  +    end;
  +raw_decode(<<C,Cs/binary>>, Acc) ->
  +    raw_decode(Cs, <<Acc/binary, C>>);
  +raw_decode(<<>>, Acc) ->
  +    check_utf8(Acc).
  +
  +%% Returns Cs if it is utf8 encoded.
  +check_utf8(Cs) ->
  +    case unicode:characters_to_list(Cs) of
  +        {incomplete,_,_} ->
  +            throw({error,invalid_utf8,Cs});
  +        {error,_,_} ->
  +            throw({error,invalid_utf8,Cs});
  +        _ -> Cs
  +    end.
  +
  +-spec is_hex_digit(char()) -> boolean().
  +is_hex_digit(C)
  +  when $0 =< C, C =< $9;$a =< C, C =< $f;$A =< C, C =< $F -> true;
  +is_hex_digit(_) -> false.
  
positive.code:     form_urlencode(Value, [{encoding, utf8}]).
  
  decode_key(Key) ->
      uri_string:percent_decode(string:trim(unicode:characters_to_binary(Key))).
  
  decode_value(Value) ->
      uri_string:percent_decode(string:trim(unicode:characters_to_binary(Value))).
  
  %% HTML 5.2 - 4.10.21.6 URL-encoded form data - WHATWG URL (10 Jan 2018) - UTF-8
  %% HTML 5.0 - 4.10.22.6 URL-encoded form data - encoding (non UTF-8)
  form_urlencode(Cs, [{encoding, latin1}]) when is_list(Cs) ->
      B = convert_to_binary(Cs, utf8, utf8),
      html5_byte_encode(base10_encode(B));
  form_urlencode(Cs, [{encoding, latin1}]) when is_binary(Cs) ->
      html5_byte_encode(base10_encode(Cs));
  form_urlencode(Cs, [{encoding, Encoding}])
    when is_list(Cs), Encoding =:= utf8; Encoding =:= unicode ->
      B = convert_to_binary(Cs, utf8, Encoding),
  
negative.code:     throw({error,invalid_encoding, Encoding});
  form_urlencode(Cs, _) ->
      throw({error,invalid_input, Cs}).
  
  html5_byte_encode(B) ->
      html5_byte_encode(B, <<>>).
  