diff --git a/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +1,12 @@
+# Low-level bindings for tree-sitter
+
+This package implements low-level bindings for [tree-sitter](https://tree-sitter.github.io/tree-sitter/),
+a widely-supported parser generator tool and an incremental parsing library.
+
+> ⚠️ WARNING:
+> You probably don't want to use this package directly, but instead use the high-level bindings implemented by [hs-tree-sitter](https://hackage.haskell.org/package/hs-tree-sitter).
+
+This package is compiled against [tree-sitter](https://github.com/tree-sitter/tree-sitter) version [0.24.3](https://github.com/tree-sitter/tree-sitter/releases/tag/v0.24.3) (2024-10-09).
+It is feature complete for version 14 of the tree-sitter ABI and is backwards compatible down to version 13.
+
+All tree-sitter versions up to version [0.25.8](https://github.com/tree-sitter/tree-sitter/releases/tag/v0.25.8) (2025-07-13) are backwards compatible down to version 13, so this package should work with all grammars generated by any version of tree-sitter after [0.19.0](https://github.com/tree-sitter/tree-sitter/releases/tag/v0.19.0) (2021-03-01), though this is untested.
diff --git a/hs-tree-sitter-capi.cabal b/hs-tree-sitter-capi.cabal
new file mode 100644
--- /dev/null
+++ b/hs-tree-sitter-capi.cabal
@@ -0,0 +1,113 @@
+cabal-version:      3.4
+name:               hs-tree-sitter-capi
+version:            13.0.14.0
+license:            AGPL-3.0-only
+synopsis:           Low-level bindings for tree-sitter
+description:        Low-level bindings for tree-sitter.
+author:             Wen Kokke
+maintainer:         wenkokke@users.noreply.github.com
+category:           Language
+build-type:         Simple
+extra-doc-files:    README.md
+extra-source-files:
+  vendor/tree-sitter/lib/include/tree_sitter/api.h
+  vendor/tree-sitter/lib/src/alloc.c
+  vendor/tree-sitter/lib/src/alloc.h
+  vendor/tree-sitter/lib/src/array.h
+  vendor/tree-sitter/lib/src/atomic.h
+  vendor/tree-sitter/lib/src/clock.h
+  vendor/tree-sitter/lib/src/error_costs.h
+  vendor/tree-sitter/lib/src/get_changed_ranges.c
+  vendor/tree-sitter/lib/src/get_changed_ranges.h
+  vendor/tree-sitter/lib/src/host.h
+  vendor/tree-sitter/lib/src/language.c
+  vendor/tree-sitter/lib/src/language.h
+  vendor/tree-sitter/lib/src/length.h
+  vendor/tree-sitter/lib/src/lexer.c
+  vendor/tree-sitter/lib/src/lexer.h
+  vendor/tree-sitter/lib/src/lib.c
+  vendor/tree-sitter/lib/src/node.c
+  vendor/tree-sitter/lib/src/parser.c
+  vendor/tree-sitter/lib/src/parser.h
+  vendor/tree-sitter/lib/src/point.h
+  vendor/tree-sitter/lib/src/query.c
+  vendor/tree-sitter/lib/src/reduce_action.h
+  vendor/tree-sitter/lib/src/reusable_node.h
+  vendor/tree-sitter/lib/src/stack.c
+  vendor/tree-sitter/lib/src/stack.h
+  vendor/tree-sitter/lib/src/subtree.c
+  vendor/tree-sitter/lib/src/subtree.h
+  vendor/tree-sitter/lib/src/tree.c
+  vendor/tree-sitter/lib/src/tree.h
+  vendor/tree-sitter/lib/src/tree_cursor.c
+  vendor/tree-sitter/lib/src/tree_cursor.h
+  vendor/tree-sitter/lib/src/ts_assert.h
+  vendor/tree-sitter/lib/src/unicode/ptypes.h
+  vendor/tree-sitter/lib/src/unicode/umachine.h
+  vendor/tree-sitter/lib/src/unicode/urename.h
+  vendor/tree-sitter/lib/src/unicode/utf.h
+  vendor/tree-sitter/lib/src/unicode/utf16.h
+  vendor/tree-sitter/lib/src/unicode/utf8.h
+  vendor/tree-sitter/lib/src/unicode.h
+  vendor/tree-sitter/lib/src/wasm/stdlib.c
+  vendor/tree-sitter/lib/src/wasm/wasm-stdlib.h
+  vendor/tree-sitter/lib/src/wasm_store.c
+  vendor/tree-sitter/lib/src/wasm_store.h
+  vendor/tree-sitter/lib/tree-sitter.pc.in
+
+tested-with:
+  GHC ==8.10.7
+   || ==9.0.2
+   || ==9.2.8
+   || ==9.4.8
+   || ==9.6.7
+   || ==9.8.4
+   || ==9.10.2
+   || ==9.12.2
+
+common language
+  ghc-options:
+    -Wall -Wcompat -Widentities -Wprepositive-qualified-module
+    -Wredundant-constraints -Wunticked-promoted-constructors
+    -Wunused-packages
+
+  default-language:   Haskell2010
+  default-extensions: ImportQualifiedPost
+
+  if impl(ghc <9.6.1)
+    ghc-options:
+      -optc=-Wno-discarded-qualifiers
+      -optc=-Wno-incompatible-pointer-types-discards-qualifiers
+
+library
+  import:             language
+  exposed-modules:    TreeSitter.CApi
+  build-tool-depends: hsc2hs:hsc2hs
+  hs-source-dirs:     src
+  include-dirs:
+    vendor/tree-sitter/lib/include vendor/tree-sitter/lib/src
+
+  includes:           tree_sitter/api.h
+  c-sources:          vendor/tree-sitter/lib/src/lib.c
+  build-depends:
+    , base                  >=4.13 && <5
+    , base-compat-constptr  >=0.1  && <0.2
+
+  -- Does not compile on macOS/arm64 with GHC <9.6.5
+  -- See: https://gitlab.haskell.org/ghc/ghc/-/issues/23456
+  if (impl(ghc <9.6.5) && arch(aarch64))
+    build-depends: base >=4.18.2.1
+
+test-suite hs-tree-sitter-capi-test
+  import:         language
+  type:           exitcode-stdio-1.0
+  hs-source-dirs: test
+  main-is:        Main.hs
+  other-modules:  Test.TreeSitter.CApi
+  build-depends:
+    , base
+    , base-compat-constptr
+    , hs-tree-sitter-capi
+    , tasty                 >=1.5  && <1.6
+    , tasty-hunit           >=0.10 && <0.11
+    , tree-sitter-while
diff --git a/src/TreeSitter/CApi.hsc b/src/TreeSitter/CApi.hsc
new file mode 100644
--- /dev/null
+++ b/src/TreeSitter/CApi.hsc
@@ -0,0 +1,4132 @@
+{-# LANGUAGE CApiFFI #-}
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE DerivingStrategies #-}
+{-# LANGUAGE DuplicateRecordFields #-}
+{-# LANGUAGE GADTs #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# LANGUAGE LambdaCase #-}
+{-# LANGUAGE PatternSynonyms #-}
+{-# LANGUAGE RecordWildCards #-}
+{-# LANGUAGE StandaloneKindSignatures #-}
+{-# LANGUAGE StandaloneDeriving #-}
+{-# LANGUAGE TypeApplications #-}
+
+module TreeSitter.CApi
+  ( -- * ABI Versioning
+    TREE_SITTER_LANGUAGE_VERSION
+  , TREE_SITTER_MIN_COMPATIBLE_LANGUAGE_VERSION
+
+    -- * Types
+  , TSStateId (..)
+  , TSSymbol (..)
+  , TSFieldId (..)
+  , TSLanguage
+  , TSParser
+  , TSTree
+  , TSQuery
+  , TSQueryCursor
+  , TSLookaheadIterator
+  , TSInputEncoding (TSInputEncodingUTF8, TSInputEncodingUTF16, ..)
+  , TSSymbolType (TSSymbolTypeRegular, TSSymbolTypeAnonymous, TSSymbolTypeSupertype, TSSymbolTypeAuxiliary, ..)
+  , TSPoint (..)
+  , TSRange (..)
+  , TSInput
+  , TSRead
+  , TSLogType (TSLogTypeParse, TSLogTypeLex, ..)
+  , TSLogger
+  , TSLog
+  , TSInputEdit (..)
+  , TSNode (..)
+  , TSNodeContext (..)
+  , TSTreeCursor (..)
+  , TSTreeCursorContext (..)
+  , TSQueryCapture (..)
+  , TSQuantifier (TSQuantifierZero, TSQuantifierZeroOrOne, TSQuantifierZeroOrMore, TSQuantifierOne, TSQuantifierOneOrMore, ..)
+  , TSQueryMatch (..)
+  , TSQueryPredicateStepType (TSQueryPredicateStepTypeDone, TSQueryPredicateStepTypeCapture, TSQueryPredicateStepTypeString, ..)
+  , TSQueryPredicateStep (..)
+  , TSQueryError (TSQueryErrorNone, TSQueryErrorSyntax, TSQueryErrorNodeType, TSQueryErrorField, TSQueryErrorCapture, TSQueryErrorStructure, TSQueryErrorLanguage, ..)
+
+    -- * Parser
+  , ts_parser_new
+  , ts_parser_delete
+  , p_ts_parser_delete
+  , ts_parser_language
+  , ts_parser_set_language
+  , ts_parser_set_included_ranges
+  , ts_parser_included_ranges
+  , ts_parser_set_logger
+  , ts_parser_logger
+  , ts_parser_remove_logger
+  , ts_parser_parse
+  , ts_parser_parse_string
+  , ts_parser_parse_string_encoding
+  , ts_parser_reset
+  , ts_parser_set_timeout_micros
+  , ts_parser_timeout_micros
+  , ts_parser_set_cancellation_flag
+  , ts_parser_cancellation_flag
+  , ts_parser_print_dot_graphs
+
+    -- * Tree
+  , ts_tree_copy
+  , ts_tree_delete
+  , p_ts_tree_delete
+  , ts_tree_language
+  , ts_tree_included_ranges
+  , ts_tree_edit
+  , ts_tree_get_changed_ranges
+  , ts_tree_print_dot_graph
+  , ts_tree_root_node
+  , ts_tree_root_node_with_offset
+
+    -- * Node
+  , ts_node_type
+  , ts_node_symbol
+  , ts_node_language
+  , ts_node_grammar_type
+  , ts_node_grammar_symbol
+  , ts_node_start_byte
+  , ts_node_start_point
+  , ts_node_end_byte
+  , ts_node_end_point
+  , ts_node_string
+  , ts_node_is_null
+  , ts_node_is_named
+  , ts_node_is_missing
+  , ts_node_is_extra
+  , ts_node_has_changes
+  , ts_node_has_error
+  , ts_node_is_error
+  , ts_node_parse_state
+  , ts_node_next_parse_state
+  , ts_node_parent
+  , ts_node_child_with_descendant
+  , ts_node_child
+  , ts_node_field_name_for_child
+  , ts_node_field_name_for_named_child
+  , ts_node_child_count
+  , ts_node_named_child
+  , ts_node_named_child_count
+  , ts_node_child_by_field_name
+  , ts_node_child_by_field_id
+  , ts_node_next_sibling
+  , ts_node_prev_sibling
+  , ts_node_next_named_sibling
+  , ts_node_prev_named_sibling
+  , ts_node_first_child_for_byte
+  , ts_node_first_named_child_for_byte
+  , ts_node_descendant_count
+  , ts_node_descendant_for_byte_range
+  , ts_node_descendant_for_point_range
+  , ts_node_named_descendant_for_byte_range
+  , ts_node_named_descendant_for_point_range
+  , ts_node_edit
+  , ts_node_eq
+
+    -- * TreeCursor
+  , ts_tree_cursor_new
+  , ts_tree_cursor_new_p
+  , ts_tree_cursor_delete
+  , p_ts_tree_cursor_delete
+  , ts_tree_cursor_reset
+  , ts_tree_cursor_reset_to
+  , ts_tree_cursor_current_node
+  , ts_tree_cursor_current_field_name
+  , ts_tree_cursor_current_field_id
+  , ts_tree_cursor_goto_parent
+  , ts_tree_cursor_goto_next_sibling
+  , ts_tree_cursor_goto_previous_sibling
+  , ts_tree_cursor_goto_first_child
+  , ts_tree_cursor_goto_last_child
+  , ts_tree_cursor_goto_descendant
+  , ts_tree_cursor_current_descendant_index
+  , ts_tree_cursor_current_depth
+  , ts_tree_cursor_goto_first_child_for_byte
+  , ts_tree_cursor_goto_first_child_for_point
+  , ts_tree_cursor_copy
+  , ts_tree_cursor_copy_p
+
+    -- * Query
+  , ts_query_new
+  , ts_query_delete
+  , p_ts_query_delete
+  , ts_query_pattern_count
+  , ts_query_capture_count
+  , ts_query_string_count
+  , ts_query_start_byte_for_pattern
+  , ts_query_end_byte_for_pattern
+  , ts_query_predicates_for_pattern
+  , ts_query_is_pattern_rooted
+  , ts_query_is_pattern_non_local
+  , ts_query_is_pattern_guaranteed_at_step
+  , ts_query_capture_name_for_id
+  , ts_query_capture_quantifier_for_id
+  , ts_query_string_value_for_id
+  , ts_query_disable_capture
+  , ts_query_disable_pattern
+  , ts_query_cursor_new
+  , ts_query_cursor_delete
+  , p_ts_query_cursor_delete
+  , ts_query_cursor_exec
+  , ts_query_cursor_did_exceed_match_limit
+  , ts_query_cursor_match_limit
+  , ts_query_cursor_set_match_limit
+  , ts_query_cursor_set_timeout_micros
+  , ts_query_cursor_timeout_micros
+  , ts_query_cursor_set_byte_range
+  , ts_query_cursor_set_point_range
+  , ts_query_cursor_next_match
+  , ts_query_cursor_remove_match
+  , ts_query_cursor_next_capture
+  , ts_query_cursor_set_max_start_depth
+
+    -- * Language
+  , ts_language_copy
+  , ts_language_delete
+  , p_ts_language_delete
+  , ts_language_symbol_count
+  , ts_language_state_count
+  , ts_language_symbol_name
+  , ts_language_symbol_for_name
+  , ts_language_field_count
+  , ts_language_field_name_for_id
+  , ts_language_field_id_for_name
+  , ts_language_symbol_type
+  , ts_language_version
+  , ts_language_next_state
+
+    -- * Lookahead Iterator
+  , ts_lookahead_iterator_new
+  , ts_lookahead_iterator_delete
+  , p_ts_lookahead_iterator_delete
+  , ts_lookahead_iterator_reset_state
+  , ts_lookahead_iterator_reset
+  , ts_lookahead_iterator_language
+  , ts_lookahead_iterator_next
+  , ts_lookahead_iterator_current_symbol
+  , ts_lookahead_iterator_current_symbol_name
+
+#ifdef TREE_SITTER_FEATURE_WASM
+    -- * WebAssembly Integration
+  , TSWasmEngine
+  , TSWasmStore
+  , TSWasmErrorKind (TSWasmErrorKindNone, TSWasmErrorKindParse, TSWasmErrorKindCompile, TSWasmErrorKindInstantiate, TSWasmErrorKindAllocate)
+  , TSWasmError
+  , peekTSWasmError
+  , withTSWasmError
+  , ts_wasm_store_new
+  , ts_wasm_store_delete
+  , p_ts_wasm_store_delete
+  , ts_wasm_store_load_language
+  , ts_wasm_store_language_count
+  , ts_language_is_wasm
+  , ts_parser_set_wasm_store
+  , ts_parser_take_wasm_store
+#endif
+
+    -- * Global Configuration
+  , ts_set_allocator
+  ) where
+
+import Control.Exception (bracket, mask_)
+#ifdef TREE_SITTER_FEATURE_WASM
+import Data.ByteString (ByteString)
+import Data.ByteString qualified as BS (packCString, useAsCString)
+#endif
+import Data.Void (Void)
+import Data.Word
+import Foreign
+import Foreign.C
+import Foreign.C.ConstPtr.Compat (ConstPtr(..))
+import GHC.TypeLits (Nat)
+
+#include <tree_sitter/api.h>
+-- string.h: required for memcpy
+#include <string.h>
+
+{----------------------------}
+{- Section - ABI Versioning -}
+{----------------------------}
+
+{-|
+  The latest ABI version that is supported by the current version of the
+  library. When Languages are generated by the Tree-sitter CLI, they are
+  assigned an ABI version number that corresponds to the current CLI version.
+  The Tree-sitter library is generally backwards-compatible with languages
+  generated using older CLI versions, but is not forwards-compatible.
+
+  > #define TREE_SITTER_LANGUAGE_VERSION 14
+-}
+type TREE_SITTER_LANGUAGE_VERSION :: Nat
+type TREE_SITTER_LANGUAGE_VERSION = #const TREE_SITTER_LANGUAGE_VERSION
+
+{-|
+  The earliest ABI version that is supported by the current version of the
+  library.
+
+  > #define TREE_SITTER_MIN_COMPATIBLE_LANGUAGE_VERSION 13
+-}
+type TREE_SITTER_MIN_COMPATIBLE_LANGUAGE_VERSION :: Nat
+type TREE_SITTER_MIN_COMPATIBLE_LANGUAGE_VERSION = #const TREE_SITTER_MIN_COMPATIBLE_LANGUAGE_VERSION
+
+{-------------------}
+{- Section - Types -}
+{-------------------}
+
+{-|
+  > typedef uint16_t TSStateId;
+  -}
+newtype
+  {-# CTYPE "tree_sitter/api.h" "TSStateId" #-}
+  TSStateId = TSStateId #{type TSStateId}
+  deriving stock (Show, Read, Eq, Ord)
+  deriving newtype (Num, Real, Integral, Enum)
+
+{-|
+  > typedef uint16_t TSSymbol;
+  -}
+newtype
+  {-# CTYPE "tree_sitter/api.h" "TSSymbol" #-}
+  TSSymbol = TSSymbol #{type TSSymbol}
+  deriving stock (Show, Read, Eq, Ord)
+  deriving newtype (Num, Real, Integral, Enum)
+
+{-|
+  > typedef uint16_t TSFieldId;
+  -}
+newtype
+  {-# CTYPE "tree_sitter/api.h" "TSFieldId" #-}
+  TSFieldId = TSFieldId #{type TSFieldId}
+  deriving stock (Show, Read, Eq, Ord)
+  deriving newtype (Num, Real, Integral, Enum)
+
+{-|
+  > typedef struct TSLanguage TSLanguage;
+  -}
+data
+  {-# CTYPE "tree_sitter/api.h" "TSLanguage" #-}
+  TSLanguage
+
+{-|
+  > typedef struct TSParser TSParser;
+  -}
+data
+  {-# CTYPE "tree_sitter/api.h" "TSParser" #-}
+  TSParser
+
+{-|
+  > typedef struct TSTree TSTree;
+  -}
+data
+  {-# CTYPE "tree_sitter/api.h" "TSTree" #-}
+  TSTree
+
+{-|
+  > typedef struct TSQuery TSQuery;
+  -}
+data
+  {-# CTYPE "tree_sitter/api.h" "TSQuery" #-}
+  TSQuery
+
+{-|
+  > typedef struct TSQueryCursor TSQueryCursor;
+  -}
+data
+  {-# CTYPE "tree_sitter/api.h" "TSQueryCursor" #-}
+  TSQueryCursor
+
+{-|
+  > typedef struct TSLookaheadIterator TSLookaheadIterator;
+  -}
+data
+  {-# CTYPE "tree_sitter/api.h" "TSLookaheadIterator" #-}
+  TSLookaheadIterator
+
+{-|
+  > typedef enum TSInputEncoding {
+  >   TSInputEncodingUTF8,
+  >   TSInputEncodingUTF16,
+  > } TSInputEncoding;
+  -}
+newtype
+  {-# CTYPE "tree_sitter/api.h" "TSInputEncoding" #-}
+  TSInputEncoding = TSInputEncoding
+    { unTSInputEncoding :: #{type TSInputEncoding}
+    }
+    deriving (Eq, Show)
+    deriving newtype (Storable)
+
+pattern TSInputEncodingUTF8 :: TSInputEncoding
+pattern TSInputEncodingUTF8 = TSInputEncoding ( #{const TSInputEncodingUTF8} )
+
+pattern TSInputEncodingUTF16 :: TSInputEncoding
+pattern TSInputEncodingUTF16 = TSInputEncoding ( #{const TSInputEncodingUTF16} )
+
+{-# COMPLETE TSInputEncodingUTF8, TSInputEncodingUTF16 #-}
+
+{-|
+  > typedef enum TSSymbolType {
+  >   TSSymbolTypeRegular,
+  >   TSSymbolTypeAnonymous,
+  >   TSSymbolTypeSupertype,
+  >   TSSymbolTypeAuxiliary,
+  > } TSSymbolType;
+  -}
+newtype
+  {-# CTYPE "tree_sitter/api.h" "TSSymbolType" #-}
+  TSSymbolType = TSSymbolType
+    { unTSSymbolType :: #{type TSSymbolType}
+    }
+    deriving (Eq, Show)
+
+pattern TSSymbolTypeRegular :: TSSymbolType
+pattern TSSymbolTypeRegular = TSSymbolType ( #{const TSSymbolTypeRegular} )
+
+pattern TSSymbolTypeAnonymous :: TSSymbolType
+pattern TSSymbolTypeAnonymous = TSSymbolType ( #{const TSSymbolTypeAnonymous} )
+
+pattern TSSymbolTypeSupertype :: TSSymbolType
+pattern TSSymbolTypeSupertype = TSSymbolType ( #{const TSSymbolTypeSupertype} )
+
+pattern TSSymbolTypeAuxiliary :: TSSymbolType
+pattern TSSymbolTypeAuxiliary = TSSymbolType ( #{const TSSymbolTypeAuxiliary} )
+
+{-# COMPLETE TSSymbolTypeRegular, TSSymbolTypeAnonymous, TSSymbolTypeSupertype, TSSymbolTypeAuxiliary #-}
+
+{-|
+  > typedef struct TSPoint {
+  >   uint32_t row;
+  >   uint32_t column;
+  > } TSPoint;
+  -}
+data
+  {-# CTYPE "tree_sitter/api.h" "struct TSPoint" #-}
+  TSPoint = TSPoint
+  { row    :: {-# UNPACK #-} !( #{type uint32_t} )
+  , column :: {-# UNPACK #-} !( #{type uint32_t} )
+  }
+  deriving (Ord, Eq, Show)
+
+instance Storable TSPoint where
+  alignment _ = #{alignment TSPoint}
+  sizeOf _ = #{size TSPoint}
+  peek ptr = do
+    row <- #{peek TSPoint, row} ptr
+    column <- #{peek TSPoint, column} ptr
+    return TSPoint{..}
+  poke ptr TSPoint{..} = do
+    #{poke TSPoint, row} ptr row
+    #{poke TSPoint, column} ptr column
+
+{-|
+  > typedef struct TSRange {
+  >   TSPoint start_point;
+  >   TSPoint end_point;
+  >   uint32_t start_byte;
+  >   uint32_t end_byte;
+  > } TSRange;
+  -}
+data
+  {-# CTYPE "tree_sitter/api.h" "struct TSRange" #-}
+  TSRange = TSRange
+  { start_point :: {-# UNPACK #-} !TSPoint
+  , end_point   :: {-# UNPACK #-} !TSPoint
+  , start_byte  :: {-# UNPACK #-} !( #{type uint32_t} )
+  , end_byte    :: {-# UNPACK #-} !( #{type uint32_t} )
+  }
+  deriving (Eq, Show)
+
+instance Storable TSRange where
+  alignment _ = #{alignment TSRange}
+  sizeOf _ = #{size TSRange}
+  peek ptr = do
+    start_point <- #{peek TSRange, start_point} ptr
+    end_point <- #{peek TSRange, end_point} ptr
+    start_byte <- #{peek TSRange, start_byte} ptr
+    end_byte <- #{peek TSRange, end_byte} ptr
+    return TSRange{..}
+  poke ptr TSRange{..} = do
+    #{poke TSRange, start_point} ptr start_point
+    #{poke TSRange, end_point} ptr end_point
+    #{poke TSRange, start_byte} ptr start_byte
+    #{poke TSRange, end_byte} ptr end_byte
+
+{-|
+  > typedef struct TSInput {
+  >   void *payload;
+  >   const char *(*read)(
+  >     void *payload,
+  >     uint32_t byte_index,
+  >     TSPoint position,
+  >     uint32_t *bytes_read
+  >   );
+  >   TSInputEncoding encoding;
+  > } TSInput;
+  -}
+data
+  {-# CTYPE "tree_sitter/api.h" "struct TSInput" #-}
+  TSInput
+
+{-| The type of the @`read`@ argument of the @`_wrap_ts_input_new`@ function.
+
+  > typedef const char *(*TSRead)(
+  >   uint32_t byte_index,
+  >   TSPoint *position,
+  >   uint32_t *bytes_read
+  > );
+  -}
+type TSRead =
+  ( #{type uint32_t} ) ->
+  Ptr TSPoint ->
+  Ptr ( #{type uint32_t} ) ->
+  IO (ConstPtr CChar)
+
+-- | Convert a Haskell 'TSRead' closure to a C 'TSRead' function pointer.
+foreign import ccall "wrapper"
+  mkTSReadFunPtr :: TSRead -> IO (FunPtr TSRead)
+
+#{def
+  typedef const char *(*TSRead)(
+    uint32_t byte_index,
+    TSPoint *position,
+    uint32_t *bytes_read
+  );
+}
+
+-- | Create a @`TSInput`@.
+foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_input_new"
+  _wrap_ts_input_new ::
+    FunPtr TSRead ->
+    TSInputEncoding ->
+    IO (Ptr TSInput)
+
+#{def
+  const char *_wrap_ts_input_read(
+    void *payload,
+    uint32_t byte_index,
+    TSPoint position,
+    uint32_t *bytes_read
+  ) {
+    TSRead read;
+    memcpy(&read, payload, sizeof read);
+    TSPoint *position_p = &position;
+    return read(byte_index, position_p, bytes_read);
+  }
+}
+
+#{def
+  TSInput *_wrap_ts_input_new(
+    TSRead read,
+    TSInputEncoding encoding
+  ) {
+    TSInput *input = malloc(sizeof *input);
+    input->payload = malloc(sizeof read);
+    memcpy(input->payload, &read, sizeof read);
+    input->read = _wrap_ts_input_read;
+    input->encoding = encoding;
+    return input;
+  }
+}
+
+-- | Delete a @`TSInput`@.
+foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_input_delete"
+  _wrap_ts_input_delete ::
+    Ptr TSInput ->
+    IO ()
+
+#{def
+  void _wrap_ts_input_delete(
+    TSInput *input
+  ) {
+    free(input->payload);
+    free(input);
+  }
+}
+
+{-|
+  > typedef enum TSLogType {
+  >   TSLogTypeParse,
+  >   TSLogTypeLex,
+  > } TSLogType;
+  -}
+newtype
+  {-# CTYPE "tree_sitter/api.h" "TSLogType" #-}
+  TSLogType = TSLogType
+    { unTSLogType :: #{type TSLogType}
+    }
+    deriving (Eq, Show)
+
+pattern TSLogTypeParse :: TSLogType
+pattern TSLogTypeParse = TSLogType ( #{const TSLogTypeParse} )
+
+pattern TSLogTypeLex :: TSLogType
+pattern TSLogTypeLex = TSLogType ( #{const TSLogTypeLex} )
+
+{-# COMPLETE TSLogTypeParse, TSLogTypeLex #-}
+
+{-|
+  > typedef struct TSLogger {
+  >   void *payload;
+  >   void (*log)(void *payload, TSLogType log_type, const char *buffer);
+  > } TSLogger;
+  -}
+data
+  {-# CTYPE "tree_sitter/api.h" "struct TSLogger" #-}
+  TSLogger
+
+#{def
+typedef void (*TSLog)(
+  TSLogType log_type,
+  const char *buffer
+);
+}
+
+{-| The type of the @`log`@ argument of the @`_wrap_ts_logger_new`@ function.
+
+  > void (*log)(TSLogType log_type, const char *buffer);
+ -}
+type TSLog =
+  TSLogType ->
+  ConstPtr CChar ->
+  IO ()
+
+{-|
+ > TSLogger *_wrap_ts_logger_new(TSLog log);
+ -}
+foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_logger_new"
+  _wrap_ts_logger_new ::
+    FunPtr TSLog ->
+    IO (Ptr TSLogger)
+
+#{def
+  void _wrap_ts_logger_log(
+    void *payload,
+    TSLogType log_type,
+    const char *buffer
+  ) {
+    TSLog log;
+    memcpy(&log, payload, sizeof log);
+    log(log_type, buffer);
+  }
+}
+
+#{def
+  TSLogger *_wrap_ts_logger_new(TSLog log) {
+    TSLogger *logger = malloc(sizeof *logger);
+    logger->payload = malloc(sizeof log);
+    memcpy(logger->payload, &log, sizeof log);
+    logger->log = _wrap_ts_logger_log;
+    return logger;
+  }
+}
+
+{-| Allocate a C function pointer for a `TSLog` function.
+ -}
+foreign import ccall "wrapper"
+  mkTSLogFunPtr :: TSLog -> IO (FunPtr TSLog)
+
+{-| Convert a C function pointer for a `TSLog` function
+    to the corresponding Haskell function.
+ -}
+foreign import ccall "dynamic"
+  unTSLogFunPtr :: FunPtr TSLog -> TSLog
+
+{-|
+  > typedef struct TSInputEdit {
+  >   uint32_t start_byte;
+  >   uint32_t old_end_byte;
+  >   uint32_t new_end_byte;
+  >   TSPoint start_point;
+  >   TSPoint old_end_point;
+  >   TSPoint new_end_point;
+  > } TSInputEdit;
+  -}
+data
+  {-# CTYPE "tree_sitter/api.h" "struct TSInputEdit" #-}
+  TSInputEdit = TSInputEdit
+  { start_byte    :: {-# UNPACK #-} !( #{type uint32_t} )
+  , old_end_byte  :: {-# UNPACK #-} !( #{type uint32_t} )
+  , new_end_byte  :: {-# UNPACK #-} !( #{type uint32_t} )
+  , start_point   :: {-# UNPACK #-} !TSPoint
+  , old_end_point :: {-# UNPACK #-} !TSPoint
+  , new_end_point :: {-# UNPACK #-} !TSPoint
+  }
+  deriving (Eq, Show)
+
+instance Storable TSInputEdit where
+  alignment _ = #{alignment TSInputEdit}
+  sizeOf _ = #{size TSInputEdit}
+  peek ptr = do
+    start_byte <- #{peek TSInputEdit, start_byte} ptr
+    old_end_byte <- #{peek TSInputEdit, old_end_byte} ptr
+    new_end_byte <- #{peek TSInputEdit, new_end_byte} ptr
+    start_point <- #{peek TSInputEdit, start_point} ptr
+    old_end_point <- #{peek TSInputEdit, old_end_point} ptr
+    new_end_point <- #{peek TSInputEdit, new_end_point} ptr
+    return TSInputEdit{..}
+  poke ptr TSInputEdit{..} = do
+    #{poke TSInputEdit, start_byte} ptr start_byte
+    #{poke TSInputEdit, old_end_byte} ptr old_end_byte
+    #{poke TSInputEdit, new_end_byte} ptr new_end_byte
+    #{poke TSInputEdit, start_point} ptr start_point
+    #{poke TSInputEdit, old_end_point} ptr old_end_point
+    #{poke TSInputEdit, new_end_point} ptr new_end_point
+
+{-|
+  > typedef struct TSNode {
+  >   uint32_t context[4];
+  >   const void *id;
+  >   const TSTree *tree;
+  > } TSNode;
+  -}
+data
+  {-# CTYPE "tree_sitter/api.h" "struct TSNode" #-}
+  TSNode = TSNode
+  { _context :: {-# UNPACK #-} !TSNodeContext
+  , _id :: {-# UNPACK #-} !(ConstPtr Void)
+  , _tree :: {-# UNPACK #-} !(ConstPtr TSTree)
+  }
+
+instance Storable TSNode where
+  alignment _ = #{alignment TSNode}
+  sizeOf _ = #{size TSNode}
+  peek ptr = do
+    _context <- peekTSNodeContext ( #{ptr TSNode, context} ptr )
+    _id <- ConstPtr <$> #{peek TSNode, id} ptr
+    _tree <- ConstPtr <$> #{peek TSNode, tree} ptr
+    return TSNode{..}
+  poke ptr TSNode{..} = do
+    pokeTSNodeContext ( #{ptr TSNode, context} ptr ) _context
+    #{poke TSNode, id} ptr (unConstPtr _id)
+    #{poke TSNode, tree} ptr (unConstPtr _tree)
+
+{-| The type of the @`_context`@ field of a @`TSNode`@ struct.
+
+ > uint32_t context[4];
+ -}
+data
+  TSNodeContext = TSNodeContext
+    {-# UNPACK #-} !( #{type uint32_t} )
+    {-# UNPACK #-} !( #{type uint32_t} )
+    {-# UNPACK #-} !( #{type uint32_t} )
+    {-# UNPACK #-} !( #{type uint32_t} )
+
+{-| Peek a @`TSNodeContext`@.
+
+    This does the same as `peek` would, except that @`TSNodeContext`@ is not an instance of `Storable`.
+ -}
+peekTSNodeContext :: Ptr ( #{type uint32_t} ) -> IO TSNodeContext
+peekTSNodeContext ptr = do
+  [x0, x1, x2, x3] <- peekArray 4 ptr
+  return $ TSNodeContext x0 x1 x2 x3
+
+{-| Poke a @`TSNodeContext`@.
+
+    This does the same as `poke` would, except that @`TSNodeContext`@ is not an instance of `Storable`.
+ -}
+pokeTSNodeContext :: Ptr ( #{type uint32_t} ) -> TSNodeContext -> IO ()
+pokeTSNodeContext ptr (TSNodeContext x0 x1 x2 x3) = do
+  pokeArray ptr [x0, x1, x2, x3]
+
+{-|
+  > typedef struct TSTreeCursor {
+  >   const void *tree;
+  >   const void *id;
+  >   uint32_t context[3];
+  > } TSTreeCursor;
+  -}
+data
+  {-# CTYPE "tree_sitter/api.h" "struct TSTreeCursor" #-}
+  TSTreeCursor = TSTreeCursor
+  { _tree :: {-# UNPACK #-} !(ConstPtr Void)
+  , _id :: {-# UNPACK #-} !(ConstPtr Void)
+  , _context :: {-# UNPACK #-} !TSTreeCursorContext
+  }
+
+instance Storable TSTreeCursor where
+  alignment _ = #{alignment TSTreeCursor}
+  sizeOf _ = #{size TSTreeCursor}
+  peek ptr = do
+    _tree <- ConstPtr <$> #{peek TSTreeCursor, tree} ptr
+    _id <- ConstPtr <$> #{peek TSTreeCursor, id} ptr
+    _context <- peekTSTreeCursorContext ( #{ptr TSTreeCursor, context} ptr )
+    return TSTreeCursor{..}
+  poke ptr TSTreeCursor{..} = do
+    #{poke TSTreeCursor, tree} ptr (unConstPtr _tree)
+    #{poke TSTreeCursor, id} ptr (unConstPtr _id)
+    pokeTSTreeCursorContext ( #{ptr TSTreeCursor, context} ptr ) _context
+
+{-| The type of the @`_context`@ field of a @`TSTreeCursor`@ struct.
+
+ > uint32_t context[3];
+ -}
+data
+  TSTreeCursorContext = TSTreeCursorContext
+    {-# UNPACK #-} !( #{type uint32_t} )
+    {-# UNPACK #-} !( #{type uint32_t} )
+    {-# UNPACK #-} !( #{type uint32_t} )
+
+{-| Peek a @`TSTreeCursorContext`@.
+
+    This does the same as `peek` would, except that @`TSTreeCursorContext`@ is not an instance of `Storable`.
+ -}
+peekTSTreeCursorContext :: Ptr ( #{type uint32_t} ) -> IO TSTreeCursorContext
+peekTSTreeCursorContext ptr = do
+  [x0, x1, x2] <- peekArray 3 ptr
+  return $ TSTreeCursorContext x0 x1 x2
+
+{-| Poke a @`TSTreeCursorContext`@.
+
+    This does the same as `poke` would, except that @`TSTreeCursorContext`@ is not an instance of `Storable`.
+ -}
+pokeTSTreeCursorContext :: Ptr ( #{type uint32_t} ) -> TSTreeCursorContext -> IO ()
+pokeTSTreeCursorContext ptr (TSTreeCursorContext x0 x1 x2) = do
+  pokeArray ptr [x0, x1, x2]
+
+{-|
+  > typedef struct TSQueryCapture {
+  >   TSNode node;
+  >   uint32_t index;
+  > } TSQueryCapture;
+  -}
+data
+  {-# CTYPE "tree_sitter/api.h" "struct TSQueryCapture" #-}
+  TSQueryCapture = TSQueryCapture
+  { _node :: {-# UNPACK #-} !TSNode
+  , _index :: {-# UNPACK #-} !( #{type uint32_t} )
+  }
+
+instance Storable TSQueryCapture where
+  alignment _ = #{alignment TSQueryCapture}
+  sizeOf _ = #{size TSQueryCapture}
+  peek ptr = do
+    _node <- #{peek TSQueryCapture, node} ptr
+    _index <- #{peek TSQueryCapture, index} ptr
+    return TSQueryCapture{..}
+  poke ptr TSQueryCapture{..} = do
+    #{poke TSQueryCapture, node} ptr _node
+    #{poke TSQueryCapture, index} ptr _index
+
+{-|
+  > typedef enum TSQuantifier {
+  >   TSQuantifierZero = 0, // must match the array initialization value
+  >   TSQuantifierZeroOrOne,
+  >   TSQuantifierZeroOrMore,
+  >   TSQuantifierOne,
+  >   TSQuantifierOneOrMore,
+  > } TSQuantifier;
+  -}
+newtype
+  {-# CTYPE "tree_sitter/api.h" "TSQuantifier" #-}
+  TSQuantifier = TSQuantifier
+    { unTSQuantifier :: #{type TSQuantifier}
+    }
+    deriving (Eq, Show)
+    deriving newtype (Storable)
+
+pattern TSQuantifierZero :: TSQuantifier
+pattern TSQuantifierZero = TSQuantifier ( #{const TSQuantifierZero} )
+
+pattern TSQuantifierZeroOrOne :: TSQuantifier
+pattern TSQuantifierZeroOrOne = TSQuantifier ( #{const TSQuantifierZeroOrOne} )
+
+pattern TSQuantifierZeroOrMore :: TSQuantifier
+pattern TSQuantifierZeroOrMore = TSQuantifier ( #{const TSQuantifierZeroOrMore} )
+
+pattern TSQuantifierOne :: TSQuantifier
+pattern TSQuantifierOne = TSQuantifier ( #{const TSQuantifierOne} )
+
+pattern TSQuantifierOneOrMore :: TSQuantifier
+pattern TSQuantifierOneOrMore = TSQuantifier ( #{const TSQuantifierOneOrMore} )
+
+{-# COMPLETE TSQuantifierZero, TSQuantifierZeroOrOne, TSQuantifierZeroOrMore, TSQuantifierOne, TSQuantifierOneOrMore #-}
+
+{-|
+  > typedef struct TSQueryMatch {
+  >   uint32_t id;
+  >   uint16_t pattern_index;
+  >   uint16_t capture_count;
+  >   const TSQueryCapture *captures;
+  > } TSQueryMatch;
+  -}
+data
+  {-# CTYPE "tree_sitter/api.h" "struct TSQueryMatch" #-}
+  TSQueryMatch = TSQueryMatch
+  { _id :: {-# UNPACK #-} !( #{type uint32_t} )
+  , _pattern_index :: {-# UNPACK #-} !( #{type uint16_t} )
+  -- , _capture_count :: {-# UNPACK #-} !( #{type uint16_t} )
+  -- , _captures :: {-# UNPACK #-} !(Ptr TSQueryCapture)
+  , _captures :: ![TSQueryCapture]
+  }
+
+instance Storable TSQueryMatch where
+  alignment _ = #{alignment TSQueryMatch}
+  sizeOf _ = #{size TSQueryMatch}
+  peek ptr = do
+    _id <- #{peek TSQueryMatch, id} ptr
+    _pattern_index <- #{peek TSQueryMatch, pattern_index} ptr
+    _capture_count <- #{peek TSQueryMatch, capture_count} ptr
+    _captures <- peekTSQueryCapture _capture_count ( #{ptr TSQueryMatch, captures} ptr )
+    return TSQueryMatch{..}
+  poke ptr TSQueryMatch{..} = do
+    #{poke TSQueryMatch, id} ptr _id
+    #{poke TSQueryMatch, pattern_index} ptr _pattern_index
+    let _capture_count :: ( #{type uint16_t} )
+        _capture_count = fromIntegral $ length _captures
+    #{poke TSQueryMatch, capture_count} ptr _capture_count
+    pokeTSQueryCapture ( #{ptr TSQueryMatch, captures} ptr ) _captures
+
+{-| Peek an array of @`TSQueryCapture`@.
+
+    This does the same as `peekArray`.
+ -}
+peekTSQueryCapture ::
+  ( #{type uint16_t} ) ->
+  Ptr TSQueryCapture ->
+  IO [TSQueryCapture]
+peekTSQueryCapture capture_count ptr =
+  peekArray (fromIntegral capture_count) ptr
+
+{-| Poke an array of @`TSQueryCapture`@.
+
+    This does the same as `pokeArray`.
+ -}
+pokeTSQueryCapture ::
+  Ptr TSQueryCapture ->
+  [TSQueryCapture] ->
+  IO ()
+pokeTSQueryCapture ptr captures =
+  pokeArray ptr captures
+
+{-|
+  > typedef enum TSQueryPredicateStepType {
+  >   TSQueryPredicateStepTypeDone,
+  >   TSQueryPredicateStepTypeCapture,
+  >   TSQueryPredicateStepTypeString,
+  > } TSQueryPredicateStepType;
+  -}
+newtype
+  {-# CTYPE "tree_sitter/api.h" "TSQueryPredicateStepType" #-}
+  TSQueryPredicateStepType = TSQueryPredicateStepType
+    { unTSQueryPredicateStepType :: #{type TSQueryPredicateStepType}
+    }
+    deriving (Eq, Show)
+    deriving newtype (Storable)
+
+pattern TSQueryPredicateStepTypeDone :: TSQueryPredicateStepType
+pattern TSQueryPredicateStepTypeDone = TSQueryPredicateStepType ( #{const TSQueryPredicateStepTypeDone} )
+
+pattern TSQueryPredicateStepTypeCapture :: TSQueryPredicateStepType
+pattern TSQueryPredicateStepTypeCapture = TSQueryPredicateStepType ( #{const TSQueryPredicateStepTypeCapture} )
+
+pattern TSQueryPredicateStepTypeString :: TSQueryPredicateStepType
+pattern TSQueryPredicateStepTypeString = TSQueryPredicateStepType ( #{const TSQueryPredicateStepTypeString} )
+
+{-# COMPLETE TSQueryPredicateStepTypeDone, TSQueryPredicateStepTypeCapture, TSQueryPredicateStepTypeString #-}
+
+{-|
+ > typedef struct TSQueryPredicateStep {
+ >   TSQueryPredicateStepType type;
+ >   uint32_t value_id;
+ > } TSQueryPredicateStep;
+ -}
+data
+  {-# CTYPE "tree_sitter/api.h" "struct TSQueryPredicateStep" #-}
+  TSQueryPredicateStep = TSQueryPredicateStep
+    { _type :: {-# UNPACK #-} !TSQueryPredicateStepType
+    , _value_id :: {-# UNPACK #-} !( #{type uint32_t} )
+    }
+
+instance Storable TSQueryPredicateStep where
+  alignment _ = #{alignment TSQueryPredicateStep}
+  sizeOf _ = #{size TSQueryPredicateStep}
+  peek ptr = do
+    _type <- #{peek TSQueryPredicateStep, type} ptr
+    _value_id <- #{peek TSQueryPredicateStep, value_id} ptr
+    return TSQueryPredicateStep{..}
+  poke ptr TSQueryPredicateStep{..} = do
+    #{poke TSQueryPredicateStep, type} ptr _type
+    #{poke TSQueryPredicateStep, value_id} ptr _value_id
+
+{-|
+ > typedef enum TSQueryError {
+ >   TSQueryErrorNone = 0,
+ >   TSQueryErrorSyntax,
+ >   TSQueryErrorNodeType,
+ >   TSQueryErrorField,
+ >   TSQueryErrorCapture,
+ >   TSQueryErrorStructure,
+ >   TSQueryErrorLanguage,
+ > } TSQueryError;
+ -}
+newtype
+  {-# CTYPE "tree_sitter/api.h" "TSQueryError" #-}
+  TSQueryError = TSQueryError
+    { unTSQueryError :: #{type TSQueryError}
+    }
+    deriving (Eq, Show)
+    deriving newtype (Storable)
+
+pattern TSQueryErrorNone :: TSQueryError
+pattern TSQueryErrorNone = TSQueryError ( #{const TSQueryErrorNone} )
+
+pattern TSQueryErrorSyntax :: TSQueryError
+pattern TSQueryErrorSyntax = TSQueryError ( #{const TSQueryErrorSyntax} )
+
+pattern TSQueryErrorNodeType :: TSQueryError
+pattern TSQueryErrorNodeType = TSQueryError ( #{const TSQueryErrorNodeType} )
+
+pattern TSQueryErrorField :: TSQueryError
+pattern TSQueryErrorField = TSQueryError ( #{const TSQueryErrorField} )
+
+pattern TSQueryErrorCapture :: TSQueryError
+pattern TSQueryErrorCapture = TSQueryError ( #{const TSQueryErrorCapture} )
+
+pattern TSQueryErrorStructure :: TSQueryError
+pattern TSQueryErrorStructure = TSQueryError ( #{const TSQueryErrorStructure} )
+
+pattern TSQueryErrorLanguage :: TSQueryError
+pattern TSQueryErrorLanguage = TSQueryError ( #{const TSQueryErrorLanguage} )
+
+{-# COMPLETE TSQueryErrorNone, TSQueryErrorSyntax, TSQueryErrorNodeType, TSQueryErrorField, TSQueryErrorCapture, TSQueryErrorStructure, TSQueryErrorLanguage #-}
+
+{--------------------}
+{- Section - Parser -}
+{--------------------}
+
+{-|
+  Create a new parser.
+
+  > TSParser *ts_parser_new(void);
+-}
+foreign import capi unsafe "tree_sitter/api.h ts_parser_new"
+  ts_parser_new ::
+    IO (Ptr TSParser)
+
+{-|
+  Delete the parser, freeing all of the memory that it used.
+
+  > void ts_parser_delete(TSParser *self);
+-}
+foreign import capi unsafe "tree_sitter/api.h ts_parser_delete"
+  ts_parser_delete ::
+    Ptr TSParser ->
+    IO ()
+
+{-| C function pointer to @`ts_parser_delete`@.
+ -}
+foreign import capi unsafe "tree_sitter/api.h &ts_parser_delete"
+  p_ts_parser_delete ::
+    FunPtr (
+      Ptr TSParser ->
+      IO ()
+    )
+
+{-|
+  Get the parser's current language.
+
+  > const TSLanguage *ts_parser_language(const TSParser *self);
+-}
+foreign import capi unsafe "tree_sitter/api.h ts_parser_language"
+  ts_parser_language ::
+    ConstPtr TSParser ->
+    IO (ConstPtr TSLanguage)
+
+{-|
+  Set the language that the parser should use for parsing.
+
+  Returns a boolean indicating whether or not the language was successfully
+  assigned. True means assignment succeeded. False means there was a version
+  mismatch: the language was generated with an incompatible version of the
+  Tree-sitter CLI. Check the language's version using @`ts_language_version`@
+  and compare it to this library's @`TREE_SITTER_LANGUAGE_VERSION`@ and
+  @`TREE_SITTER_MIN_COMPATIBLE_LANGUAGE_VERSION`@ constants.
+
+  > bool ts_parser_set_language(TSParser *self, const TSLanguage *language);
+-}
+foreign import capi unsafe "tree_sitter/api.h ts_parser_set_language"
+  ts_parser_set_language ::
+    Ptr TSParser ->
+    ConstPtr TSLanguage ->
+    IO CBool
+
+{-|
+  Set the ranges of text that the parser should include when parsing.
+
+  By default, the parser will always include entire documents. This function
+  allows you to parse only a *portion* of a document but still return a syntax
+  tree whose ranges match up with the document as a whole. You can also pass
+  multiple disjoint ranges.
+
+  The second and third parameters specify the location and length of an array
+  of ranges. The parser does *not* take ownership of these ranges; it copies
+  the data, so it doesn't matter how these ranges are allocated.
+
+  If @count@ is zero, then the entire document will be parsed. Otherwise,
+  the given ranges must be ordered from earliest to latest in the document,
+  and they must not overlap. That is, the following must hold for all:
+
+  > i < count - 1: ranges[i].end_byte <= ranges[i + 1].start_byte
+
+  If this requirement is not satisfied, the operation will fail, the ranges
+  will not be assigned, and this function will return @`False`@. On success,
+  this function returns @`True`@.
+
+  > bool ts_parser_set_included_ranges(
+  >   TSParser *self,
+  >   const TSRange *ranges,
+  >   uint32_t count
+  > );
+-}
+foreign import capi unsafe "tree_sitter/api.h ts_parser_set_included_ranges"
+  ts_parser_set_included_ranges ::
+    Ptr TSParser ->
+    ConstPtr TSRange ->
+    ( #{type uint32_t} ) ->
+    IO CBool
+
+{-|
+  Get the ranges of text that the parser will include when parsing.
+
+  The returned pointer is owned by the parser. The caller should not free it
+  or write to it. The length of the array will be written to the given
+  @count@ pointer.
+
+  > const TSRange *ts_parser_included_ranges(
+  >   const TSParser *self,
+  >   uint32_t *count
+  > );
+-}
+foreign import capi unsafe "tree_sitter/api.h ts_parser_included_ranges"
+  ts_parser_included_ranges ::
+    ConstPtr TSParser ->
+    Ptr ( #{type uint32_t} ) ->
+    IO (ConstPtr TSRange)
+
+{-|
+  Use the parser to parse some source code and create a syntax tree.
+
+  If you are parsing this document for the first time, pass @NULL@ for the
+  @old_tree@ parameter. Otherwise, if you have already parsed an earlier
+  version of this document and the document has since been edited, pass the
+  previous syntax tree so that the unchanged parts of it can be reused.
+  This will save time and memory. For this to work correctly, you must have
+  already edited the old syntax tree using the @`ts_tree_edit`@ function in a
+  way that exactly matches the source code changes.
+
+  The @t`TSInput`@ parameter lets you specify how to read the text. It has the
+  following three fields:
+
+  1. @read@: A function to retrieve a chunk of text at a given byte offset
+     and (row, column) position. The function should return a pointer to the
+     text and write its length to the @bytes_read@ pointer. The parser does
+     not take ownership of this buffer; it just borrows it until it has
+     finished reading it. The function should write a zero value to the
+     @bytes_read@ pointer to indicate the end of the document.
+  2. @payload@: An arbitrary pointer that will be passed to each invocation
+     of the @read@ function.
+  3. @encoding@: An indication of how the text is encoded. Either
+     @TSInputEncodingUTF8@ or @TSInputEncodingUTF16@.
+
+  This function returns a syntax tree on success, and @NULL@ on failure. There
+  are three possible reasons for failure:
+
+  1. The parser does not have a language assigned. Check for this using the
+      @`ts_parser_language`@ function.
+  2. Parsing was cancelled due to a timeout that was set by an earlier call to
+     the @`ts_parser_set_timeout_micros`@ function. You can resume parsing from
+     where the parser left out by calling @`ts_parser_parse`@ again with the
+     same arguments. Or you can start parsing from scratch by first calling
+     @`ts_parser_reset`@.
+  3. Parsing was cancelled using a cancellation flag that was set by an
+     earlier call to @`ts_parser_set_cancellation_flag`@. You can resume parsing
+     from where the parser left out by calling @`ts_parser_parse`@ again with
+     the same arguments.
+
+  > TSTree *ts_parser_parse(
+  >   TSParser *self,
+  >   const TSTree *old_tree,
+  >   TSInput input
+  > );
+-}
+ts_parser_parse ::
+  Ptr TSParser ->
+  ConstPtr TSTree ->
+  TSRead ->
+  TSInputEncoding ->
+  IO (Ptr TSTree)
+ts_parser_parse = \self old_tree readFun encoding ->
+  bracket (mkTSReadFunPtr readFun) freeHaskellFunPtr $ \readFun_p ->
+    bracket (_wrap_ts_input_new readFun_p encoding) _wrap_ts_input_delete $ \input_p ->
+      _wrap_ts_parser_parse self old_tree input_p
+
+foreign import capi safe "TreeSitter/CApi_hsc.h _wrap_ts_parser_parse"
+  _wrap_ts_parser_parse ::
+    Ptr TSParser ->
+    ConstPtr TSTree ->
+    Ptr TSInput ->
+    IO (Ptr TSTree)
+
+#{def
+  TSTree *_wrap_ts_parser_parse(
+    TSParser *self,
+    const TSTree *old_tree,
+    TSInput *input
+  )
+  {
+    return ts_parser_parse(self, old_tree, *input);
+  }
+}
+
+{-|
+  Use the parser to parse some source code stored in one contiguous buffer.
+  The first two parameters are the same as in the @`ts_parser_parse`@ function
+  above. The second two parameters indicate the location of the buffer and its
+  length in bytes.
+
+  > TSTree *ts_parser_parse_string(
+  >   TSParser *self,
+  >   const TSTree *old_tree,
+  >   const char *string,
+  >   uint32_t length
+  > );
+-}
+foreign import capi safe "tree_sitter/api.h ts_parser_parse_string"
+  ts_parser_parse_string ::
+    Ptr TSParser ->
+    ConstPtr TSTree ->
+    ConstPtr CChar ->
+    ( #{type uint32_t} ) ->
+    IO (Ptr TSTree)
+
+{-|
+  Use the parser to parse some source code stored in one contiguous buffer with
+  a given encoding. The first four parameters work the same as in the
+  @`ts_parser_parse_string`@ method above. The final parameter indicates whether
+  the text is encoded as UTF8 or UTF16.
+
+  > TSTree *ts_parser_parse_string_encoding(
+  >   TSParser *self,
+  >   const TSTree *old_tree,
+  >   const char *string,
+  >   uint32_t length,
+  >   TSInputEncoding encoding
+  > );
+-}
+foreign import capi safe "tree_sitter/api.h ts_parser_parse_string_encoding"
+  ts_parser_parse_string_encoding ::
+    Ptr TSParser ->
+    ConstPtr TSTree ->
+    ConstPtr CChar ->
+    ( #{type uint32_t} ) ->
+    TSInputEncoding ->
+    IO (Ptr TSTree)
+
+{-|
+  Instruct the parser to start the next parse from the beginning.
+
+  If the parser previously failed because of a timeout or a cancellation, then
+  by default, it will resume where it left off on the next call to
+  @`ts_parser_parse`@ or other parsing functions. If you don't want to resume,
+  and instead intend to use this parser to parse some other document, you must
+  call @`ts_parser_reset`@ first.
+
+  > void ts_parser_reset(TSParser *self);
+-}
+foreign import capi unsafe "tree_sitter/api.h ts_parser_reset"
+  ts_parser_reset ::
+    Ptr TSParser ->
+    IO ()
+
+{-|
+  Set the maximum duration in microseconds that parsing should be allowed to
+  take before halting.
+
+  If parsing takes longer than this, it will halt early, returning @NULL@.
+  See @`ts_parser_parse`@ for more information.
+
+  > void ts_parser_set_timeout_micros(TSParser *self, uint64_t timeout_micros);
+-}
+foreign import capi unsafe "tree_sitter/api.h ts_parser_set_timeout_micros"
+  ts_parser_set_timeout_micros ::
+    Ptr TSParser ->
+    ( #{type uint64_t} ) ->
+    IO ()
+
+{-|
+  Get the duration in microseconds that parsing is allowed to take.
+
+  > uint64_t ts_parser_timeout_micros(const TSParser *self);
+-}
+foreign import capi unsafe "tree_sitter/api.h ts_parser_timeout_micros"
+  ts_parser_timeout_micros ::
+    Ptr TSParser ->
+    IO ( #{type uint64_t} )
+
+{-|
+  Set the parser's current cancellation flag pointer.
+
+  If a non-null pointer is assigned, then the parser will periodically read
+  from this pointer during parsing. If it reads a non-zero value, it will
+  halt early, returning @NULL@. See @`ts_parser_parse`@ for more information.
+
+  > void ts_parser_set_cancellation_flag(TSParser *self, const size_t *flag);
+-}
+foreign import capi unsafe "tree_sitter/api.h ts_parser_set_cancellation_flag"
+  ts_parser_set_cancellation_flag ::
+    Ptr TSParser ->
+    ConstPtr CSize ->
+    IO ()
+
+{-|
+  Get the parser's current cancellation flag pointer.
+
+  > const size_t *ts_parser_cancellation_flag(const TSParser *self);
+-}
+foreign import capi unsafe "tree_sitter/api.h ts_parser_cancellation_flag"
+  ts_parser_cancellation_flag ::
+    ConstPtr TSParser ->
+    IO (ConstPtr CSize)
+
+{-|
+  Set the logger that a parser should use during parsing.
+
+  The parser does not take ownership over the logger payload. If a logger was
+  previously assigned, the caller is responsible for releasing any memory
+  owned by the previous logger.
+
+  > void ts_parser_set_logger(TSParser *self, TSLogger logger);
+-}
+ts_parser_set_logger ::
+  Ptr TSParser ->
+  TSLog ->
+  IO ()
+ts_parser_set_logger = \self logFun -> mask_ $ do
+  logFun_p <- mkTSLogFunPtr logFun
+  logger_p <- _wrap_ts_logger_new logFun_p
+  _wrap_ts_parser_set_logger self logger_p
+
+#{def
+  void _wrap_ts_parser_set_logger(
+    TSParser *self,
+    TSLogger *logger
+  )
+  {
+    ts_parser_set_logger(self, *logger);
+  }
+}
+
+foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_parser_set_logger"
+  _wrap_ts_parser_set_logger ::
+    Ptr TSParser ->
+    Ptr TSLogger ->
+    IO ()
+
+{-|
+  Get the parser's current logger.
+
+  > TSLogger ts_parser_logger(const TSParser *self);
+-}
+ts_parser_logger ::
+  ConstPtr TSParser ->
+  IO (Maybe TSLog)
+ts_parser_logger = \self -> do
+  logFun_p <- _wrap_ts_parser_logger self
+  pure $
+    if logFun_p /= nullFunPtr
+      then Just $ unTSLogFunPtr logFun_p
+      else Nothing
+{-# INLINE ts_parser_logger #-}
+
+foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_parser_logger"
+  _wrap_ts_parser_logger ::
+    ConstPtr TSParser ->
+    IO (FunPtr TSLog)
+
+#{def
+  TSLog _wrap_ts_parser_logger(
+    const TSParser *self
+  )
+  {
+    // Get the current logger
+    TSLogger logger = ts_parser_logger(self);
+    // Copy the payload into the log function
+    if(logger.payload) {
+      TSLog log;
+      memcpy(&log, logger.payload, sizeof log);
+      return log;
+    }
+    return NULL;
+  }
+}
+
+{-|
+  Remove the parser's current logger.
+-}
+ts_parser_remove_logger ::
+  Ptr TSParser ->
+  IO (Maybe TSLog)
+ts_parser_remove_logger = \self -> mask_ $ do
+  logFun_p <- _wrap_ts_parser_remove_logger self
+  if logFun_p == nullFunPtr
+    then pure Nothing
+    else do
+      let logFun = unTSLogFunPtr logFun_p
+      freeHaskellFunPtr logFun_p
+      pure $ Just logFun
+
+foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_parser_remove_logger"
+  _wrap_ts_parser_remove_logger ::
+    Ptr TSParser ->
+    IO (FunPtr TSLog)
+
+#{def
+  TSLog _wrap_ts_parser_remove_logger(
+    TSParser *self
+  )
+  {
+    // Get the current logger
+    TSLogger logger = ts_parser_logger(self);
+    // Set the parser's logger to NULL
+    TSLogger logger_null = {NULL, NULL};
+    ts_parser_set_logger(self, logger_null);
+    // Copy the payload into the log function
+    if (logger.payload) {
+      TSLog log;
+      memcpy(&log, logger.payload, sizeof log);
+      free(logger.payload);
+      return log;
+    }
+    return NULL;
+  }
+}
+
+{-|
+  Set the file descriptor to which the parser should write debugging graphs
+  during parsing. The graphs are formatted in the DOT language. You may want
+  to pipe these graphs directly to a `dot(1)` process in order to generate
+  SVG output. You can turn off this logging by passing a negative number.
+
+  > void ts_parser_print_dot_graphs(TSParser *self, int fd);
+-}
+foreign import capi unsafe "tree_sitter/api.h ts_parser_print_dot_graphs"
+  ts_parser_print_dot_graphs ::
+    Ptr TSParser ->
+    ( #{type int} ) ->
+    IO ()
+
+{------------------}
+{- Section - Tree -}
+{------------------}
+
+{-|
+  Create a shallow copy of the syntax tree. This is very fast.
+
+  You need to copy a syntax tree in order to use it on more than one thread at
+  a time, as syntax trees are not thread safe.
+
+  > TSTree *ts_tree_copy(const TSTree *self);
+-}
+foreign import capi unsafe "tree_sitter/api.h ts_tree_copy"
+  ts_tree_copy ::
+    Ptr TSTree ->
+    IO (Ptr TSTree)
+
+{-|
+  Delete the syntax tree, freeing all of the memory that it used.
+
+  > void ts_tree_delete(TSTree *self);
+-}
+foreign import capi unsafe "tree_sitter/api.h ts_tree_delete"
+  ts_tree_delete ::
+    Ptr TSTree ->
+    IO ()
+
+{-| C function pointer to @`ts_tree_delete`@.
+ -}
+foreign import capi unsafe "tree_sitter/api.h &ts_tree_delete"
+  p_ts_tree_delete ::
+    FunPtr (
+      Ptr TSTree ->
+      IO ()
+    )
+
+{-|
+  Get the root node of the syntax tree.
+
+  > TSNode ts_tree_root_node(const TSTree *self);
+-}
+ts_tree_root_node ::
+  ConstPtr TSTree ->
+  IO TSNode
+ts_tree_root_node = \self ->
+  alloca $ \result_p -> do
+    _wrap_ts_tree_root_node self result_p
+    peek result_p
+{-# INLINE ts_tree_root_node #-}
+
+#{def
+  void _wrap_ts_tree_root_node(
+    const TSTree *self,
+    TSNode *result
+  )
+  {
+    *result = ts_tree_root_node(self);
+  }
+}
+
+foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_tree_root_node"
+  _wrap_ts_tree_root_node ::
+    ConstPtr TSTree ->
+    Ptr TSNode ->
+    IO ()
+
+{-|
+  Get the root node of the syntax tree, but with its position
+  shifted forward by the given offset.
+
+  > TSNode ts_tree_root_node_with_offset(
+  >   const TSTree *self,
+  >   uint32_t offset_bytes,
+  >   TSPoint offset_extent
+  > );
+-}
+ts_tree_root_node_with_offset ::
+  ConstPtr TSTree ->
+  ( #{type uint32_t} ) ->
+  TSPoint ->
+  IO TSNode
+ts_tree_root_node_with_offset = \self offset_bytes offset_extent ->
+  alloca $ \result_p -> do
+    with offset_extent $ \offset_extent_p ->
+      _wrap_ts_tree_root_node_with_offset self offset_bytes offset_extent_p result_p
+    peek result_p
+{-# INLINE ts_tree_root_node_with_offset #-}
+
+#{def
+  void _wrap_ts_tree_root_node_with_offset(
+    const TSTree *self,
+    uint32_t offset_bytes,
+    TSPoint *offset_extent,
+    TSNode *result
+  )
+  {
+    *result = ts_tree_root_node_with_offset(self, offset_bytes, *offset_extent);
+  }
+}
+
+foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_tree_root_node_with_offset"
+  _wrap_ts_tree_root_node_with_offset ::
+    ConstPtr TSTree ->
+    ( #{type uint32_t } ) ->
+    Ptr TSPoint ->
+    Ptr TSNode ->
+    IO ()
+
+{-|
+  Get the language that was used to parse the syntax tree.
+
+  > const TSLanguage *ts_tree_language(const TSTree *self);
+-}
+foreign import capi unsafe "tree_sitter/api.h ts_tree_language"
+  ts_tree_language ::
+    Ptr TSTree ->
+    IO (ConstPtr TSLanguage)
+
+{-|
+  Get the array of included ranges that was used to parse the syntax tree.
+
+  The returned pointer must be freed by the caller.
+
+  > TSRange *ts_tree_included_ranges(const TSTree *self, uint32_t *length);
+-}
+foreign import capi unsafe "tree_sitter/api.h ts_tree_included_ranges"
+  ts_tree_included_ranges ::
+    Ptr TSTree ->
+    Ptr ( #{type uint32_t} ) ->
+    IO ( Ptr TSRange )
+
+{-|
+  Edit the syntax tree to keep it in sync with source code that has been
+  edited.
+
+  You must describe the edit both in terms of byte offsets and in terms of
+  (row, column) coordinates.
+
+  > void ts_tree_edit(TSTree *self, const TSInputEdit *edit);
+-}
+foreign import capi unsafe "tree_sitter/api.h ts_tree_edit"
+  ts_tree_edit ::
+    Ptr TSTree ->
+    Ptr TSInputEdit ->
+    IO ()
+
+{-|
+  Compare an old edited syntax tree to a new syntax tree representing the same
+  document, returning an array of ranges whose syntactic structure has changed.
+
+  For this to work correctly, the old syntax tree must have been edited such
+  that its ranges match up to the new tree. Generally, you'll want to call
+  this function right after calling one of the @`ts_parser_parse`@ functions.
+  You need to pass the old tree that was passed to parse, as well as the new
+  tree that was returned from that function.
+
+  The returned array is allocated using @malloc@ and the caller is responsible
+  for freeing it using @free@. The length of the array will be written to the
+  given @length@ pointer.
+
+  > TSRange *ts_tree_get_changed_ranges(
+  >   const TSTree *old_tree,
+  >   const TSTree *new_tree,
+  >   uint32_t *length
+  > );
+-}
+foreign import capi unsafe "tree_sitter/api.h ts_tree_get_changed_ranges"
+  ts_tree_get_changed_ranges ::
+    Ptr TSTree ->
+    Ptr TSTree ->
+    Ptr ( #{type uint32_t} ) ->
+    IO ( Ptr TSRange )
+
+{-|
+  Write a DOT graph describing the syntax tree to the given file.
+
+  > void ts_tree_print_dot_graph(const TSTree *self, int file_descriptor);
+-}
+foreign import capi unsafe "tree_sitter/api.h ts_tree_print_dot_graph"
+  ts_tree_print_dot_graph ::
+    Ptr TSTree ->
+    ( #{type int} ) ->
+    IO ()
+
+{------------------}
+{- Section - Node -}
+{------------------}
+
+{-|
+  Get the node's type as a null-terminated string.
+
+  > const char *ts_node_type(TSNode self);
+-}
+ts_node_type ::
+  TSNode ->
+  IO (ConstPtr CChar)
+ts_node_type = \self ->
+  with self $ \self_p ->
+    _wrap_ts_node_type self_p
+{-# INLINE ts_node_type #-}
+
+#{def
+  const char *_wrap_ts_node_type(TSNode *self)
+  {
+    return ts_node_type(*self);
+  }
+}
+
+foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_node_type"
+  _wrap_ts_node_type ::
+    Ptr TSNode ->
+    IO (ConstPtr CChar)
+
+{-|
+  Get the node's type as a numerical id.
+
+  > TSSymbol ts_node_symbol(TSNode self);
+-}
+ts_node_symbol ::
+  TSNode ->
+  IO TSSymbol
+ts_node_symbol = \self ->
+  with self $ \self_p ->
+    _wrap_ts_node_symbol self_p
+{-# INLINE ts_node_symbol #-}
+
+#{def
+  TSSymbol _wrap_ts_node_symbol(TSNode *self)
+  {
+    return ts_node_symbol(*self);
+  }
+}
+
+foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_node_symbol"
+  _wrap_ts_node_symbol ::
+    Ptr TSNode ->
+    IO TSSymbol
+
+{-|
+  Get the node's language.
+
+  > const TSLanguage *ts_node_language(TSNode self);
+-}
+ts_node_language ::
+  TSNode ->
+  IO (ConstPtr TSLanguage)
+ts_node_language = \self ->
+  with self $ \self_p ->
+    _wrap_ts_node_language self_p
+{-# INLINE ts_node_language #-}
+
+#{def
+  const TSLanguage *_wrap_ts_node_language(TSNode *self)
+  {
+    return ts_node_language(*self);
+  }
+}
+
+foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_node_language"
+  _wrap_ts_node_language ::
+    Ptr TSNode ->
+    IO (ConstPtr TSLanguage)
+
+{-|
+  Get the node's type as it appears in the grammar ignoring aliases as a
+  null-terminated string.
+
+  > const char *ts_node_grammar_type(TSNode self);
+-}
+ts_node_grammar_type ::
+  TSNode ->
+  IO (ConstPtr CChar)
+ts_node_grammar_type = \self ->
+  with self $ \self_p ->
+    _wrap_ts_node_grammar_type self_p
+{-# INLINE ts_node_grammar_type #-}
+
+#{def
+  const char *_wrap_ts_node_grammar_type(TSNode *self)
+  {
+    return ts_node_grammar_type(*self);
+  }
+}
+
+foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_node_grammar_type"
+  _wrap_ts_node_grammar_type ::
+    Ptr TSNode ->
+    IO (ConstPtr CChar)
+
+{-|
+  Get the node's type as a numerical id as it appears in the grammar ignoring
+  aliases. This should be used in @`ts_language_next_state`@ instead of
+  @`ts_node_symbol`@.
+
+  > TSSymbol ts_node_grammar_symbol(TSNode self);
+-}
+ts_node_grammar_symbol ::
+  TSNode ->
+  IO TSSymbol
+ts_node_grammar_symbol = \self ->
+  with self $ \self_p ->
+    _wrap_ts_node_grammar_symbol self_p
+{-# INLINE ts_node_grammar_symbol #-}
+
+#{def
+  TSSymbol _wrap_ts_node_grammar_symbol(TSNode *self)
+  {
+    return ts_node_grammar_symbol(*self);
+  }
+}
+
+foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_node_grammar_symbol"
+  _wrap_ts_node_grammar_symbol ::
+    Ptr TSNode ->
+    IO TSSymbol
+
+{-|
+  Get the node's start byte.
+
+  > uint32_t ts_node_start_byte(TSNode self);
+-}
+ts_node_start_byte ::
+  TSNode ->
+  IO ( #{type uint32_t} )
+ts_node_start_byte = \self ->
+  with self $ \self_p ->
+    _wrap_ts_node_start_byte self_p
+{-# INLINE ts_node_start_byte #-}
+
+#{def
+  uint32_t _wrap_ts_node_start_byte(TSNode *self)
+  {
+    return ts_node_start_byte(*self);
+  }
+}
+
+foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_node_start_byte"
+  _wrap_ts_node_start_byte ::
+    Ptr TSNode ->
+    IO ( #{type uint32_t} )
+
+{-|
+  Get the node's start position in terms of rows and columns.
+
+  > TSPoint ts_node_start_point(TSNode self);
+-}
+ts_node_start_point ::
+  TSNode ->
+  IO TSPoint
+ts_node_start_point = \self ->
+  alloca $ \result_p -> do
+    with self $ \self_p ->
+      _wrap_ts_node_start_point self_p result_p
+    peek result_p
+{-# INLINE ts_node_start_point #-}
+
+#{def
+  void _wrap_ts_node_start_point(TSNode *self, TSPoint *result)
+  {
+    *result = ts_node_start_point(*self);
+  }
+}
+
+foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_node_start_point"
+  _wrap_ts_node_start_point ::
+    Ptr TSNode ->
+    Ptr TSPoint ->
+    IO ()
+
+{-|
+  Get the node's end byte.
+
+  > uint32_t ts_node_end_byte(TSNode self);
+-}
+ts_node_end_byte ::
+  TSNode ->
+  IO ( #{type uint32_t} )
+ts_node_end_byte = \self ->
+  with self $ \self_p ->
+    _wrap_ts_node_end_byte self_p
+{-# INLINE ts_node_end_byte #-}
+
+#{def
+  uint32_t _wrap_ts_node_end_byte(TSNode *self)
+  {
+    return ts_node_end_byte(*self);
+  }
+}
+
+foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_node_end_byte"
+  _wrap_ts_node_end_byte ::
+    Ptr TSNode ->
+    IO ( #{type uint32_t} )
+
+{-|
+  Get the node's end position in terms of rows and columns.
+
+  > TSPoint ts_node_end_point(TSNode self);
+-}
+ts_node_end_point ::
+  TSNode ->
+  IO TSPoint
+ts_node_end_point = \self ->
+  alloca $ \result_p -> do
+    with self $ \self_p ->
+      _wrap_ts_node_end_point self_p result_p
+    peek result_p
+{-# INLINE ts_node_end_point #-}
+
+#{def
+  void _wrap_ts_node_end_point(TSNode *self, TSPoint *result)
+  {
+    *result = ts_node_end_point(*self);
+  }
+}
+
+foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_node_end_point"
+  _wrap_ts_node_end_point ::
+    Ptr TSNode ->
+    Ptr TSPoint ->
+    IO ()
+
+{-|
+  Get an S-expression representing the node as a string.
+
+  This string is allocated with @malloc@ and the caller is responsible for
+  freeing it using @free@.
+
+  > char *ts_node_string(TSNode self);
+-}
+ts_node_string ::
+  TSNode ->
+  IO (Ptr CChar)
+ts_node_string = \self ->
+  with self $ \self_p ->
+    _wrap_ts_node_string self_p
+{-# INLINE ts_node_string #-}
+
+#{def
+  char *_wrap_ts_node_string(TSNode *self)
+  {
+    return ts_node_string(*self);
+  }
+}
+
+foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_node_string"
+  _wrap_ts_node_string ::
+    Ptr TSNode ->
+    IO (Ptr CChar)
+
+{-|
+  Check if the node is null. Functions like @`ts_node_child`@ and
+  @`ts_node_next_sibling`@ will return a null node to indicate that no such node
+  was found.
+
+  > bool ts_node_is_null(TSNode self);
+-}
+ts_node_is_null ::
+  TSNode ->
+  IO CBool
+ts_node_is_null = \self ->
+  with self $ \self_p ->
+    _wrap_ts_node_is_null self_p
+{-# INLINE ts_node_is_null #-}
+
+#{def
+  bool _wrap_ts_node_is_null(TSNode *self)
+  {
+    return ts_node_is_null(*self);
+  }
+}
+
+foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_node_is_null"
+  _wrap_ts_node_is_null ::
+    Ptr TSNode ->
+    IO CBool
+
+{-|
+  Check if the node is *named*. Named nodes correspond to named rules in the
+  grammar, whereas *anonymous* nodes correspond to string literals in the
+  grammar.
+
+  > bool ts_node_is_named(TSNode self);
+-}
+ts_node_is_named ::
+  TSNode ->
+  IO CBool
+ts_node_is_named = \self ->
+  with self $ \self_p ->
+    _wrap_ts_node_is_named self_p
+{-# INLINE ts_node_is_named #-}
+
+#{def
+  bool _wrap_ts_node_is_named(TSNode *self)
+  {
+    return ts_node_is_named(*self);
+  }
+}
+
+foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_node_is_named"
+  _wrap_ts_node_is_named ::
+    Ptr TSNode ->
+    IO CBool
+
+{-|
+  Check if the node is *missing*. Missing nodes are inserted by the parser in
+  order to recover from certain kinds of syntax errors.
+
+  > bool ts_node_is_missing(TSNode self);
+-}
+ts_node_is_missing ::
+  TSNode ->
+  IO CBool
+ts_node_is_missing = \self ->
+  with self $ \self_p ->
+    _wrap_ts_node_is_missing self_p
+{-# INLINE ts_node_is_missing #-}
+
+#{def
+  bool _wrap_ts_node_is_missing(TSNode *self)
+  {
+    return ts_node_is_missing(*self);
+  }
+}
+
+foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_node_is_missing"
+  _wrap_ts_node_is_missing ::
+    Ptr TSNode ->
+    IO CBool
+
+{-|
+  Check if the node is *extra*. Extra nodes represent things like comments,
+  which are not required the grammar, but can appear anywhere.
+
+  > bool ts_node_is_extra(TSNode self);
+-}
+ts_node_is_extra ::
+  TSNode ->
+  IO CBool
+ts_node_is_extra = \self ->
+  with self $ \self_p ->
+    _wrap_ts_node_is_extra self_p
+{-# INLINE ts_node_is_extra #-}
+
+#{def
+  bool _wrap_ts_node_is_extra(TSNode *self)
+  {
+    return ts_node_is_extra(*self);
+  }
+}
+
+foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_node_is_extra"
+  _wrap_ts_node_is_extra ::
+    Ptr TSNode ->
+    IO CBool
+
+{-|
+  Check if a syntax node has been edited.
+
+  > bool ts_node_has_changes(TSNode self);
+-}
+ts_node_has_changes ::
+  TSNode ->
+  IO CBool
+ts_node_has_changes = \self ->
+  with self $ \self_p ->
+    _wrap_ts_node_has_changes self_p
+{-# INLINE ts_node_has_changes #-}
+
+#{def
+  bool _wrap_ts_node_has_changes(TSNode *self)
+  {
+    return ts_node_has_changes(*self);
+  }
+}
+
+foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_node_has_changes"
+  _wrap_ts_node_has_changes ::
+    Ptr TSNode ->
+    IO CBool
+
+{-|
+  Check if the node is a syntax error or contains any syntax errors.
+
+  > bool ts_node_has_error(TSNode self);
+-}
+ts_node_has_error ::
+  TSNode ->
+  IO CBool
+ts_node_has_error = \self ->
+  with self $ \self_p ->
+    _wrap_ts_node_has_error self_p
+{-# INLINE ts_node_has_error #-}
+
+#{def
+  bool _wrap_ts_node_has_error(TSNode *self)
+  {
+    return ts_node_has_error(*self);
+  }
+}
+
+foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_node_has_error"
+  _wrap_ts_node_has_error ::
+    Ptr TSNode ->
+    IO CBool
+
+{-|
+  Check if the node is a syntax error.
+
+  > bool ts_node_is_error (TSNode self)
+-}
+ts_node_is_error ::
+  TSNode ->
+  IO CBool
+ts_node_is_error = \self ->
+  with self $ \self_p ->
+    _wrap_ts_node_is_error self_p
+{-# INLINE ts_node_is_error #-}
+
+#{def
+  bool _wrap_ts_node_is_error(TSNode *self)
+  {
+    return ts_node_is_error(*self);
+  }
+}
+
+foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_node_is_error"
+  _wrap_ts_node_is_error ::
+    Ptr TSNode ->
+    IO CBool
+
+{-|
+  Get this node's parse state.
+
+  > TSStateId ts_node_parse_state (TSNode self)
+-}
+ts_node_parse_state ::
+  TSNode ->
+  IO TSStateId
+ts_node_parse_state = \self ->
+  with self $ \self_p ->
+    _wrap_ts_node_parse_state self_p
+{-# INLINE ts_node_parse_state #-}
+
+#{def
+  TSStateId _wrap_ts_node_parse_state(TSNode *self)
+  {
+    return ts_node_parse_state(*self);
+  }
+}
+
+foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_node_parse_state"
+  _wrap_ts_node_parse_state ::
+    Ptr TSNode ->
+    IO TSStateId
+
+{-|
+  Get the parse state after this node.
+
+  > TSStateId ts_node_next_parse_state (TSNode self)
+-}
+ts_node_next_parse_state ::
+  TSNode ->
+  IO TSStateId
+ts_node_next_parse_state = \self ->
+  with self $ \self_p ->
+    _wrap_ts_node_next_parse_state self_p
+{-# INLINE ts_node_next_parse_state #-}
+
+#{def
+  TSStateId _wrap_ts_node_next_parse_state(TSNode *self)
+  {
+    return ts_node_next_parse_state(*self);
+  }
+}
+
+foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_node_next_parse_state"
+  _wrap_ts_node_next_parse_state ::
+    Ptr TSNode ->
+    IO TSStateId
+
+{-|
+  Get the node's immediate parent.
+
+  > TSNode ts_node_parent(TSNode self);
+-}
+ts_node_parent ::
+  TSNode ->
+  IO TSNode
+ts_node_parent = \self ->
+  alloca $ \result_p -> do
+    with self $ \self_p ->
+      _wrap_ts_node_parent self_p result_p
+    peek result_p
+{-# INLINE ts_node_parent #-}
+
+#{def
+  void _wrap_ts_node_parent(TSNode *self, TSNode *result)
+  {
+    *result = ts_node_parent(*self);
+  }
+}
+
+foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_node_parent"
+  _wrap_ts_node_parent ::
+    Ptr TSNode ->
+    Ptr TSNode ->
+    IO ()
+
+{-|
+  Get the node that contains @descendant@.
+
+  Note that this can return @descendant@ itself.
+
+  > TSNode ts_node_child_with_descendant(TSNode self, TSNode descendant);
+-}
+ts_node_child_with_descendant ::
+  TSNode ->
+  TSNode ->
+  IO TSNode
+ts_node_child_with_descendant = \self descendant ->
+  alloca $ \result_p -> do
+    with self $ \self_p ->
+      with descendant $ \descendant_p ->
+        _wrap_ts_node_child_with_descendant self_p descendant_p result_p
+    peek result_p
+{-# INLINE ts_node_child_with_descendant #-}
+
+#{def
+  void _wrap_ts_node_child_with_descendant(TSNode *self, TSNode *descendant, TSNode *result)
+  {
+    *result = ts_node_child_with_descendant(*self, *descendant);
+  }
+}
+
+foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_node_child_with_descendant"
+  _wrap_ts_node_child_with_descendant ::
+    Ptr TSNode ->
+    Ptr TSNode ->
+    Ptr TSNode ->
+    IO ()
+
+{-|
+  Get the node's child at the given index, where zero represents the first
+  child.
+
+  > TSNode ts_node_child(TSNode self, uint32_t child_index);
+-}
+ts_node_child ::
+  TSNode ->
+  ( #{type uint32_t} ) ->
+  IO TSNode
+ts_node_child = \self child_index ->
+  alloca $ \result_p -> do
+    with self $ \self_p ->
+      _wrap_ts_node_child self_p child_index result_p
+    peek result_p
+{-# INLINE ts_node_child #-}
+
+#{def
+  void _wrap_ts_node_child(TSNode *self, uint32_t child_index, TSNode *result)
+  {
+    *result = ts_node_child(*self, child_index);
+  }
+}
+
+foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_node_child"
+  _wrap_ts_node_child ::
+    Ptr TSNode ->
+    ( #{type uint32_t} ) ->
+    Ptr TSNode ->
+    IO ()
+
+{-|
+  Get the field name for node's child at the given index, where zero represents
+  the first child. Returns @NULL@ if no field is found.
+
+  > const char *ts_node_field_name_for_child(TSNode self, uint32_t child_index);
+-}
+ts_node_field_name_for_child ::
+  TSNode ->
+  ( #{type uint32_t} ) ->
+  IO (ConstPtr CChar)
+ts_node_field_name_for_child = \self child_index ->
+  with self $ \self_p ->
+    _wrap_ts_node_field_name_for_child self_p child_index
+{-# INLINE ts_node_field_name_for_child #-}
+
+#{def
+  const char *_wrap_ts_node_field_name_for_child(TSNode *self, uint32_t child_index)
+  {
+    return ts_node_field_name_for_child(*self, child_index);
+  }
+}
+
+foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_node_field_name_for_child"
+  _wrap_ts_node_field_name_for_child ::
+    Ptr TSNode ->
+    ( #{type uint32_t} ) ->
+    IO (ConstPtr CChar)
+
+{-|
+  Get the field name for node's named child at the given index, where zero
+  represents the first named child. Returns @NULL@, if no field is found.
+
+  > const char *ts_node_field_name_for_named_child(TSNode self, uint32_t named_child_index);
+-}
+ts_node_field_name_for_named_child ::
+  TSNode ->
+  ( #{type uint32_t} ) ->
+  IO (ConstPtr CChar)
+ts_node_field_name_for_named_child = \self child_index ->
+  with self $ \self_p ->
+    _wrap_ts_node_field_name_for_named_child self_p child_index
+{-# INLINE ts_node_field_name_for_named_child #-}
+
+#{def
+  const char *_wrap_ts_node_field_name_for_named_child(TSNode *self, uint32_t child_index)
+  {
+    return ts_node_field_name_for_named_child(*self, child_index);
+  }
+}
+
+foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_node_field_name_for_named_child"
+  _wrap_ts_node_field_name_for_named_child ::
+    Ptr TSNode ->
+    ( #{type uint32_t} ) ->
+    IO (ConstPtr CChar)
+
+{-|
+  Get the node's number of children.
+
+  > uint32_t ts_node_child_count(TSNode self);
+-}
+ts_node_child_count ::
+  TSNode ->
+  IO ( #{type uint32_t} )
+ts_node_child_count = \self ->
+  with self $ \self_p ->
+    _wrap_ts_node_child_count self_p
+{-# INLINE ts_node_child_count #-}
+
+#{def
+  uint32_t _wrap_ts_node_child_count(TSNode *self)
+  {
+    return ts_node_child_count(*self);
+  }
+}
+
+foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_node_child_count"
+  _wrap_ts_node_child_count ::
+    Ptr TSNode ->
+    IO ( #{type uint32_t} )
+
+{-|
+  Get the node's *named* child at the given index.
+
+  See also @`ts_node_is_named`@.
+
+  > TSNode ts_node_named_child(TSNode self, uint32_t child_index);
+-}
+ts_node_named_child ::
+  TSNode ->
+  #{type uint32_t} ->
+  IO TSNode
+ts_node_named_child = \self child_index ->
+  alloca $ \result_p -> do
+    with self $ \self_p ->
+      _wrap_ts_node_named_child self_p child_index result_p
+    peek result_p
+{-# INLINE ts_node_named_child #-}
+
+#{def
+  void _wrap_ts_node_named_child(TSNode *self, uint32_t child_index, TSNode *result)
+  {
+    *result = ts_node_named_child(*self, child_index);
+  }
+}
+
+foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_node_named_child"
+  _wrap_ts_node_named_child ::
+    Ptr TSNode ->
+    ( #{type uint32_t} ) ->
+    Ptr TSNode ->
+    IO ()
+
+{-|
+  Get the node's number of *named* children.
+
+  See also @`ts_node_is_named`@.
+
+  > uint32_t ts_node_named_child_count(TSNode self);
+-}
+ts_node_named_child_count ::
+  TSNode ->
+  IO ( #{type uint32_t} )
+ts_node_named_child_count = \self ->
+  with self $ \self_p ->
+    _wrap_ts_node_named_child_count self_p
+{-# INLINE ts_node_named_child_count #-}
+
+#{def
+  uint32_t _wrap_ts_node_named_child_count(TSNode *self)
+  {
+    return ts_node_named_child_count(*self);
+  }
+}
+
+foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_node_named_child_count"
+  _wrap_ts_node_named_child_count ::
+    Ptr TSNode ->
+    IO ( #{type uint32_t} )
+
+{-|
+  Get the node's child with the given field name.
+
+  > TSNode ts_node_child_by_field_name(
+  >   TSNode self,
+  >   const char *name,
+  >   uint32_t name_length
+  > );
+-}
+ts_node_child_by_field_name ::
+  TSNode ->
+  ConstPtr CChar ->
+  ( #{type uint32_t} ) ->
+  IO TSNode
+ts_node_child_by_field_name = \self name name_length ->
+  alloca $ \result_p -> do
+    with self $ \self_p ->
+      _wrap_ts_node_child_by_field_name self_p name name_length result_p
+    peek result_p
+{-# INLINE ts_node_child_by_field_name #-}
+
+#{def
+  void _wrap_ts_node_child_by_field_name(
+    TSNode *self,
+    const char *name,
+    uint32_t name_length,
+    TSNode *result
+  )
+  {
+    *result = ts_node_child_by_field_name(*self, name, name_length);
+  }
+}
+
+foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_node_child_by_field_name"
+  _wrap_ts_node_child_by_field_name ::
+    Ptr TSNode ->
+    ConstPtr CChar ->
+    ( #{type uint32_t} ) ->
+    Ptr TSNode ->
+    IO ()
+
+{-|
+  Get the node's child with the given numerical field id.
+
+  You can convert a field name to an id using the
+  @`ts_language_field_id_for_name`@ function.
+
+  > TSNode ts_node_child_by_field_id(TSNode self, TSFieldId field_id);
+-}
+ts_node_child_by_field_id ::
+  TSNode ->
+  TSFieldId ->
+  IO TSNode
+ts_node_child_by_field_id = \self field_id ->
+  alloca $ \result_p -> do
+    with self $ \self_p ->
+      _wrap_ts_node_child_by_field_id self_p field_id result_p
+    peek result_p
+{-# INLINE ts_node_child_by_field_id #-}
+
+#{def
+  void _wrap_ts_node_child_by_field_id(
+    TSNode *self,
+    TSFieldId field_id,
+    TSNode *result
+  )
+  {
+    *result = ts_node_child_by_field_id(*self, field_id);
+  }
+}
+
+foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_node_child_by_field_id"
+  _wrap_ts_node_child_by_field_id ::
+    Ptr TSNode ->
+    TSFieldId ->
+    Ptr TSNode ->
+    IO ()
+
+{-|
+  Get the node's next sibling.
+
+  > TSNode ts_node_next_sibling(TSNode self);
+-}
+ts_node_next_sibling ::
+  TSNode ->
+  IO TSNode
+ts_node_next_sibling = \self ->
+  alloca $ \result_p -> do
+    with self $ \self_p ->
+      _wrap_ts_node_next_sibling self_p result_p
+    peek result_p
+{-# INLINE ts_node_next_sibling #-}
+
+#{def
+  void _wrap_ts_node_next_sibling(TSNode *self, TSNode *result)
+  {
+    *result = ts_node_next_sibling(*self);
+  }
+}
+
+foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_node_next_sibling"
+  _wrap_ts_node_next_sibling ::
+    Ptr TSNode ->
+    Ptr TSNode ->
+    IO ()
+
+{-|
+  Get the node's previous sibling.
+
+  > TSNode ts_node_prev_sibling(TSNode self);
+-}
+ts_node_prev_sibling ::
+  TSNode ->
+  IO TSNode
+ts_node_prev_sibling = \self ->
+  alloca $ \result_p -> do
+    with self $ \self_p ->
+      _wrap_ts_node_prev_sibling self_p result_p
+    peek result_p
+{-# INLINE ts_node_prev_sibling #-}
+
+#{def
+  void _wrap_ts_node_prev_sibling(TSNode *self, TSNode *result)
+  {
+    *result = ts_node_prev_sibling(*self);
+  }
+}
+
+foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_node_prev_sibling"
+  _wrap_ts_node_prev_sibling ::
+    Ptr TSNode ->
+    Ptr TSNode ->
+    IO ()
+
+{-|
+  Get the node's next *named* sibling.
+
+  > TSNode ts_node_next_named_sibling(TSNode self);
+-}
+ts_node_next_named_sibling ::
+  TSNode ->
+  IO TSNode
+ts_node_next_named_sibling = \self ->
+  alloca $ \result_p -> do
+    with self $ \self_p ->
+      _wrap_ts_node_next_named_sibling self_p result_p
+    peek result_p
+{-# INLINE ts_node_next_named_sibling #-}
+
+#{def
+  void _wrap_ts_node_next_named_sibling(TSNode *self, TSNode *result)
+  {
+    *result = ts_node_next_named_sibling(*self);
+  }
+}
+
+foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_node_next_named_sibling"
+  _wrap_ts_node_next_named_sibling ::
+    Ptr TSNode ->
+    Ptr TSNode ->
+    IO ()
+
+{-|
+  Get the node's previous *named* sibling.
+
+  > TSNode ts_node_prev_named_sibling(TSNode self);
+-}
+ts_node_prev_named_sibling ::
+  TSNode ->
+  IO TSNode
+ts_node_prev_named_sibling = \self ->
+  alloca $ \result_p -> do
+    with self $ \self_p ->
+      _wrap_ts_node_prev_named_sibling self_p result_p
+    peek result_p
+{-# INLINE ts_node_prev_named_sibling #-}
+
+#{def
+  void _wrap_ts_node_prev_named_sibling(TSNode *self, TSNode *result)
+  {
+    *result = ts_node_prev_named_sibling(*self);
+  }
+}
+
+foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_node_prev_named_sibling"
+  _wrap_ts_node_prev_named_sibling ::
+    Ptr TSNode ->
+    Ptr TSNode ->
+    IO ()
+
+{-|
+  Get the node's first child that extends beyond the given byte offset.
+
+  > TSNode ts_node_first_child_for_byte(TSNode self, uint32_t byte);
+-}
+ts_node_first_child_for_byte ::
+  TSNode ->
+  ( #{type uint32_t} ) ->
+  IO TSNode
+ts_node_first_child_for_byte = \self byte ->
+  alloca $ \result_p -> do
+    with self $ \self_p ->
+      _wrap_ts_node_first_child_for_byte self_p byte result_p
+    peek result_p
+{-# INLINE ts_node_first_child_for_byte #-}
+
+#{def
+  void _wrap_ts_node_first_child_for_byte(TSNode *self, uint32_t byte, TSNode *result)
+  {
+    *result = ts_node_first_child_for_byte(*self, byte);
+  }
+}
+
+foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_node_first_child_for_byte"
+  _wrap_ts_node_first_child_for_byte ::
+    Ptr TSNode ->
+    ( #{type uint32_t} ) ->
+    Ptr TSNode ->
+    IO ()
+
+{-|
+  Get the node's first named child that extends beyond the given byte offset.
+
+  > TSNode ts_node_first_named_child_for_byte(TSNode self, uint32_t byte);
+-}
+ts_node_first_named_child_for_byte ::
+  TSNode ->
+  ( #{type uint32_t} ) ->
+  IO TSNode
+ts_node_first_named_child_for_byte = \self byte ->
+  alloca $ \result_p -> do
+    with self $ \self_p ->
+      _wrap_ts_node_first_named_child_for_byte self_p byte result_p
+    peek result_p
+{-# INLINE ts_node_first_named_child_for_byte #-}
+
+#{def
+  void _wrap_ts_node_first_named_child_for_byte(TSNode *self, uint32_t byte, TSNode *result)
+  {
+    *result = ts_node_first_named_child_for_byte(*self, byte);
+  }
+}
+
+foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_node_first_named_child_for_byte"
+  _wrap_ts_node_first_named_child_for_byte ::
+    Ptr TSNode ->
+    ( #{type uint32_t} ) ->
+    Ptr TSNode ->
+    IO ()
+
+{-|
+  Get the node's number of descendants, including one for the node itself.
+
+  > uint32_t ts_node_descendant_count(TSNode self);
+-}
+ts_node_descendant_count ::
+  TSNode ->
+  IO ( #{type uint32_t} )
+ts_node_descendant_count = \self ->
+  with self $ \self_p ->
+    _wrap_ts_node_descendant_count self_p
+{-# INLINE ts_node_descendant_count #-}
+
+#{def
+  uint32_t _wrap_ts_node_descendant_count(TSNode *self)
+  {
+    return ts_node_descendant_count(*self);
+  }
+}
+
+foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_node_descendant_count"
+  _wrap_ts_node_descendant_count ::
+    Ptr TSNode ->
+    IO ( #{type uint32_t} )
+
+{-|
+  Get the smallest node within this node that spans the given range of bytes.
+
+  > TSNode ts_node_descendant_for_byte_range(TSNode self, uint32_t start, uint32_t end);
+-}
+ts_node_descendant_for_byte_range ::
+  TSNode ->
+  ( #{type uint32_t} ) ->
+  ( #{type uint32_t} ) ->
+  IO TSNode
+ts_node_descendant_for_byte_range = \self start end ->
+  alloca $ \result_p -> do
+    with self $ \self_p ->
+      _wrap_ts_node_descendant_for_byte_range self_p start end result_p
+    peek result_p
+{-# INLINE ts_node_descendant_for_byte_range #-}
+
+#{def
+  void _wrap_ts_node_descendant_for_byte_range(TSNode *self, uint32_t start, uint32_t end, TSNode *result)
+  {
+    *result = ts_node_descendant_for_byte_range(*self, start, end);
+  }
+}
+
+foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_node_descendant_for_byte_range"
+  _wrap_ts_node_descendant_for_byte_range ::
+    Ptr TSNode ->
+    ( #{type uint32_t} ) ->
+    ( #{type uint32_t} ) ->
+    Ptr TSNode ->
+    IO ()
+
+{-|
+  Get the smallest node within this node that spans the given range of positions.
+
+  > TSNode ts_node_descendant_for_point_range(TSNode self, TSPoint start, TSPoint end);
+-}
+ts_node_descendant_for_point_range ::
+  TSNode ->
+  TSPoint ->
+  TSPoint ->
+  IO TSNode
+ts_node_descendant_for_point_range = \self start end ->
+  alloca $ \result_p -> do
+    with self $ \self_p ->
+      with start $ \start_p ->
+        with end $ \end_p ->
+          _wrap_ts_node_descendant_for_point_range self_p start_p end_p result_p
+    peek result_p
+{-# INLINE ts_node_descendant_for_point_range #-}
+
+#{def
+  void _wrap_ts_node_descendant_for_point_range(TSNode *self, TSPoint *start, TSPoint *end, TSNode *result)
+  {
+    *result = ts_node_descendant_for_point_range(*self, *start, *end);
+  }
+}
+
+foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_node_descendant_for_point_range"
+  _wrap_ts_node_descendant_for_point_range ::
+    Ptr TSNode ->
+    Ptr TSPoint ->
+    Ptr TSPoint ->
+    Ptr TSNode ->
+    IO ()
+
+{-|
+  Get the smallest named node within this node that spans the given range of
+  bytes.
+
+  > TSNode ts_node_named_descendant_for_byte_range(TSNode self, uint32_t start, uint32_t end);
+-}
+ts_node_named_descendant_for_byte_range ::
+  TSNode ->
+  ( #{type uint32_t} ) ->
+  ( #{type uint32_t} ) ->
+  IO TSNode
+ts_node_named_descendant_for_byte_range = \self start end ->
+  alloca $ \result_p -> do
+    with self $ \self_p ->
+      _wrap_ts_node_named_descendant_for_byte_range self_p start end result_p
+    peek result_p
+{-# INLINE ts_node_named_descendant_for_byte_range #-}
+
+#{def
+  void _wrap_ts_node_named_descendant_for_byte_range(TSNode *self, uint32_t start, uint32_t end, TSNode *result)
+  {
+    *result = ts_node_named_descendant_for_byte_range(*self, start, end);
+  }
+}
+
+foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_node_named_descendant_for_byte_range"
+  _wrap_ts_node_named_descendant_for_byte_range ::
+    Ptr TSNode ->
+    ( #{type uint32_t} ) ->
+    ( #{type uint32_t} ) ->
+    Ptr TSNode ->
+    IO ()
+
+{-|
+  Get the smallest named node within this node that spans the given range of positions.
+
+  > TSNode ts_node_named_descendant_for_point_range(TSNode self, TSPoint start, TSPoint end);
+-}
+ts_node_named_descendant_for_point_range ::
+  TSNode ->
+  TSPoint ->
+  TSPoint ->
+  IO TSNode
+ts_node_named_descendant_for_point_range = \self start end ->
+  alloca $ \result_p -> do
+    with self $ \self_p ->
+      with start $ \start_p ->
+        with end $ \end_p ->
+          _wrap_ts_node_named_descendant_for_point_range self_p start_p end_p result_p
+    peek result_p
+{-# INLINE ts_node_named_descendant_for_point_range #-}
+
+#{def
+  void _wrap_ts_node_named_descendant_for_point_range(TSNode *self, TSPoint *start, TSPoint *end, TSNode *result)
+  {
+    *result = ts_node_named_descendant_for_point_range(*self, *start, *end);
+  }
+}
+
+foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_node_named_descendant_for_point_range"
+  _wrap_ts_node_named_descendant_for_point_range ::
+    Ptr TSNode ->
+    Ptr TSPoint ->
+    Ptr TSPoint ->
+    Ptr TSNode ->
+    IO ()
+
+{-|
+  Edit the node to keep it in-sync with source code that has been edited.
+
+  This function is only rarely needed. When you edit a syntax tree with the
+  @`ts_tree_edit`@ function, all of the nodes that you retrieve from the tree
+  afterward will already reflect the edit. You only need to use @`ts_node_edit`@
+  when you have a @t`TSNode`@ instance that you want to keep and continue to use
+  after an edit.
+
+  > void ts_node_edit(TSNode *self, const TSInputEdit *edit);
+-}
+foreign import capi unsafe "TreeSitter/CApi_hsc.h ts_node_edit"
+  ts_node_edit ::
+    Ptr TSNode ->
+    ConstPtr TSInputEdit ->
+    IO ()
+
+{-|
+  Check if two nodes are identical.
+
+  > bool ts_node_eq(TSNode self, TSNode other);
+-}
+ts_node_eq ::
+  TSNode ->
+  TSNode ->
+  IO CBool
+ts_node_eq = \self other ->
+  with self $ \self_p ->
+    with other $ \other_p ->
+        _wrap_ts_node_eq self_p other_p
+{-# INLINE ts_node_eq #-}
+
+#{def
+  bool _wrap_ts_node_eq(TSNode *self, TSNode *other)
+  {
+    return ts_node_eq(*self, *other);
+  }
+}
+
+foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_node_eq"
+  _wrap_ts_node_eq ::
+    Ptr TSNode ->
+    Ptr TSNode ->
+    IO CBool
+
+{- Section - TreeCursor -}
+
+{-|
+  Create a new tree cursor starting from the given node.
+
+  A tree cursor allows you to walk a syntax tree more efficiently than is
+  possible using the @t`TSNode`@ functions. It is a mutable object that is always
+  on a certain syntax node, and can be moved imperatively to different nodes.
+
+  > TSTreeCursor ts_tree_cursor_new(TSNode node);
+-}
+ts_tree_cursor_new ::
+  TSNode ->
+  IO TSTreeCursor
+ts_tree_cursor_new = \node ->
+  alloca $ \result_p -> do
+    ts_tree_cursor_new_p node result_p
+    peek result_p
+{-# INLINE ts_tree_cursor_new #-}
+
+-- | Create a new tree cursor starting from the given node.
+--
+--   Variant of 'ts_tree_cursor_new' that writes the tree cursor to the provided pointer.
+ts_tree_cursor_new_p ::
+  TSNode ->
+  Ptr TSTreeCursor -> -- ^ Output pointer for the new tree cursor.
+  IO ()
+ts_tree_cursor_new_p = \node result_p ->
+  with node $ \node_p ->
+    _wrap_ts_tree_cursor_new node_p result_p
+{-# INLINE ts_tree_cursor_new_p #-}
+
+#{def
+  void _wrap_ts_tree_cursor_new(TSNode *node, TSTreeCursor *result)
+  {
+    *result = ts_tree_cursor_new(*node);
+  }
+}
+
+foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_tree_cursor_new"
+  _wrap_ts_tree_cursor_new ::
+    Ptr TSNode ->
+    Ptr TSTreeCursor ->
+    IO ()
+
+{-|
+  Delete a tree cursor, freeing all of the memory that it used.
+
+  > void ts_tree_cursor_delete(TSTreeCursor *self);
+-}
+foreign import capi unsafe "tree_sitter/api.h ts_tree_cursor_delete"
+  ts_tree_cursor_delete ::
+    Ptr TSTreeCursor ->
+    IO ()
+
+{-| C function pointer to @`ts_tree_cursor_delete`@.
+ -}
+foreign import capi unsafe "tree_sitter/api.h &ts_tree_cursor_delete"
+  p_ts_tree_cursor_delete ::
+    FunPtr (
+      Ptr TSTreeCursor ->
+      IO ()
+    )
+
+{-|
+  Re-initialize a tree cursor to start at the original node that the cursor was
+  constructed with.
+
+  > void ts_tree_cursor_reset(TSTreeCursor *self, TSNode node);
+-}
+ts_tree_cursor_reset ::
+  Ptr TSTreeCursor ->
+  TSNode ->
+  IO ()
+ts_tree_cursor_reset = \self node ->
+  with node $ \node_p ->
+    _wrap_ts_tree_cursor_reset self node_p
+{-# INLINE ts_tree_cursor_reset #-}
+
+#{def
+  void _wrap_ts_tree_cursor_reset(TSTreeCursor *self, TSNode *node)
+  {
+    ts_tree_cursor_reset(self, *node);
+  }
+}
+
+foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_tree_cursor_reset"
+  _wrap_ts_tree_cursor_reset ::
+    Ptr TSTreeCursor ->
+    Ptr TSNode ->
+    IO ()
+
+{-|
+  Re-initialize a tree cursor to the same position as another cursor.
+
+  Unlike @`ts_tree_cursor_reset`@, this will not lose parent information and
+  allows reusing already created cursors.
+
+  > void ts_tree_cursor_reset_to(TSTreeCursor *dst, const TSTreeCursor *src);
+-}
+foreign import capi unsafe "tree_sitter/api.h ts_tree_cursor_reset_to"
+  ts_tree_cursor_reset_to ::
+    Ptr TSTreeCursor ->
+    ConstPtr TSTreeCursor ->
+    IO ()
+
+{-|
+  Get the tree cursor's current node.
+
+  > TSNode ts_tree_cursor_current_node(const TSTreeCursor *self);
+-}
+ts_tree_cursor_current_node ::
+  ConstPtr TSTreeCursor ->
+  IO TSNode
+ts_tree_cursor_current_node = \self ->
+  alloca $ \result_p -> do
+    _wrap_ts_tree_cursor_current_node self result_p
+    peek result_p
+{-# INLINE ts_tree_cursor_current_node #-}
+
+#{def
+  void _wrap_ts_tree_cursor_current_node(const TSTreeCursor *self, TSNode *result)
+  {
+    *result = ts_tree_cursor_current_node(self);
+  }
+}
+
+foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_tree_cursor_current_node"
+  _wrap_ts_tree_cursor_current_node ::
+    ConstPtr TSTreeCursor ->
+    Ptr TSNode ->
+    IO ()
+
+{-|
+  Get the field name of the tree cursor's current node.
+
+  This returns @NULL@ if the current node doesn't have a field.
+  See also @`ts_node_child_by_field_name`@.
+
+  > const char *ts_tree_cursor_current_field_name(const TSTreeCursor *self);
+-}
+foreign import capi unsafe "tree_sitter/api.h ts_tree_cursor_current_field_name"
+  ts_tree_cursor_current_field_name ::
+    ConstPtr TSTreeCursor ->
+    IO (ConstPtr CChar)
+
+{-|
+  Get the field id of the tree cursor's current node.
+
+  This returns zero if the current node doesn't have a field.
+  See also @`ts_node_child_by_field_id`@, @`ts_language_field_id_for_name`@.
+
+  > TSFieldId ts_tree_cursor_current_field_id(const TSTreeCursor *self);
+-}
+foreign import capi unsafe "tree_sitter/api.h ts_tree_cursor_current_field_id"
+  ts_tree_cursor_current_field_id ::
+    ConstPtr TSTreeCursor ->
+    IO TSFieldId
+
+{-|
+  Move the cursor to the parent of its current node.
+
+  This returns @true@ if the cursor successfully moved, and returns @false@
+  if there was no parent node (the cursor was already on the root node).
+
+  > bool ts_tree_cursor_goto_parent(TSTreeCursor *self);
+-}
+foreign import capi unsafe "tree_sitter/api.h ts_tree_cursor_goto_parent"
+  ts_tree_cursor_goto_parent ::
+    Ptr TSTreeCursor ->
+    IO CBool
+
+{-|
+  Move the cursor to the next sibling of its current node.
+
+  This returns @true@ if the cursor successfully moved, and returns @false@
+  if there was no next sibling node.
+
+  > bool ts_tree_cursor_goto_next_sibling(TSTreeCursor *self);
+-}
+foreign import capi unsafe "tree_sitter/api.h ts_tree_cursor_goto_next_sibling"
+  ts_tree_cursor_goto_next_sibling ::
+    Ptr TSTreeCursor ->
+    IO CBool
+
+{-|
+  Move the cursor to the previous sibling of its current node.
+
+  This returns @true@ if the cursor successfully moved, and returns @false@ if
+  there was no previous sibling node.
+
+  Note, that this function may be slower than
+  @`ts_tree_cursor_goto_next_sibling`@ due to how node positions are stored. In
+  the worst case, this will need to iterate through all the children upto the
+  previous sibling node to recalculate its position.
+
+  > bool ts_tree_cursor_goto_previous_sibling(TSTreeCursor *self);
+-}
+foreign import capi unsafe "tree_sitter/api.h ts_tree_cursor_goto_previous_sibling"
+  ts_tree_cursor_goto_previous_sibling ::
+    Ptr TSTreeCursor ->
+    IO CBool
+
+{-|
+  Move the cursor to the first child of its current node.
+
+  This returns @true@ if the cursor successfully moved, and returns @false@
+  if there were no children.
+
+  > bool ts_tree_cursor_goto_first_child(TSTreeCursor *self);
+-}
+foreign import capi unsafe "tree_sitter/api.h ts_tree_cursor_goto_first_child"
+  ts_tree_cursor_goto_first_child ::
+    Ptr TSTreeCursor ->
+    IO CBool
+
+{-|
+  Move the cursor to the last child of its current node.
+
+  This returns @true@ if the cursor successfully moved, and returns @false@ if
+  there were no children.
+
+  Note that this function may be slower than @`ts_tree_cursor_goto_first_child`@
+  because it needs to iterate through all the children to compute the child's
+  position.
+
+  > bool ts_tree_cursor_goto_last_child(TSTreeCursor *self);
+-}
+foreign import capi unsafe "tree_sitter/api.h ts_tree_cursor_goto_last_child"
+  ts_tree_cursor_goto_last_child ::
+    Ptr TSTreeCursor ->
+    IO CBool
+
+{-|
+  Move the cursor to the node that is the nth descendant of
+  the original node that the cursor was constructed with, where
+  zero represents the original node itself.
+
+  > void ts_tree_cursor_goto_descendant(TSTreeCursor *self, uint32_t goal_descendant_index);
+-}
+foreign import capi unsafe "tree_sitter/api.h ts_tree_cursor_goto_descendant"
+  ts_tree_cursor_goto_descendant ::
+    Ptr TSTreeCursor ->
+    ( #{type uint32_t} ) ->
+    IO ()
+
+{-|
+  Get the index of the cursor's current node out of all of the
+  descendants of the original node that the cursor was constructed with.
+
+  > uint32_t ts_tree_cursor_current_descendant_index(const TSTreeCursor *self);
+-}
+foreign import capi unsafe "tree_sitter/api.h ts_tree_cursor_current_descendant_index"
+  ts_tree_cursor_current_descendant_index ::
+    ConstPtr TSTreeCursor ->
+    IO ( #{type uint32_t} )
+
+{-|
+  Get the depth of the cursor's current node relative to the original
+  node that the cursor was constructed with.
+
+  > uint32_t ts_tree_cursor_current_depth(const TSTreeCursor *self);
+-}
+foreign import capi unsafe "tree_sitter/api.h ts_tree_cursor_current_depth"
+  ts_tree_cursor_current_depth ::
+    ConstPtr TSTreeCursor ->
+    IO ( #{type uint32_t} )
+
+{-|
+  Move the cursor to the first child of its current node that extends beyond
+  the given byte offset.
+
+  This returns the index of the child node if one was found, and returns -1
+  if no such child was found.
+
+  > int64_t ts_tree_cursor_goto_first_child_for_byte(TSTreeCursor *self, uint32_t goal_byte);
+-}
+foreign import capi unsafe "tree_sitter/api.h ts_tree_cursor_goto_first_child_for_byte"
+  ts_tree_cursor_goto_first_child_for_byte ::
+    Ptr TSTreeCursor ->
+    ( #{type uint32_t} ) ->
+    IO ( #{type int64_t} )
+
+{-|
+  Move the cursor to the first child of its current node that extends beyond
+  the given byte point.
+
+  This returns the index of the child node if one was found, and returns -1
+  if no such child was found.
+
+  > int64_t ts_tree_cursor_goto_first_child_for_point(TSTreeCursor *self, TSPoint goal_point);
+-}
+ts_tree_cursor_goto_first_child_for_point ::
+    Ptr TSTreeCursor ->
+    TSPoint ->
+    IO ( #{type int64_t} )
+ts_tree_cursor_goto_first_child_for_point = \self goal_point ->
+  with goal_point $ \goal_point_p ->
+    _wrap_ts_tree_cursor_goto_first_child_for_point self goal_point_p
+{-# INLINE ts_tree_cursor_goto_first_child_for_point #-}
+
+#{def
+  int64_t _wrap_ts_tree_cursor_goto_first_child_for_point(TSTreeCursor *self, TSPoint *goal_point)
+  {
+    return ts_tree_cursor_goto_first_child_for_point(self, *goal_point);
+  }
+}
+
+foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_tree_cursor_goto_first_child_for_point"
+  _wrap_ts_tree_cursor_goto_first_child_for_point ::
+    Ptr TSTreeCursor ->
+    Ptr TSPoint ->
+    IO ( #{type int64_t} )
+
+{-|
+  > TSTreeCursor ts_tree_cursor_copy(const TSTreeCursor *cursor);
+  -}
+ts_tree_cursor_copy ::
+    Ptr TSTreeCursor ->
+    IO TSTreeCursor
+ts_tree_cursor_copy = \self ->
+  alloca $ \result_p -> do
+    _wrap_ts_tree_cursor_copy self result_p
+    peek result_p
+{-# INLINE ts_tree_cursor_copy #-}
+
+-- | Copy a tree cursor.
+--
+--   Variant of 'ts_tree_cursor_copy' that writes the tree cursor to the provided pointer.
+ts_tree_cursor_copy_p ::
+  Ptr TSTreeCursor ->
+  Ptr TSTreeCursor -> -- ^ Output pointer for the new tree cursor.
+  IO ()
+ts_tree_cursor_copy_p = _wrap_ts_tree_cursor_copy
+{-# INLINE ts_tree_cursor_copy_p #-}
+
+
+#{def
+  void _wrap_ts_tree_cursor_copy(TSTreeCursor *self, TSTreeCursor *result)
+  {
+    *result = ts_tree_cursor_copy(self);
+  }
+}
+
+foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_tree_cursor_copy"
+  _wrap_ts_tree_cursor_copy ::
+    Ptr TSTreeCursor ->
+    Ptr TSTreeCursor ->
+    IO ()
+
+{- Section - Query -}
+
+{-|
+  Create a new query from a string containing one or more S-expression
+  patterns. The query is associated with a particular language, and can
+  only be run on syntax nodes parsed with that language.
+
+  If all of the given patterns are valid, this returns a @t`TSQuery`@.
+  If a pattern is invalid, this returns @NULL@, and provides two pieces
+  of information about the problem:
+  1. The byte offset of the error is written to the @error_offset@ parameter.
+  2. The type of error is written to the @error_type@ parameter.
+
+  > TSQuery *ts_query_new(
+  >   const TSLanguage *language,
+  >   const char *source,
+  >   uint32_t source_len,
+  >   uint32_t *error_offset,
+  >   TSQueryError *error_type
+  > );
+-}
+foreign import capi unsafe "tree_sitter/api.h ts_query_new"
+  ts_query_new ::
+    ConstPtr TSLanguage ->
+    ConstPtr CChar ->
+    ( #{type uint32_t} ) ->
+    Ptr ( #{type uint32_t} ) ->
+    Ptr TSQueryError ->
+    IO (Ptr TSQuery)
+
+{-|
+  Delete a query, freeing all of the memory that it used.
+
+  > void ts_query_delete(TSQuery *self);
+-}
+foreign import capi unsafe "tree_sitter/api.h ts_query_delete"
+  ts_query_delete ::
+    Ptr TSQuery ->
+    IO ()
+
+{-| C function pointer to @`ts_query_delete`@.
+ -}
+foreign import capi unsafe "tree_sitter/api.h &ts_query_delete"
+  p_ts_query_delete ::
+    FunPtr (
+      Ptr TSQuery ->
+      IO ()
+    )
+
+{-|
+  Get the number of patterns in the query.
+
+  > uint32_t ts_query_pattern_count(const TSQuery *self);
+-}
+foreign import capi unsafe "tree_sitter/api.h ts_query_pattern_count"
+  ts_query_pattern_count ::
+    ConstPtr TSQuery ->
+    IO ( #{type uint32_t} )
+
+{-|
+  Get the number of captures in the query.
+
+  > uint32_t ts_query_capture_count(const TSQuery *self);
+-}
+foreign import capi unsafe "tree_sitter/api.h ts_query_capture_count"
+  ts_query_capture_count ::
+    ConstPtr TSQuery ->
+    IO ( #{type uint32_t} )
+
+{-|
+  Get the number of string literals in the query.
+
+  > uint32_t ts_query_string_count(const TSQuery *self);
+-}
+foreign import capi unsafe "tree_sitter/api.h ts_query_string_count"
+  ts_query_string_count ::
+    ConstPtr TSQuery ->
+    IO ( #{type uint32_t} )
+
+{-|
+  Get the byte offset where the given pattern starts in the query's source.
+
+  This can be useful when combining queries by concatenating their source
+  code strings.
+
+  > uint32_t ts_query_start_byte_for_pattern(const TSQuery *self, uint32_t pattern_index);
+-}
+foreign import capi unsafe "tree_sitter/api.h ts_query_start_byte_for_pattern"
+  ts_query_start_byte_for_pattern ::
+    ConstPtr TSQuery ->
+    ( #{type uint32_t} ) ->
+    IO ( #{type uint32_t} )
+
+{-|
+  Get the byte offset where the given pattern ends in the query's source.
+
+  This can be useful when combining queries by concatenating their source
+  code strings.
+
+  > uint32_t ts_query_end_byte_for_pattern(const TSQuery *self, uint32_t pattern_index);
+-}
+foreign import capi unsafe "tree_sitter/api.h ts_query_end_byte_for_pattern"
+  ts_query_end_byte_for_pattern ::
+    ConstPtr TSQuery ->
+    ( #{type uint32_t} ) ->
+    IO ( #{type uint32_t} )
+
+{-|
+  Get all of the predicates for the given pattern in the query.
+
+  The predicates are represented as a single array of steps. There are three
+  types of steps in this array, which correspond to the three legal values for
+  the `type` field:
+  - @`TSQueryPredicateStepTypeCapture`@ - Steps with this type represent names
+     of captures. Their @value_id@ can be used with the
+    @`ts_query_capture_name_for_id`@ function to obtain the name of the capture.
+  - @`TSQueryPredicateStepTypeString`@ - Steps with this type represent literal
+     strings. Their @value_id@ can be used with the
+     @`ts_query_string_value_for_id`@ function to obtain their string value.
+  - @`TSQueryPredicateStepTypeDone`@ - Steps with this type are *sentinels*
+     that represent the end of an individual predicate. If a pattern has two
+     predicates, then there will be two steps with this `type` in the array.
+
+  > const TSQueryPredicateStep *ts_query_predicates_for_pattern(
+  >   const TSQuery *self,
+  >   uint32_t pattern_index,
+  >   uint32_t *step_count
+  > );
+-}
+foreign import capi unsafe "tree_sitter/api.h ts_query_predicates_for_pattern"
+  ts_query_predicates_for_pattern ::
+    ConstPtr TSQuery ->
+    ( #{type uint32_t} ) ->
+    Ptr ( #{type uint32_t} ) ->
+    IO (ConstPtr TSQueryPredicateStep)
+
+{-|
+  Check if the given pattern in the query has a single root node.
+
+  > bool ts_query_is_pattern_rooted(const TSQuery *self, uint32_t pattern_index);
+-}
+foreign import capi unsafe "tree_sitter/api.h ts_query_is_pattern_rooted"
+  ts_query_is_pattern_rooted ::
+    ConstPtr TSQuery ->
+    ( #{type uint32_t} ) ->
+    IO CBool
+
+{-|
+  Check if the given pattern in the query is non-local.
+
+  A non-local pattern has multiple root nodes and can match within a
+  repeating sequence of nodes, as specified by the grammar. Non-local
+  patterns disable certain optimizations that would otherwise be possible
+  when executing a query on a specific range of a syntax tree.
+
+  > bool ts_query_is_pattern_non_local(const TSQuery *self, uint32_t pattern_index);
+-}
+foreign import capi unsafe "tree_sitter/api.h ts_query_is_pattern_non_local"
+  ts_query_is_pattern_non_local ::
+    ConstPtr TSQuery ->
+    ( #{type uint32_t} ) ->
+    IO CBool
+
+{-|
+  Check if a given pattern is guaranteed to match once a given step is reached.
+  The step is specified by its byte offset in the query's source code.
+
+  > bool ts_query_is_pattern_guaranteed_at_step(const TSQuery *self, uint32_t byte_offset);
+-}
+foreign import capi unsafe "tree_sitter/api.h ts_query_is_pattern_guaranteed_at_step"
+  ts_query_is_pattern_guaranteed_at_step ::
+    ConstPtr TSQuery ->
+    ( #{type uint32_t} ) ->
+    IO CBool
+
+{-|
+  Get the name and length of one of the query's captures, or one of the
+  query's string literals. Each capture and string is associated with a
+  numeric id based on the order that it appeared in the query's source.
+
+  > const char *ts_query_capture_name_for_id(
+  >   const TSQuery *self,
+  >   uint32_t index,
+  >   uint32_t *length
+  > );
+-}
+foreign import capi unsafe "tree_sitter/api.h ts_query_capture_name_for_id"
+  ts_query_capture_name_for_id ::
+    ConstPtr TSQuery ->
+    ( #{type uint32_t} ) ->
+    Ptr ( #{type uint32_t} ) ->
+    IO (ConstPtr CChar)
+
+{-|
+  Get the quantifier of the query's captures. Each capture is * associated
+  with a numeric id based on the order that it appeared in the query's source.
+
+  > TSQuantifier ts_query_capture_quantifier_for_id(
+  >   const TSQuery *self,
+  >   uint32_t pattern_index,
+  >   uint32_t capture_index
+  > );
+-}
+foreign import capi unsafe "tree_sitter/api.h ts_query_capture_quantifier_for_id"
+  ts_query_capture_quantifier_for_id ::
+    ConstPtr TSQuery ->
+    ( #{type uint32_t} ) ->
+    ( #{type uint32_t} ) ->
+    IO TSQuantifier
+
+{-|
+  > const char *ts_query_string_value_for_id(
+  >   const TSQuery *self,
+  >   uint32_t index,
+  >   uint32_t *length
+  > );
+  -}
+foreign import capi unsafe "tree_sitter/api.h ts_query_string_value_for_id"
+  ts_query_string_value_for_id ::
+    ConstPtr TSQuery ->
+    ( #{type uint32_t} ) ->
+    Ptr ( #{type uint32_t} ) ->
+    IO (ConstPtr CChar)
+
+{-|
+  Disable a certain capture within a query.
+
+  This prevents the capture from being returned in matches, and also avoids
+  any resource usage associated with recording the capture. Currently, there
+  is no way to undo this.
+
+  > void ts_query_disable_capture(TSQuery *self, const char *name, uint32_t length);
+-}
+foreign import capi unsafe "tree_sitter/api.h ts_query_disable_capture"
+  ts_query_disable_capture ::
+    Ptr TSQuery ->
+    ConstPtr CChar ->
+    ( #{type uint32_t} ) ->
+    IO ()
+
+{-|
+  Disable a certain pattern within a query.
+
+  This prevents the pattern from matching and removes most of the overhead
+  associated with the pattern. Currently, there is no way to undo this.
+
+  > void ts_query_disable_pattern(TSQuery *self, uint32_t pattern_index);
+-}
+foreign import capi unsafe "tree_sitter/api.h ts_query_disable_pattern"
+  ts_query_disable_pattern ::
+    Ptr TSQuery ->
+    ( #{type uint32_t} ) ->
+    IO ()
+
+{-|
+  Create a new cursor for executing a given query.
+
+  The cursor stores the state that is needed to iteratively search
+  for matches. To use the query cursor, first call @`ts_query_cursor_exec`@
+  to start running a given query on a given syntax node. Then, there are
+  two options for consuming the results of the query:
+  1. Repeatedly call @`ts_query_cursor_next_match`@ to iterate over all of the
+     *matches* in the order that they were found. Each match contains the
+     index of the pattern that matched, and an array of captures. Because
+     multiple patterns can match the same set of nodes, one match may contain
+     captures that appear *before* some of the captures from a previous match.
+  2. Repeatedly call @`ts_query_cursor_next_capture`@ to iterate over all of the
+     individual *captures* in the order that they appear. This is useful if
+     don't care about which pattern matched, and just want a single ordered
+     sequence of captures.
+
+  If you don't care about consuming all of the results, you can stop calling
+  @`ts_query_cursor_next_match`@ or @`ts_query_cursor_next_capture`@ at any point.
+   You can then start executing another query on another node by calling
+   @`ts_query_cursor_exec`@ again.
+
+    > TSQueryCursor *ts_query_cursor_new(void);
+-}
+foreign import capi unsafe "tree_sitter/api.h ts_query_cursor_new"
+  ts_query_cursor_new ::
+    IO (Ptr TSQueryCursor)
+
+{-|
+  Delete a query cursor, freeing all of the memory that it used.
+
+  > void ts_query_cursor_delete(TSQueryCursor *self);
+-}
+foreign import capi unsafe "tree_sitter/api.h ts_query_cursor_delete"
+  ts_query_cursor_delete ::
+    Ptr TSQueryCursor ->
+    IO ()
+
+{-| C function pointer to @`ts_query_cursor_delete`@.
+ -}
+foreign import capi unsafe "tree_sitter/api.h &ts_query_cursor_delete"
+  p_ts_query_cursor_delete ::
+    FunPtr (
+      Ptr TSQueryCursor ->
+      IO ()
+    )
+
+{-|
+  Start running a given query on a given node.
+
+  > void ts_query_cursor_exec(TSQueryCursor *self, const TSQuery *query, TSNode node);
+-}
+ts_query_cursor_exec ::
+  Ptr TSQueryCursor ->
+  ConstPtr TSQuery ->
+  TSNode ->
+  IO ()
+ts_query_cursor_exec = \self query node ->
+  with node $ \node_p ->
+    _wrap_ts_query_cursor_exec self query node_p
+{-# INLINE ts_query_cursor_exec #-}
+
+#{def
+  void _wrap_ts_query_cursor_exec(TSQueryCursor *self, const TSQuery *query, TSNode *node)
+  {
+    return ts_query_cursor_exec(self, query, *node);
+  }
+}
+
+foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_query_cursor_exec"
+  _wrap_ts_query_cursor_exec ::
+    Ptr TSQueryCursor ->
+    ConstPtr TSQuery ->
+    Ptr TSNode ->
+    IO ()
+
+{-|
+  Check whether the maximum number of in-progress matches allowed by this query cursor was exceeded.
+
+  Query cursors have an optional maximum capacity for storing lists of
+  in-progress captures. If this capacity is exceeded, then the
+  earliest-starting match will silently be dropped to make room for further
+  matches. This maximum capacity is optional — by default, query cursors allow
+  any number of pending matches, dynamically allocating new space for them as
+  needed as the query is executed.
+
+  > bool ts_query_cursor_did_exceed_match_limit(const TSQueryCursor *self);
+-}
+foreign import capi unsafe "tree_sitter/api.h ts_query_cursor_did_exceed_match_limit"
+  ts_query_cursor_did_exceed_match_limit ::
+    ConstPtr TSQueryCursor ->
+    IO CBool
+
+{-|
+  Get the maximum number of in-progress matches allowed by this query cursor.
+
+  > uint32_t ts_query_cursor_match_limit(const TSQueryCursor *self);
+-}
+foreign import capi unsafe "tree_sitter/api.h ts_query_cursor_match_limit"
+  ts_query_cursor_match_limit ::
+    ConstPtr TSQueryCursor ->
+    IO ( #{type uint32_t} )
+
+{-|
+  Set the maximum number of in-progress matches allowed by this query cursor.
+
+  > void ts_query_cursor_set_match_limit(TSQueryCursor *self, uint32_t limit);
+-}
+foreign import capi unsafe "tree_sitter/api.h ts_query_cursor_set_match_limit"
+  ts_query_cursor_set_match_limit ::
+    Ptr TSQueryCursor ->
+    ( #{type uint32_t} ) ->
+    IO ()
+
+{-|
+  Set the maximum duration in microseconds that query execution should be allowed to
+  take before halting.
+
+  If query execution takes longer than this, it will halt early, returning @NULL@.
+  See @`ts_query_cursor_next_match`@ or @`ts_query_cursor_next_capture`@ for more information.
+
+  > void ts_query_cursor_set_timeout_micros(TSQueryCursor *self, uint64_t timeout_micros);
+-}
+foreign import capi unsafe "tree_sitter/api.h ts_query_cursor_set_timeout_micros"
+  ts_query_cursor_set_timeout_micros ::
+    Ptr TSQueryCursor ->
+    ( #{type uint64_t} ) ->
+    IO ()
+
+{-|
+  Get the duration in microseconds that query execution is allowed to take.
+
+  This is set via @`ts_query_cursor_set_timeout_micros`@.
+
+  > uint64_t ts_query_cursor_timeout_micros(const TSQueryCursor *self);
+-}
+foreign import capi unsafe "tree_sitter/api.h ts_query_cursor_timeout_micros"
+  ts_query_cursor_timeout_micros ::
+    ConstPtr TSQueryCursor ->
+    IO ( #{type uint64_t} )
+
+{-|
+  Set the range of bytes in which the query will be executed.
+
+  > void ts_query_cursor_set_byte_range(TSQueryCursor *self, uint32_t start_byte, uint32_t end_byte);
+-}
+foreign import capi unsafe "tree_sitter/api.h ts_query_cursor_set_byte_range"
+  ts_query_cursor_set_byte_range ::
+    Ptr TSQueryCursor ->
+    ( #{type uint32_t} ) ->
+    ( #{type uint32_t} ) ->
+    IO ()
+
+{-|
+  Set the range of positions in which the query will be executed.
+
+  > void ts_query_cursor_set_point_range(TSQueryCursor *self, TSPoint start_point, TSPoint end_point);
+-}
+ts_query_cursor_set_point_range ::
+    Ptr TSQueryCursor ->
+    TSPoint ->
+    TSPoint ->
+    IO ()
+ts_query_cursor_set_point_range = \self start_point end_point ->
+  with start_point $ \start_point_p ->
+    with end_point $ \end_point_p ->
+      _wrap_ts_query_cursor_set_point_range self start_point_p end_point_p
+{-# INLINE ts_query_cursor_set_point_range #-}
+
+#{def
+  void _wrap_ts_query_cursor_set_point_range(TSQueryCursor *self, TSPoint *start_point, TSPoint *end_point)
+  {
+    ts_query_cursor_set_point_range(self, *start_point, *end_point);
+  }
+}
+
+foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_query_cursor_set_point_range"
+  _wrap_ts_query_cursor_set_point_range ::
+    Ptr TSQueryCursor ->
+    Ptr TSPoint ->
+    Ptr TSPoint ->
+    IO ()
+
+{-|
+  Advance to the next match of the currently running query.
+
+  If there is a match, write it to `*match` and return @true@.
+  Otherwise, return @false@.
+
+  > bool ts_query_cursor_next_match(TSQueryCursor *self, TSQueryMatch *match);
+-}
+foreign import capi unsafe "tree_sitter/api.h ts_query_cursor_next_match"
+  ts_query_cursor_next_match ::
+    Ptr TSQueryCursor ->
+    Ptr TSQueryMatch ->
+    IO CBool
+
+{-|
+  Remove a match of the currently running query.
+
+  > void ts_query_cursor_remove_match(TSQueryCursor *self, uint32_t match_id);
+-}
+foreign import capi unsafe "tree_sitter/api.h ts_query_cursor_remove_match"
+  ts_query_cursor_remove_match ::
+    Ptr TSQueryCursor ->
+    ( #{type uint32_t} ) ->
+    IO ()
+
+{-|
+  Advance to the next capture of the currently running query.
+
+  If there is a capture, write its match to `*match` and its index within
+  the matche's capture list to `*capture_index`. Otherwise, return @false@.
+
+  > bool ts_query_cursor_next_capture(
+  >   TSQueryCursor *self,
+  >   TSQueryMatch *match,
+  >   uint32_t *capture_index
+  > );
+-}
+foreign import capi unsafe "tree_sitter/api.h ts_query_cursor_next_capture"
+  ts_query_cursor_next_capture ::
+    Ptr TSQueryCursor ->
+    Ptr TSQueryMatch ->
+    Ptr ( #{type uint32_t} ) ->
+    IO CBool
+
+{-|
+  Set the maximum start depth for a query cursor.
+
+  This prevents cursors from exploring children nodes at a certain depth.
+  Note if a pattern includes many children, then they will still be checked.
+
+  The zero max start depth value can be used as a special behavior and
+  it helps to destructure a subtree by staying on a node and using captures
+  for interested parts. Note that the zero max start depth only limit a search
+  depth for a pattern's root node but other nodes that are parts of the pattern
+  may be searched at any depth what defined by the pattern structure.
+
+  Set to @UINT32_MAX@ to remove the maximum start depth.
+
+  > void ts_query_cursor_set_max_start_depth(TSQueryCursor *self, uint32_t max_start_depth);
+-}
+foreign import capi unsafe "tree_sitter/api.h ts_query_cursor_set_max_start_depth"
+  ts_query_cursor_set_max_start_depth ::
+    Ptr TSQueryCursor ->
+    ( #{type uint32_t} ) ->
+    IO ()
+
+{- Section - Language -}
+
+{-|
+  Get another reference to the given language.
+
+  > const TSLanguage *ts_language_copy(const TSLanguage *self);
+-}
+foreign import capi unsafe "tree_sitter/api.h ts_language_copy"
+  ts_language_copy ::
+    ConstPtr TSLanguage ->
+    IO (ConstPtr TSLanguage)
+
+{-|
+  Free any dynamically-allocated resources for this language, if
+  this is the last reference.
+
+  > void ts_language_delete(const TSLanguage *self);
+-}
+foreign import capi unsafe "tree_sitter/api.h ts_language_delete"
+  ts_language_delete ::
+    ConstPtr TSLanguage ->
+    IO ()
+
+{-| C function pointer to @`ts_language_delete`@.
+ -}
+foreign import capi unsafe "tree_sitter/api.h &ts_language_delete"
+  p_ts_language_delete ::
+    FunPtr (
+      ConstPtr TSLanguage ->
+      IO ()
+    )
+
+{-|
+  Get the number of distinct node types in the language.
+
+  > uint32_t ts_language_symbol_count(const TSLanguage *self);
+-}
+foreign import capi unsafe "tree_sitter/api.h ts_language_symbol_count"
+  ts_language_symbol_count ::
+    ConstPtr TSLanguage ->
+    IO ( #{type uint32_t} )
+
+{-|
+  Get the number of valid states in this language.
+
+  > uint32_t ts_language_state_count(const TSLanguage *self);
+-}
+foreign import capi unsafe "tree_sitter/api.h ts_language_state_count"
+  ts_language_state_count ::
+    ConstPtr TSLanguage ->
+    IO ( #{type uint32_t} )
+
+{-|
+  Get a node type string for the given numerical id.
+
+  > const char *ts_language_symbol_name(const TSLanguage *self, TSSymbol symbol);
+-}
+foreign import capi unsafe "tree_sitter/api.h ts_language_symbol_name"
+  ts_language_symbol_name ::
+    ConstPtr TSLanguage ->
+    TSSymbol ->
+    IO (ConstPtr CChar)
+
+{-|
+  Get the numerical id for the given node type string.
+
+  > TSSymbol ts_language_symbol_for_name(
+  >   const TSLanguage *self,
+  >   const char *string,
+  >   uint32_t length,
+  >   bool is_named
+  > );
+-}
+foreign import capi unsafe "tree_sitter/api.h ts_language_symbol_for_name"
+  ts_language_symbol_for_name ::
+    ConstPtr TSLanguage ->
+    ConstPtr CChar ->
+    ( #{type uint32_t} ) ->
+    CBool ->
+    IO TSSymbol
+
+{-|
+  Get the number of distinct field names in the language.
+
+  > uint32_t ts_language_field_count(const TSLanguage *self);
+-}
+foreign import capi unsafe "tree_sitter/api.h ts_language_field_count"
+  ts_language_field_count ::
+    ConstPtr TSLanguage ->
+    IO ( #{type uint32_t} )
+
+{-|
+  Get the field name string for the given numerical id.
+
+  > const char *ts_language_field_name_for_id(const TSLanguage *self, TSFieldId id);
+-}
+foreign import capi unsafe "tree_sitter/api.h ts_language_field_name_for_id"
+  ts_language_field_name_for_id ::
+    ConstPtr TSLanguage ->
+    TSFieldId ->
+    IO (ConstPtr CChar)
+
+{-|
+  Get the numerical id for the given field name string.
+
+  > TSFieldId ts_language_field_id_for_name(const TSLanguage *self, const char *name, uint32_t name_length);
+-}
+foreign import capi unsafe "tree_sitter/api.h ts_language_field_id_for_name"
+  ts_language_field_id_for_name ::
+    ConstPtr TSLanguage ->
+    ConstPtr CChar ->
+    ( #{type uint32_t} ) ->
+    IO TSFieldId
+
+{-|
+  Check whether the given node type id belongs to named nodes, anonymous nodes,
+  or a hidden nodes.
+
+  See also @`ts_node_is_named`@. Hidden nodes are never returned from the API.
+
+  > TSSymbolType ts_language_symbol_type(const TSLanguage *self, TSSymbol symbol);
+-}
+foreign import capi unsafe "tree_sitter/api.h ts_language_symbol_type"
+  ts_language_symbol_type ::
+    ConstPtr TSLanguage ->
+    TSSymbol ->
+    IO TSSymbolType
+
+{-|
+  Get the ABI version number for this language. This version number is used
+  to ensure that languages were generated by a compatible version of
+  Tree-sitter.
+
+  See also @`ts_parser_set_language`@.
+
+  > uint32_t ts_language_version(const TSLanguage *self);
+-}
+foreign import capi unsafe "tree_sitter/api.h ts_language_version"
+  ts_language_version ::
+    ConstPtr TSLanguage ->
+    IO ( #{type uint32_t} )
+
+{-|
+  Get the next parse state. Combine this with lookahead iterators to generate
+  completion suggestions or valid symbols in error nodes. Use
+  @`ts_node_grammar_symbol`@ for valid symbols.
+
+  > TSStateId ts_language_next_state(const TSLanguage *self, TSStateId state, TSSymbol symbol);
+-}
+foreign import capi unsafe "tree_sitter/api.h ts_language_next_state"
+  ts_language_next_state ::
+    ConstPtr TSLanguage ->
+    TSStateId ->
+    TSSymbol ->
+    IO TSStateId
+
+{--------------------------------}
+{- Section - Lookahead Iterator -}
+{--------------------------------}
+
+{-|
+  Create a new lookahead iterator for the given language and parse state.
+
+  This returns @NULL@ if state is invalid for the language.
+
+  Repeatedly using @`ts_lookahead_iterator_next`@ and
+  @`ts_lookahead_iterator_current_symbol`@ will generate valid symbols in the
+  given parse state. Newly created lookahead iterators will contain the @ERROR@
+  symbol.
+
+  Lookahead iterators can be useful to generate suggestions and improve syntax
+  error diagnostics. To get symbols valid in an ERROR node, use the lookahead
+  iterator on its first leaf node state. For @MISSING@ nodes, a lookahead
+  iterator created on the previous non-extra leaf node may be appropriate.
+
+  > TSLookaheadIterator *ts_lookahead_iterator_new(const TSLanguage *self, TSStateId state);
+-}
+foreign import capi unsafe "tree_sitter/api.h ts_lookahead_iterator_new"
+  ts_lookahead_iterator_new ::
+    ConstPtr TSLanguage ->
+    TSStateId ->
+    IO (Ptr TSLookaheadIterator)
+
+{-|
+  Delete a lookahead iterator freeing all the memory used.
+
+  > void ts_lookahead_iterator_delete(TSLookaheadIterator *self);
+-}
+foreign import capi unsafe "tree_sitter/api.h ts_lookahead_iterator_delete"
+  ts_lookahead_iterator_delete ::
+    Ptr TSLookaheadIterator ->
+    IO ()
+
+{-| C function pointer to @`ts_lookahead_iterator_delete`@.
+ -}
+foreign import capi unsafe "tree_sitter/api.h &ts_lookahead_iterator_delete"
+  p_ts_lookahead_iterator_delete ::
+    FunPtr (
+      Ptr TSLookaheadIterator ->
+      IO ()
+    )
+
+{-|
+  Reset the lookahead iterator to another state.
+
+  This returns @true@ if the iterator was reset to the given state and @false@
+  otherwise.
+
+  > bool ts_lookahead_iterator_reset_state(TSLookaheadIterator *self, TSStateId state);
+-}
+foreign import capi unsafe "tree_sitter/api.h ts_lookahead_iterator_reset_state"
+  ts_lookahead_iterator_reset_state ::
+    Ptr TSLookaheadIterator ->
+    TSStateId ->
+    IO CBool
+
+{-|
+  Reset the lookahead iterator.
+
+  This returns @true@ if the language was set successfully and @false@
+  otherwise.
+
+  > bool ts_lookahead_iterator_reset(TSLookaheadIterator *self, const TSLanguage *language, TSStateId state);
+-}
+foreign import capi unsafe "tree_sitter/api.h ts_lookahead_iterator_reset"
+  ts_lookahead_iterator_reset ::
+    Ptr TSLookaheadIterator ->
+    ConstPtr TSLanguage ->
+    TSStateId ->
+    IO CBool
+
+{-|
+  Get the current language of the lookahead iterator.
+
+  > const TSLanguage *ts_lookahead_iterator_language(const TSLookaheadIterator *self);
+-}
+foreign import capi unsafe "tree_sitter/api.h ts_lookahead_iterator_language"
+  ts_lookahead_iterator_language ::
+    Ptr TSLookaheadIterator ->
+    IO (ConstPtr TSLanguage)
+
+{-|
+  Advance the lookahead iterator to the next symbol.
+
+  This returns @true@ if there is a new symbol and @false@ otherwise.
+
+  > bool ts_lookahead_iterator_next(TSLookaheadIterator *self);
+-}
+foreign import capi unsafe "tree_sitter/api.h ts_lookahead_iterator_next"
+  ts_lookahead_iterator_next ::
+    Ptr TSLookaheadIterator ->
+    IO CBool
+
+{-|
+  Get the current symbol of the lookahead iterator;
+
+  > TSSymbol ts_lookahead_iterator_current_symbol(const TSLookaheadIterator *self);
+-}
+foreign import capi unsafe "tree_sitter/api.h ts_lookahead_iterator_current_symbol"
+  ts_lookahead_iterator_current_symbol ::
+    ConstPtr TSLookaheadIterator ->
+    IO TSSymbol
+
+{-|
+  Get the current symbol type of the lookahead iterator as a null terminated
+  string.
+
+  > const char *ts_lookahead_iterator_current_symbol_name(const TSLookaheadIterator *self);
+-}
+foreign import capi unsafe "tree_sitter/api.h ts_lookahead_iterator_current_symbol_name"
+  ts_lookahead_iterator_current_symbol_name ::
+    ConstPtr TSLookaheadIterator ->
+    IO (ConstPtr CChar)
+
+{-------------------------------------}
+{- Section - WebAssembly Integration -}
+{-------------------------------------}
+
+-- def TREE_SITTER_FEATURE_WASM
+#ifdef TREE_SITTER_FEATURE_WASM
+
+{-|
+  > typedef struct wasm_engine_t TSWasmEngine;
+  -}
+data
+  {-# CTYPE "tree_sitter/api.h" "TSWasmEngine" #-}
+  TSWasmEngine
+
+{-|
+  > typedef struct TSWasmStore TSWasmStore;
+  -}
+data
+  {-# CTYPE "tree_sitter/api.h" "TSWasmStore" #-}
+  TSWasmStore
+
+{-|
+  > typedef enum {
+  >   TSWasmErrorKindNone = 0,
+  >   TSWasmErrorKindParse,
+  >   TSWasmErrorKindCompile,
+  >   TSWasmErrorKindInstantiate,
+  >   TSWasmErrorKindAllocate,
+  > } TSWasmErrorKind;
+  -}
+newtype
+  {-# CTYPE "tree_sitter/api.h" "TSWasmErrorKind" #-}
+  TSWasmErrorKind = TSWasmErrorKind
+    { unTSWasmErrorKind :: #{type TSWasmErrorKind}
+    }
+    deriving (Eq, Show)
+    deriving newtype (Storable)
+
+pattern TSWasmErrorKindNone :: TSWasmErrorKind
+pattern TSWasmErrorKindNone = TSWasmErrorKind ( #{const TSWasmErrorKindNone} )
+
+pattern TSWasmErrorKindParse :: TSWasmErrorKind
+pattern TSWasmErrorKindParse = TSWasmErrorKind ( #{const TSWasmErrorKindParse} )
+
+pattern TSWasmErrorKindCompile :: TSWasmErrorKind
+pattern TSWasmErrorKindCompile = TSWasmErrorKind ( #{const TSWasmErrorKindCompile} )
+
+pattern TSWasmErrorKindInstantiate :: TSWasmErrorKind
+pattern TSWasmErrorKindInstantiate = TSWasmErrorKind ( #{const TSWasmErrorKindInstantiate} )
+
+pattern TSWasmErrorKindAllocate :: TSWasmErrorKind
+pattern TSWasmErrorKindAllocate = TSWasmErrorKind ( #{const TSWasmErrorKindAllocate} )
+
+{-# COMPLETE TSWasmErrorKindNone, TSWasmErrorKindParse, TSWasmErrorKindCompile, TSWasmErrorKindInstantiate, TSWasmErrorKindAllocate #-}
+
+{-|
+  > typedef struct {
+  >   TSWasmErrorKind kind;
+  >   char *message;
+  > } TSWasmError;
+  -}
+data
+  {-# CTYPE "tree_sitter/api.h" "TSWasmError" #-}
+  TSWasmError = TSWasmError
+    { _kind :: {-# UNPACK #-} !TSWasmErrorKind
+    , _message :: {-# UNPACK #-} !ByteString
+    }
+
+peekTSWasmError :: Ptr TSWasmError -> IO TSWasmError
+peekTSWasmError ptr = do
+  _kind <- #{peek TSWasmError, kind} ptr
+  _message <- BS.packCString ( #{ptr TSWasmError, message} ptr )
+  return TSWasmError{..}
+
+withTSWasmError :: TSWasmError -> (Ptr TSWasmError -> IO a) -> IO a
+withTSWasmError TSWasmError{..} action = do
+  allocaBytesAligned @TSWasmError ( #{size TSWasmError} ) ( #{alignment TSWasmError} ) $ \ptr -> do
+    #{poke TSWasmError, kind} ptr _kind
+    BS.useAsCString _message $ \_message_p -> do
+      #{poke TSWasmError, message} ptr _message_p
+      action ptr
+
+{-|
+  Create a Wasm store.
+
+  > TSWasmStore *ts_wasm_store_new(
+  >   TSWasmEngine *engine,
+  >   TSWasmError *error
+  > );
+-}
+foreign import capi unsafe "tree_sitter/api.h ts_wasm_store_new"
+  ts_wasm_store_new ::
+    Ptr TSWasmEngine ->
+    Ptr TSWasmError ->
+    IO (Ptr TSWasmStore)
+
+{-|
+  Free the memory associated with the given Wasm store.
+
+  > void ts_wasm_store_delete(TSWasmStore *);
+-}
+foreign import capi unsafe "tree_sitter/api.h ts_wasm_store_delete"
+  ts_wasm_store_delete ::
+    Ptr TSWasmStore ->
+    IO ()
+
+{-| C function pointer to @`ts_wasm_store_delete`@.
+ -}
+foreign import capi unsafe "tree_sitter/api.h &ts_wasm_store_delete"
+  p_ts_wasm_store_delete ::
+    FunPtr (
+      Ptr TSWasmStore ->
+      IO ()
+    )
+
+{-|
+  Create a language from a buffer of Wasm. The resulting language behaves
+  like any other Tree-sitter language, except that in order to use it with
+  a parser, that parser must have a Wasm store. Note that the language
+  can be used with any Wasm store, it doesn't need to be the same store that
+  was used to originally load it.
+
+  > const TSLanguage *ts_wasm_store_load_language(
+  >   TSWasmStore *,
+  >   const char *name,
+  >   const char *wasm,
+  >   uint32_t wasm_len,
+  >   TSWasmError *error
+  > );
+-}
+foreign import capi unsafe "tree_sitter/api.h ts_wasm_store_load_language"
+  ts_wasm_store_load_language ::
+    Ptr TSWasmStore ->
+    ConstPtr CChar ->
+    ConstPtr CChar ->
+    ( #{type uint32_t} ) ->
+    Ptr TSWasmError ->
+    IO (ConstPtr TSLanguage)
+
+{-|
+  Get the number of languages instantiated in the given wasm store.
+
+  > size_t ts_wasm_store_language_count(const TSWasmStore *);
+-}
+foreign import capi unsafe "tree_sitter/api.h ts_wasm_store_language_count"
+  ts_wasm_store_language_count ::
+    ConstPtr TSWasmStore ->
+    IO CSize
+
+{-|
+  Check if the language came from a Wasm module. If so, then in order to use
+  this language with a Parser, that parser must have a Wasm store assigned.
+
+  > bool ts_language_is_wasm(const TSLanguage *);
+-}
+foreign import capi unsafe "tree_sitter/api.h ts_language_is_wasm"
+  ts_language_is_wasm ::
+    ConstPtr TSLanguage ->
+    IO CBool
+
+{-|
+  Assign the given Wasm store to the parser. A parser must have a Wasm store
+  in order to use Wasm languages.
+
+  > void ts_parser_set_wasm_store(TSParser *, TSWasmStore *);
+-}
+foreign import capi unsafe "tree_sitter/api.h ts_parser_set_wasm_store"
+  ts_parser_set_wasm_store ::
+    Ptr TSParser ->
+    Ptr TSWasmStore ->
+    IO ()
+
+{-|
+  Remove the parser's current Wasm store and return it. This returns @NULL@ if
+  the parser doesn't have a Wasm store.
+
+  > TSWasmStore *ts_parser_take_wasm_store(TSParser *);
+-}
+foreign import capi unsafe "tree_sitter/api.h ts_parser_take_wasm_store"
+  ts_parser_take_wasm_store ::
+    Ptr TSParser ->
+    IO (Ptr TSWasmStore)
+
+-- end TREE_SITTER_FEATURE_WASM
+#endif
+
+{----------------------------------}
+{- Section - Global Configuration -}
+{----------------------------------}
+
+{-|
+  Set the allocation functions used by the library.
+
+  By default, Tree-sitter uses the standard libc allocation functions,
+  but aborts the process when an allocation fails. This function lets
+  you supply alternative allocation functions at runtime.
+
+  If you pass @NULL@ for any parameter, Tree-sitter will switch back to
+  its default implementation of that function.
+
+  If you call this function after the library has already been used, then
+  you must ensure that either:
+
+    1. All the existing objects have been freed.
+    2. The new allocator shares its state with the old one, so it is capable of freeing memory that was allocated by the old allocator.
+
+  > void ts_set_allocator(
+  >   void *(*new_malloc)(size_t),
+  >   void *(*new_calloc)(size_t, size_t),
+  >   void *(*new_realloc)(void *, size_t),
+  >   void (*new_free)(void *)
+  > );
+-}
+foreign import capi unsafe "tree_sitter/api.h ts_set_allocator"
+  ts_set_allocator ::
+    FunPtr (CSize -> IO ()) ->
+    FunPtr (CSize -> CSize -> IO ()) ->
+    FunPtr (Ptr a -> CSize -> IO ()) ->
+    FunPtr (Ptr a -> IO ()) ->
+    IO ()
diff --git a/test/Main.hs b/test/Main.hs
new file mode 100644
--- /dev/null
+++ b/test/Main.hs
@@ -0,0 +1,11 @@
+-- | Test suite for @tree-sitter-capi@.
+module Main where
+
+import Test.Tasty (defaultMain, testGroup)
+import Test.TreeSitter.CApi qualified as CApi
+
+-- | All tests for @tree-sitter-capi@.
+main :: IO ()
+main = do
+  defaultMain $
+    testGroup "TreeSitter" [CApi.tests]
diff --git a/test/Test/TreeSitter/CApi.hs b/test/Test/TreeSitter/CApi.hs
new file mode 100644
--- /dev/null
+++ b/test/Test/TreeSitter/CApi.hs
@@ -0,0 +1,77 @@
+{-|
+Tests for `TreeSitter.CApi`.
+-}
+module Test.TreeSitter.CApi where
+
+import Control.Exception (bracket)
+import Control.Monad (when)
+import Data.Foldable (for_)
+import Foreign (castPtr, nullPtr)
+import Foreign.C (withCStringLen)
+import Foreign.C.ConstPtr.Compat (ConstPtr (..))
+import Test.Tasty (TestTree, testGroup)
+import Test.Tasty.HUnit (testCase, (@=?))
+import TreeSitter.CApi (
+  TSStateId (..),
+  ts_language_delete,
+  ts_language_state_count,
+  ts_lookahead_iterator_current_symbol,
+  ts_lookahead_iterator_delete,
+  ts_lookahead_iterator_new,
+  ts_lookahead_iterator_next,
+  ts_parser_delete,
+  ts_parser_new,
+  ts_parser_parse_string,
+ )
+import TreeSitter.While (tree_sitter_while)
+
+-- | All tests for `TreeSitter.CApi`.
+tests :: TestTree
+tests =
+  testGroup
+    "CApi"
+    [ test_ts_lookaheaditerator
+    , test_ts_language_delete
+    , test_ts_parser_parse_fails_without_language
+    ]
+
+-- | Does the lookahead iterator work?
+test_ts_lookaheaditerator :: TestTree
+test_ts_lookaheaditerator =
+  testCase "test_ts_lookaheaditerator" $ do
+    language <- castConstPtr <$> tree_sitter_while
+    stateCount <- ts_language_state_count language
+    for_ [0 .. stateCount - 1] $ \stateId -> do
+      lookaheadIterator <- ts_lookahead_iterator_new language (TSStateId . fromIntegral $ stateId)
+      let loop = do
+            _currentSymbol <- ts_lookahead_iterator_current_symbol (ConstPtr lookaheadIterator)
+            success <- ts_lookahead_iterator_next lookaheadIterator
+            when (success >= 1) loop
+      loop
+      ts_lookahead_iterator_delete lookaheadIterator
+
+-- | Is deleting a @`TreeSitter.CApi.TSLanguage`@ multiple times safe?
+test_ts_language_delete :: TestTree
+test_ts_language_delete =
+  testCase "ts_language_delete" $ do
+    language <- castConstPtr <$> tree_sitter_while
+    ts_language_delete language
+    ts_language_delete language
+
+-- | Does @`ts_parser_parse_string`@ return @NULL@ when the parser does not have a language assigned.
+test_ts_parser_parse_fails_without_language :: TestTree
+test_ts_parser_parse_fails_without_language =
+  testCase "test_ts_parser_parse fails without language" $ do
+    bracket ts_parser_new ts_parser_delete $ \ts_parser ->
+      withCStringLen "" $ \(string, string_length) -> do
+        tree_p <-
+          ts_parser_parse_string
+            ts_parser
+            (ConstPtr nullPtr)
+            (ConstPtr string)
+            (fromIntegral string_length)
+        nullPtr @=? tree_p
+
+-- | Internal helper: Cast a t`ConstPtr` using `castPtr`.
+castConstPtr :: ConstPtr a -> ConstPtr b
+castConstPtr = ConstPtr . castPtr . unConstPtr
diff --git a/vendor/tree-sitter/lib/include/tree_sitter/api.h b/vendor/tree-sitter/lib/include/tree_sitter/api.h
new file mode 100644
--- /dev/null
+++ b/vendor/tree-sitter/lib/include/tree_sitter/api.h
@@ -0,0 +1,1317 @@
+#ifndef TREE_SITTER_API_H_
+#define TREE_SITTER_API_H_
+
+#ifndef TREE_SITTER_HIDE_SYMBOLS
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC visibility push(default)
+#endif
+#endif
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <stdbool.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/****************************/
+/* Section - ABI Versioning */
+/****************************/
+
+/**
+ * The latest ABI version that is supported by the current version of the
+ * library. When Languages are generated by the Tree-sitter CLI, they are
+ * assigned an ABI version number that corresponds to the current CLI version.
+ * The Tree-sitter library is generally backwards-compatible with languages
+ * generated using older CLI versions, but is not forwards-compatible.
+ */
+#define TREE_SITTER_LANGUAGE_VERSION 14
+
+/**
+ * The earliest ABI version that is supported by the current version of the
+ * library.
+ */
+#define TREE_SITTER_MIN_COMPATIBLE_LANGUAGE_VERSION 13
+
+/*******************/
+/* Section - Types */
+/*******************/
+
+typedef uint16_t TSStateId;
+typedef uint16_t TSSymbol;
+typedef uint16_t TSFieldId;
+typedef struct TSLanguage TSLanguage;
+typedef struct TSParser TSParser;
+typedef struct TSTree TSTree;
+typedef struct TSQuery TSQuery;
+typedef struct TSQueryCursor TSQueryCursor;
+typedef struct TSLookaheadIterator TSLookaheadIterator;
+
+typedef enum TSInputEncoding {
+  TSInputEncodingUTF8,
+  TSInputEncodingUTF16,
+} TSInputEncoding;
+
+typedef enum TSSymbolType {
+  TSSymbolTypeRegular,
+  TSSymbolTypeAnonymous,
+  TSSymbolTypeSupertype,
+  TSSymbolTypeAuxiliary,
+} TSSymbolType;
+
+typedef struct TSPoint {
+  uint32_t row;
+  uint32_t column;
+} TSPoint;
+
+typedef struct TSRange {
+  TSPoint start_point;
+  TSPoint end_point;
+  uint32_t start_byte;
+  uint32_t end_byte;
+} TSRange;
+
+typedef struct TSInput {
+  void *payload;
+  const char *(*read)(void *payload, uint32_t byte_index, TSPoint position, uint32_t *bytes_read);
+  TSInputEncoding encoding;
+} TSInput;
+
+typedef enum TSLogType {
+  TSLogTypeParse,
+  TSLogTypeLex,
+} TSLogType;
+
+typedef struct TSLogger {
+  void *payload;
+  void (*log)(void *payload, TSLogType log_type, const char *buffer);
+} TSLogger;
+
+typedef struct TSInputEdit {
+  uint32_t start_byte;
+  uint32_t old_end_byte;
+  uint32_t new_end_byte;
+  TSPoint start_point;
+  TSPoint old_end_point;
+  TSPoint new_end_point;
+} TSInputEdit;
+
+typedef struct TSNode {
+  uint32_t context[4];
+  const void *id;
+  const TSTree *tree;
+} TSNode;
+
+typedef struct TSTreeCursor {
+  const void *tree;
+  const void *id;
+  uint32_t context[3];
+} TSTreeCursor;
+
+typedef struct TSQueryCapture {
+  TSNode node;
+  uint32_t index;
+} TSQueryCapture;
+
+typedef enum TSQuantifier {
+  TSQuantifierZero = 0, // must match the array initialization value
+  TSQuantifierZeroOrOne,
+  TSQuantifierZeroOrMore,
+  TSQuantifierOne,
+  TSQuantifierOneOrMore,
+} TSQuantifier;
+
+typedef struct TSQueryMatch {
+  uint32_t id;
+  uint16_t pattern_index;
+  uint16_t capture_count;
+  const TSQueryCapture *captures;
+} TSQueryMatch;
+
+typedef enum TSQueryPredicateStepType {
+  TSQueryPredicateStepTypeDone,
+  TSQueryPredicateStepTypeCapture,
+  TSQueryPredicateStepTypeString,
+} TSQueryPredicateStepType;
+
+typedef struct TSQueryPredicateStep {
+  TSQueryPredicateStepType type;
+  uint32_t value_id;
+} TSQueryPredicateStep;
+
+typedef enum TSQueryError {
+  TSQueryErrorNone = 0,
+  TSQueryErrorSyntax,
+  TSQueryErrorNodeType,
+  TSQueryErrorField,
+  TSQueryErrorCapture,
+  TSQueryErrorStructure,
+  TSQueryErrorLanguage,
+} TSQueryError;
+
+/********************/
+/* Section - Parser */
+/********************/
+
+/**
+ * Create a new parser.
+ */
+TSParser *ts_parser_new(void);
+
+/**
+ * Delete the parser, freeing all of the memory that it used.
+ */
+void ts_parser_delete(TSParser *self);
+
+/**
+ * Get the parser's current language.
+ */
+const TSLanguage *ts_parser_language(const TSParser *self);
+
+/**
+ * Set the language that the parser should use for parsing.
+ *
+ * Returns a boolean indicating whether or not the language was successfully
+ * assigned. True means assignment succeeded. False means there was a version
+ * mismatch: the language was generated with an incompatible version of the
+ * Tree-sitter CLI. Check the language's version using [`ts_language_version`]
+ * and compare it to this library's [`TREE_SITTER_LANGUAGE_VERSION`] and
+ * [`TREE_SITTER_MIN_COMPATIBLE_LANGUAGE_VERSION`] constants.
+ */
+bool ts_parser_set_language(TSParser *self, const TSLanguage *language);
+
+/**
+ * Set the ranges of text that the parser should include when parsing.
+ *
+ * By default, the parser will always include entire documents. This function
+ * allows you to parse only a *portion* of a document but still return a syntax
+ * tree whose ranges match up with the document as a whole. You can also pass
+ * multiple disjoint ranges.
+ *
+ * The second and third parameters specify the location and length of an array
+ * of ranges. The parser does *not* take ownership of these ranges; it copies
+ * the data, so it doesn't matter how these ranges are allocated.
+ *
+ * If `count` is zero, then the entire document will be parsed. Otherwise,
+ * the given ranges must be ordered from earliest to latest in the document,
+ * and they must not overlap. That is, the following must hold for all:
+ *
+ * `i < count - 1`: `ranges[i].end_byte <= ranges[i + 1].start_byte`
+ *
+ * If this requirement is not satisfied, the operation will fail, the ranges
+ * will not be assigned, and this function will return `false`. On success,
+ * this function returns `true`
+ */
+bool ts_parser_set_included_ranges(
+  TSParser *self,
+  const TSRange *ranges,
+  uint32_t count
+);
+
+/**
+ * Get the ranges of text that the parser will include when parsing.
+ *
+ * The returned pointer is owned by the parser. The caller should not free it
+ * or write to it. The length of the array will be written to the given
+ * `count` pointer.
+ */
+const TSRange *ts_parser_included_ranges(
+  const TSParser *self,
+  uint32_t *count
+);
+
+/**
+ * Use the parser to parse some source code and create a syntax tree.
+ *
+ * If you are parsing this document for the first time, pass `NULL` for the
+ * `old_tree` parameter. Otherwise, if you have already parsed an earlier
+ * version of this document and the document has since been edited, pass the
+ * previous syntax tree so that the unchanged parts of it can be reused.
+ * This will save time and memory. For this to work correctly, you must have
+ * already edited the old syntax tree using the [`ts_tree_edit`] function in a
+ * way that exactly matches the source code changes.
+ *
+ * The [`TSInput`] parameter lets you specify how to read the text. It has the
+ * following three fields:
+ * 1. [`read`]: A function to retrieve a chunk of text at a given byte offset
+ *    and (row, column) position. The function should return a pointer to the
+ *    text and write its length to the [`bytes_read`] pointer. The parser does
+ *    not take ownership of this buffer; it just borrows it until it has
+ *    finished reading it. The function should write a zero value to the
+ *    [`bytes_read`] pointer to indicate the end of the document.
+ * 2. [`payload`]: An arbitrary pointer that will be passed to each invocation
+ *    of the [`read`] function.
+ * 3. [`encoding`]: An indication of how the text is encoded. Either
+ *    `TSInputEncodingUTF8` or `TSInputEncodingUTF16`.
+ *
+ * This function returns a syntax tree on success, and `NULL` on failure. There
+ * are three possible reasons for failure:
+ * 1. The parser does not have a language assigned. Check for this using the
+      [`ts_parser_language`] function.
+ * 2. Parsing was cancelled due to a timeout that was set by an earlier call to
+ *    the [`ts_parser_set_timeout_micros`] function. You can resume parsing from
+ *    where the parser left out by calling [`ts_parser_parse`] again with the
+ *    same arguments. Or you can start parsing from scratch by first calling
+ *    [`ts_parser_reset`].
+ * 3. Parsing was cancelled using a cancellation flag that was set by an
+ *    earlier call to [`ts_parser_set_cancellation_flag`]. You can resume parsing
+ *    from where the parser left out by calling [`ts_parser_parse`] again with
+ *    the same arguments.
+ *
+ * [`read`]: TSInput::read
+ * [`payload`]: TSInput::payload
+ * [`encoding`]: TSInput::encoding
+ * [`bytes_read`]: TSInput::read
+ */
+TSTree *ts_parser_parse(
+  TSParser *self,
+  const TSTree *old_tree,
+  TSInput input
+);
+
+/**
+ * Use the parser to parse some source code stored in one contiguous buffer.
+ * The first two parameters are the same as in the [`ts_parser_parse`] function
+ * above. The second two parameters indicate the location of the buffer and its
+ * length in bytes.
+ */
+TSTree *ts_parser_parse_string(
+  TSParser *self,
+  const TSTree *old_tree,
+  const char *string,
+  uint32_t length
+);
+
+/**
+ * Use the parser to parse some source code stored in one contiguous buffer with
+ * a given encoding. The first four parameters work the same as in the
+ * [`ts_parser_parse_string`] method above. The final parameter indicates whether
+ * the text is encoded as UTF8 or UTF16.
+ */
+TSTree *ts_parser_parse_string_encoding(
+  TSParser *self,
+  const TSTree *old_tree,
+  const char *string,
+  uint32_t length,
+  TSInputEncoding encoding
+);
+
+/**
+ * Instruct the parser to start the next parse from the beginning.
+ *
+ * If the parser previously failed because of a timeout or a cancellation, then
+ * by default, it will resume where it left off on the next call to
+ * [`ts_parser_parse`] or other parsing functions. If you don't want to resume,
+ * and instead intend to use this parser to parse some other document, you must
+ * call [`ts_parser_reset`] first.
+ */
+void ts_parser_reset(TSParser *self);
+
+/**
+ * Set the maximum duration in microseconds that parsing should be allowed to
+ * take before halting.
+ *
+ * If parsing takes longer than this, it will halt early, returning NULL.
+ * See [`ts_parser_parse`] for more information.
+ */
+void ts_parser_set_timeout_micros(TSParser *self, uint64_t timeout_micros);
+
+/**
+ * Get the duration in microseconds that parsing is allowed to take.
+ */
+uint64_t ts_parser_timeout_micros(const TSParser *self);
+
+/**
+ * Set the parser's current cancellation flag pointer.
+ *
+ * If a non-null pointer is assigned, then the parser will periodically read
+ * from this pointer during parsing. If it reads a non-zero value, it will
+ * halt early, returning NULL. See [`ts_parser_parse`] for more information.
+ */
+void ts_parser_set_cancellation_flag(TSParser *self, const size_t *flag);
+
+/**
+ * Get the parser's current cancellation flag pointer.
+ */
+const size_t *ts_parser_cancellation_flag(const TSParser *self);
+
+/**
+ * Set the logger that a parser should use during parsing.
+ *
+ * The parser does not take ownership over the logger payload. If a logger was
+ * previously assigned, the caller is responsible for releasing any memory
+ * owned by the previous logger.
+ */
+void ts_parser_set_logger(TSParser *self, TSLogger logger);
+
+/**
+ * Get the parser's current logger.
+ */
+TSLogger ts_parser_logger(const TSParser *self);
+
+/**
+ * Set the file descriptor to which the parser should write debugging graphs
+ * during parsing. The graphs are formatted in the DOT language. You may want
+ * to pipe these graphs directly to a `dot(1)` process in order to generate
+ * SVG output. You can turn off this logging by passing a negative number.
+ */
+void ts_parser_print_dot_graphs(TSParser *self, int fd);
+
+/******************/
+/* Section - Tree */
+/******************/
+
+/**
+ * Create a shallow copy of the syntax tree. This is very fast.
+ *
+ * You need to copy a syntax tree in order to use it on more than one thread at
+ * a time, as syntax trees are not thread safe.
+ */
+TSTree *ts_tree_copy(const TSTree *self);
+
+/**
+ * Delete the syntax tree, freeing all of the memory that it used.
+ */
+void ts_tree_delete(TSTree *self);
+
+/**
+ * Get the root node of the syntax tree.
+ */
+TSNode ts_tree_root_node(const TSTree *self);
+
+/**
+ * Get the root node of the syntax tree, but with its position
+ * shifted forward by the given offset.
+ */
+TSNode ts_tree_root_node_with_offset(
+  const TSTree *self,
+  uint32_t offset_bytes,
+  TSPoint offset_extent
+);
+
+/**
+ * Get the language that was used to parse the syntax tree.
+ */
+const TSLanguage *ts_tree_language(const TSTree *self);
+
+/**
+ * Get the array of included ranges that was used to parse the syntax tree.
+ *
+ * The returned pointer must be freed by the caller.
+ */
+TSRange *ts_tree_included_ranges(const TSTree *self, uint32_t *length);
+
+/**
+ * Edit the syntax tree to keep it in sync with source code that has been
+ * edited.
+ *
+ * You must describe the edit both in terms of byte offsets and in terms of
+ * (row, column) coordinates.
+ */
+void ts_tree_edit(TSTree *self, const TSInputEdit *edit);
+
+/**
+ * Compare an old edited syntax tree to a new syntax tree representing the same
+ * document, returning an array of ranges whose syntactic structure has changed.
+ *
+ * For this to work correctly, the old syntax tree must have been edited such
+ * that its ranges match up to the new tree. Generally, you'll want to call
+ * this function right after calling one of the [`ts_parser_parse`] functions.
+ * You need to pass the old tree that was passed to parse, as well as the new
+ * tree that was returned from that function.
+ *
+ * The returned array is allocated using `malloc` and the caller is responsible
+ * for freeing it using `free`. The length of the array will be written to the
+ * given `length` pointer.
+ */
+TSRange *ts_tree_get_changed_ranges(
+  const TSTree *old_tree,
+  const TSTree *new_tree,
+  uint32_t *length
+);
+
+/**
+ * Write a DOT graph describing the syntax tree to the given file.
+ */
+void ts_tree_print_dot_graph(const TSTree *self, int file_descriptor);
+
+/******************/
+/* Section - Node */
+/******************/
+
+/**
+ * Get the node's type as a null-terminated string.
+ */
+const char *ts_node_type(TSNode self);
+
+/**
+ * Get the node's type as a numerical id.
+ */
+TSSymbol ts_node_symbol(TSNode self);
+
+/**
+ * Get the node's language.
+ */
+const TSLanguage *ts_node_language(TSNode self);
+
+/**
+ * Get the node's type as it appears in the grammar ignoring aliases as a
+ * null-terminated string.
+ */
+const char *ts_node_grammar_type(TSNode self);
+
+/**
+ * Get the node's type as a numerical id as it appears in the grammar ignoring
+ * aliases. This should be used in [`ts_language_next_state`] instead of
+ * [`ts_node_symbol`].
+ */
+TSSymbol ts_node_grammar_symbol(TSNode self);
+
+/**
+ * Get the node's start byte.
+ */
+uint32_t ts_node_start_byte(TSNode self);
+
+/**
+ * Get the node's start position in terms of rows and columns.
+ */
+TSPoint ts_node_start_point(TSNode self);
+
+/**
+ * Get the node's end byte.
+ */
+uint32_t ts_node_end_byte(TSNode self);
+
+/**
+ * Get the node's end position in terms of rows and columns.
+ */
+TSPoint ts_node_end_point(TSNode self);
+
+/**
+ * Get an S-expression representing the node as a string.
+ *
+ * This string is allocated with `malloc` and the caller is responsible for
+ * freeing it using `free`.
+ */
+char *ts_node_string(TSNode self);
+
+/**
+ * Check if the node is null. Functions like [`ts_node_child`] and
+ * [`ts_node_next_sibling`] will return a null node to indicate that no such node
+ * was found.
+ */
+bool ts_node_is_null(TSNode self);
+
+/**
+ * Check if the node is *named*. Named nodes correspond to named rules in the
+ * grammar, whereas *anonymous* nodes correspond to string literals in the
+ * grammar.
+ */
+bool ts_node_is_named(TSNode self);
+
+/**
+ * Check if the node is *missing*. Missing nodes are inserted by the parser in
+ * order to recover from certain kinds of syntax errors.
+ */
+bool ts_node_is_missing(TSNode self);
+
+/**
+ * Check if the node is *extra*. Extra nodes represent things like comments,
+ * which are not required the grammar, but can appear anywhere.
+ */
+bool ts_node_is_extra(TSNode self);
+
+/**
+ * Check if a syntax node has been edited.
+ */
+bool ts_node_has_changes(TSNode self);
+
+/**
+ * Check if the node is a syntax error or contains any syntax errors.
+ */
+bool ts_node_has_error(TSNode self);
+
+/**
+ * Check if the node is a syntax error.
+*/
+bool ts_node_is_error(TSNode self);
+
+/**
+ * Get this node's parse state.
+*/
+TSStateId ts_node_parse_state(TSNode self);
+
+/**
+ * Get the parse state after this node.
+*/
+TSStateId ts_node_next_parse_state(TSNode self);
+
+/**
+ * Get the node's immediate parent.
+ * Prefer [`ts_node_child_containing_descendant`] for
+ * iterating over the node's ancestors.
+ */
+TSNode ts_node_parent(TSNode self);
+
+/**
+ * @deprecated use [`ts_node_contains_descendant`] instead, this will be removed in 0.25
+ *
+ * Get the node's child containing `descendant`. This will not return
+ * the descendant if it is a direct child of `self`, for that use
+ * `ts_node_contains_descendant`.
+ */
+TSNode ts_node_child_containing_descendant(TSNode self, TSNode descendant);
+
+/**
+ * Get the node that contains `descendant`.
+ *
+ * Note that this can return `descendant` itself, unlike the deprecated function
+ * [`ts_node_child_containing_descendant`].
+ */
+TSNode ts_node_child_with_descendant(TSNode self, TSNode descendant);
+
+/**
+ * Get the node's child at the given index, where zero represents the first
+ * child.
+ */
+TSNode ts_node_child(TSNode self, uint32_t child_index);
+
+/**
+ * Get the field name for node's child at the given index, where zero represents
+ * the first child. Returns NULL, if no field is found.
+ */
+const char *ts_node_field_name_for_child(TSNode self, uint32_t child_index);
+
+/**
+ * Get the field name for node's named child at the given index, where zero
+ * represents the first named child. Returns NULL, if no field is found.
+ */
+const char *ts_node_field_name_for_named_child(TSNode self, uint32_t named_child_index);
+
+/**
+ * Get the node's number of children.
+ */
+uint32_t ts_node_child_count(TSNode self);
+
+/**
+ * Get the node's *named* child at the given index.
+ *
+ * See also [`ts_node_is_named`].
+ */
+TSNode ts_node_named_child(TSNode self, uint32_t child_index);
+
+/**
+ * Get the node's number of *named* children.
+ *
+ * See also [`ts_node_is_named`].
+ */
+uint32_t ts_node_named_child_count(TSNode self);
+
+/**
+ * Get the node's child with the given field name.
+ */
+TSNode ts_node_child_by_field_name(
+  TSNode self,
+  const char *name,
+  uint32_t name_length
+);
+
+/**
+ * Get the node's child with the given numerical field id.
+ *
+ * You can convert a field name to an id using the
+ * [`ts_language_field_id_for_name`] function.
+ */
+TSNode ts_node_child_by_field_id(TSNode self, TSFieldId field_id);
+
+/**
+ * Get the node's next / previous sibling.
+ */
+TSNode ts_node_next_sibling(TSNode self);
+TSNode ts_node_prev_sibling(TSNode self);
+
+/**
+ * Get the node's next / previous *named* sibling.
+ */
+TSNode ts_node_next_named_sibling(TSNode self);
+TSNode ts_node_prev_named_sibling(TSNode self);
+
+/**
+ * Get the node's first child that extends beyond the given byte offset.
+ */
+TSNode ts_node_first_child_for_byte(TSNode self, uint32_t byte);
+
+/**
+ * Get the node's first named child that extends beyond the given byte offset.
+ */
+TSNode ts_node_first_named_child_for_byte(TSNode self, uint32_t byte);
+
+/**
+ * Get the node's number of descendants, including one for the node itself.
+ */
+uint32_t ts_node_descendant_count(TSNode self);
+
+/**
+ * Get the smallest node within this node that spans the given range of bytes
+ * or (row, column) positions.
+ */
+TSNode ts_node_descendant_for_byte_range(TSNode self, uint32_t start, uint32_t end);
+TSNode ts_node_descendant_for_point_range(TSNode self, TSPoint start, TSPoint end);
+
+/**
+ * Get the smallest named node within this node that spans the given range of
+ * bytes or (row, column) positions.
+ */
+TSNode ts_node_named_descendant_for_byte_range(TSNode self, uint32_t start, uint32_t end);
+TSNode ts_node_named_descendant_for_point_range(TSNode self, TSPoint start, TSPoint end);
+
+/**
+ * Edit the node to keep it in-sync with source code that has been edited.
+ *
+ * This function is only rarely needed. When you edit a syntax tree with the
+ * [`ts_tree_edit`] function, all of the nodes that you retrieve from the tree
+ * afterward will already reflect the edit. You only need to use [`ts_node_edit`]
+ * when you have a [`TSNode`] instance that you want to keep and continue to use
+ * after an edit.
+ */
+void ts_node_edit(TSNode *self, const TSInputEdit *edit);
+
+/**
+ * Check if two nodes are identical.
+ */
+bool ts_node_eq(TSNode self, TSNode other);
+
+/************************/
+/* Section - TreeCursor */
+/************************/
+
+/**
+ * Create a new tree cursor starting from the given node.
+ *
+ * A tree cursor allows you to walk a syntax tree more efficiently than is
+ * possible using the [`TSNode`] functions. It is a mutable object that is always
+ * on a certain syntax node, and can be moved imperatively to different nodes.
+ */
+TSTreeCursor ts_tree_cursor_new(TSNode node);
+
+/**
+ * Delete a tree cursor, freeing all of the memory that it used.
+ */
+void ts_tree_cursor_delete(TSTreeCursor *self);
+
+/**
+ * Re-initialize a tree cursor to start at the original node that the cursor was
+ * constructed with.
+ */
+void ts_tree_cursor_reset(TSTreeCursor *self, TSNode node);
+
+/**
+ * Re-initialize a tree cursor to the same position as another cursor.
+ *
+ * Unlike [`ts_tree_cursor_reset`], this will not lose parent information and
+ * allows reusing already created cursors.
+*/
+void ts_tree_cursor_reset_to(TSTreeCursor *dst, const TSTreeCursor *src);
+
+/**
+ * Get the tree cursor's current node.
+ */
+TSNode ts_tree_cursor_current_node(const TSTreeCursor *self);
+
+/**
+ * Get the field name of the tree cursor's current node.
+ *
+ * This returns `NULL` if the current node doesn't have a field.
+ * See also [`ts_node_child_by_field_name`].
+ */
+const char *ts_tree_cursor_current_field_name(const TSTreeCursor *self);
+
+/**
+ * Get the field id of the tree cursor's current node.
+ *
+ * This returns zero if the current node doesn't have a field.
+ * See also [`ts_node_child_by_field_id`], [`ts_language_field_id_for_name`].
+ */
+TSFieldId ts_tree_cursor_current_field_id(const TSTreeCursor *self);
+
+/**
+ * Move the cursor to the parent of its current node.
+ *
+ * This returns `true` if the cursor successfully moved, and returns `false`
+ * if there was no parent node (the cursor was already on the root node).
+ */
+bool ts_tree_cursor_goto_parent(TSTreeCursor *self);
+
+/**
+ * Move the cursor to the next sibling of its current node.
+ *
+ * This returns `true` if the cursor successfully moved, and returns `false`
+ * if there was no next sibling node.
+ */
+bool ts_tree_cursor_goto_next_sibling(TSTreeCursor *self);
+
+/**
+ * Move the cursor to the previous sibling of its current node.
+ *
+ * This returns `true` if the cursor successfully moved, and returns `false` if
+ * there was no previous sibling node.
+ *
+ * Note, that this function may be slower than
+ * [`ts_tree_cursor_goto_next_sibling`] due to how node positions are stored. In
+ * the worst case, this will need to iterate through all the children upto the
+ * previous sibling node to recalculate its position.
+ */
+bool ts_tree_cursor_goto_previous_sibling(TSTreeCursor *self);
+
+/**
+ * Move the cursor to the first child of its current node.
+ *
+ * This returns `true` if the cursor successfully moved, and returns `false`
+ * if there were no children.
+ */
+bool ts_tree_cursor_goto_first_child(TSTreeCursor *self);
+
+/**
+ * Move the cursor to the last child of its current node.
+ *
+ * This returns `true` if the cursor successfully moved, and returns `false` if
+ * there were no children.
+ *
+ * Note that this function may be slower than [`ts_tree_cursor_goto_first_child`]
+ * because it needs to iterate through all the children to compute the child's
+ * position.
+ */
+bool ts_tree_cursor_goto_last_child(TSTreeCursor *self);
+
+/**
+ * Move the cursor to the node that is the nth descendant of
+ * the original node that the cursor was constructed with, where
+ * zero represents the original node itself.
+ */
+void ts_tree_cursor_goto_descendant(TSTreeCursor *self, uint32_t goal_descendant_index);
+
+/**
+ * Get the index of the cursor's current node out of all of the
+ * descendants of the original node that the cursor was constructed with.
+ */
+uint32_t ts_tree_cursor_current_descendant_index(const TSTreeCursor *self);
+
+/**
+ * Get the depth of the cursor's current node relative to the original
+ * node that the cursor was constructed with.
+ */
+uint32_t ts_tree_cursor_current_depth(const TSTreeCursor *self);
+
+/**
+ * Move the cursor to the first child of its current node that extends beyond
+ * the given byte offset or point.
+ *
+ * This returns the index of the child node if one was found, and returns -1
+ * if no such child was found.
+ */
+int64_t ts_tree_cursor_goto_first_child_for_byte(TSTreeCursor *self, uint32_t goal_byte);
+int64_t ts_tree_cursor_goto_first_child_for_point(TSTreeCursor *self, TSPoint goal_point);
+
+TSTreeCursor ts_tree_cursor_copy(const TSTreeCursor *cursor);
+
+/*******************/
+/* Section - Query */
+/*******************/
+
+/**
+ * Create a new query from a string containing one or more S-expression
+ * patterns. The query is associated with a particular language, and can
+ * only be run on syntax nodes parsed with that language.
+ *
+ * If all of the given patterns are valid, this returns a [`TSQuery`].
+ * If a pattern is invalid, this returns `NULL`, and provides two pieces
+ * of information about the problem:
+ * 1. The byte offset of the error is written to the `error_offset` parameter.
+ * 2. The type of error is written to the `error_type` parameter.
+ */
+TSQuery *ts_query_new(
+  const TSLanguage *language,
+  const char *source,
+  uint32_t source_len,
+  uint32_t *error_offset,
+  TSQueryError *error_type
+);
+
+/**
+ * Delete a query, freeing all of the memory that it used.
+ */
+void ts_query_delete(TSQuery *self);
+
+/**
+ * Get the number of patterns, captures, or string literals in the query.
+ */
+uint32_t ts_query_pattern_count(const TSQuery *self);
+uint32_t ts_query_capture_count(const TSQuery *self);
+uint32_t ts_query_string_count(const TSQuery *self);
+
+/**
+ * Get the byte offset where the given pattern starts in the query's source.
+ *
+ * This can be useful when combining queries by concatenating their source
+ * code strings.
+ */
+uint32_t ts_query_start_byte_for_pattern(const TSQuery *self, uint32_t pattern_index);
+
+/**
+ * Get the byte offset where the given pattern ends in the query's source.
+ *
+ * This can be useful when combining queries by concatenating their source
+ * code strings.
+ */
+uint32_t ts_query_end_byte_for_pattern(const TSQuery *self, uint32_t pattern_index);
+
+/**
+ * Get all of the predicates for the given pattern in the query.
+ *
+ * The predicates are represented as a single array of steps. There are three
+ * types of steps in this array, which correspond to the three legal values for
+ * the `type` field:
+ * - `TSQueryPredicateStepTypeCapture` - Steps with this type represent names
+ *    of captures. Their `value_id` can be used with the
+ *   [`ts_query_capture_name_for_id`] function to obtain the name of the capture.
+ * - `TSQueryPredicateStepTypeString` - Steps with this type represent literal
+ *    strings. Their `value_id` can be used with the
+ *    [`ts_query_string_value_for_id`] function to obtain their string value.
+ * - `TSQueryPredicateStepTypeDone` - Steps with this type are *sentinels*
+ *    that represent the end of an individual predicate. If a pattern has two
+ *    predicates, then there will be two steps with this `type` in the array.
+ */
+const TSQueryPredicateStep *ts_query_predicates_for_pattern(
+  const TSQuery *self,
+  uint32_t pattern_index,
+  uint32_t *step_count
+);
+
+/*
+ * Check if the given pattern in the query has a single root node.
+ */
+bool ts_query_is_pattern_rooted(const TSQuery *self, uint32_t pattern_index);
+
+/*
+ * Check if the given pattern in the query is 'non local'.
+ *
+ * A non-local pattern has multiple root nodes and can match within a
+ * repeating sequence of nodes, as specified by the grammar. Non-local
+ * patterns disable certain optimizations that would otherwise be possible
+ * when executing a query on a specific range of a syntax tree.
+ */
+bool ts_query_is_pattern_non_local(const TSQuery *self, uint32_t pattern_index);
+
+/*
+ * Check if a given pattern is guaranteed to match once a given step is reached.
+ * The step is specified by its byte offset in the query's source code.
+ */
+bool ts_query_is_pattern_guaranteed_at_step(const TSQuery *self, uint32_t byte_offset);
+
+/**
+ * Get the name and length of one of the query's captures, or one of the
+ * query's string literals. Each capture and string is associated with a
+ * numeric id based on the order that it appeared in the query's source.
+ */
+const char *ts_query_capture_name_for_id(
+  const TSQuery *self,
+  uint32_t index,
+  uint32_t *length
+);
+
+/**
+ * Get the quantifier of the query's captures. Each capture is * associated
+ * with a numeric id based on the order that it appeared in the query's source.
+ */
+TSQuantifier ts_query_capture_quantifier_for_id(
+  const TSQuery *self,
+  uint32_t pattern_index,
+  uint32_t capture_index
+);
+
+const char *ts_query_string_value_for_id(
+  const TSQuery *self,
+  uint32_t index,
+  uint32_t *length
+);
+
+/**
+ * Disable a certain capture within a query.
+ *
+ * This prevents the capture from being returned in matches, and also avoids
+ * any resource usage associated with recording the capture. Currently, there
+ * is no way to undo this.
+ */
+void ts_query_disable_capture(TSQuery *self, const char *name, uint32_t length);
+
+/**
+ * Disable a certain pattern within a query.
+ *
+ * This prevents the pattern from matching and removes most of the overhead
+ * associated with the pattern. Currently, there is no way to undo this.
+ */
+void ts_query_disable_pattern(TSQuery *self, uint32_t pattern_index);
+
+/**
+ * Create a new cursor for executing a given query.
+ *
+ * The cursor stores the state that is needed to iteratively search
+ * for matches. To use the query cursor, first call [`ts_query_cursor_exec`]
+ * to start running a given query on a given syntax node. Then, there are
+ * two options for consuming the results of the query:
+ * 1. Repeatedly call [`ts_query_cursor_next_match`] to iterate over all of the
+ *    *matches* in the order that they were found. Each match contains the
+ *    index of the pattern that matched, and an array of captures. Because
+ *    multiple patterns can match the same set of nodes, one match may contain
+ *    captures that appear *before* some of the captures from a previous match.
+ * 2. Repeatedly call [`ts_query_cursor_next_capture`] to iterate over all of the
+ *    individual *captures* in the order that they appear. This is useful if
+ *    don't care about which pattern matched, and just want a single ordered
+ *    sequence of captures.
+ *
+ * If you don't care about consuming all of the results, you can stop calling
+ * [`ts_query_cursor_next_match`] or [`ts_query_cursor_next_capture`] at any point.
+ *  You can then start executing another query on another node by calling
+ *  [`ts_query_cursor_exec`] again.
+ */
+TSQueryCursor *ts_query_cursor_new(void);
+
+/**
+ * Delete a query cursor, freeing all of the memory that it used.
+ */
+void ts_query_cursor_delete(TSQueryCursor *self);
+
+/**
+ * Start running a given query on a given node.
+ */
+void ts_query_cursor_exec(TSQueryCursor *self, const TSQuery *query, TSNode node);
+
+/**
+ * Manage the maximum number of in-progress matches allowed by this query
+ * cursor.
+ *
+ * Query cursors have an optional maximum capacity for storing lists of
+ * in-progress captures. If this capacity is exceeded, then the
+ * earliest-starting match will silently be dropped to make room for further
+ * matches. This maximum capacity is optional — by default, query cursors allow
+ * any number of pending matches, dynamically allocating new space for them as
+ * needed as the query is executed.
+ */
+bool ts_query_cursor_did_exceed_match_limit(const TSQueryCursor *self);
+uint32_t ts_query_cursor_match_limit(const TSQueryCursor *self);
+void ts_query_cursor_set_match_limit(TSQueryCursor *self, uint32_t limit);
+
+/**
+ * Set the maximum duration in microseconds that query execution should be allowed to
+ * take before halting.
+ *
+ * If query execution takes longer than this, it will halt early, returning NULL.
+ * See [`ts_query_cursor_next_match`] or [`ts_query_cursor_next_capture`] for more information.
+ */
+void ts_query_cursor_set_timeout_micros(TSQueryCursor *self, uint64_t timeout_micros);
+
+/**
+ * Get the duration in microseconds that query execution is allowed to take.
+ *
+ * This is set via [`ts_query_cursor_set_timeout_micros`].
+ */
+uint64_t ts_query_cursor_timeout_micros(const TSQueryCursor *self);
+
+/**
+ * Set the range of bytes or (row, column) positions in which the query
+ * will be executed.
+ */
+void ts_query_cursor_set_byte_range(TSQueryCursor *self, uint32_t start_byte, uint32_t end_byte);
+void ts_query_cursor_set_point_range(TSQueryCursor *self, TSPoint start_point, TSPoint end_point);
+
+/**
+ * Advance to the next match of the currently running query.
+ *
+ * If there is a match, write it to `*match` and return `true`.
+ * Otherwise, return `false`.
+ */
+bool ts_query_cursor_next_match(TSQueryCursor *self, TSQueryMatch *match);
+void ts_query_cursor_remove_match(TSQueryCursor *self, uint32_t match_id);
+
+/**
+ * Advance to the next capture of the currently running query.
+ *
+ * If there is a capture, write its match to `*match` and its index within
+ * the matche's capture list to `*capture_index`. Otherwise, return `false`.
+ */
+bool ts_query_cursor_next_capture(
+  TSQueryCursor *self,
+  TSQueryMatch *match,
+  uint32_t *capture_index
+);
+
+/**
+ * Set the maximum start depth for a query cursor.
+ *
+ * This prevents cursors from exploring children nodes at a certain depth.
+ * Note if a pattern includes many children, then they will still be checked.
+ *
+ * The zero max start depth value can be used as a special behavior and
+ * it helps to destructure a subtree by staying on a node and using captures
+ * for interested parts. Note that the zero max start depth only limit a search
+ * depth for a pattern's root node but other nodes that are parts of the pattern
+ * may be searched at any depth what defined by the pattern structure.
+ *
+ * Set to `UINT32_MAX` to remove the maximum start depth.
+ */
+void ts_query_cursor_set_max_start_depth(TSQueryCursor *self, uint32_t max_start_depth);
+
+/**********************/
+/* Section - Language */
+/**********************/
+
+/**
+ * Get another reference to the given language.
+ */
+const TSLanguage *ts_language_copy(const TSLanguage *self);
+
+/**
+ * Free any dynamically-allocated resources for this language, if
+ * this is the last reference.
+ */
+void ts_language_delete(const TSLanguage *self);
+
+/**
+ * Get the number of distinct node types in the language.
+ */
+uint32_t ts_language_symbol_count(const TSLanguage *self);
+
+/**
+ * Get the number of valid states in this language.
+*/
+uint32_t ts_language_state_count(const TSLanguage *self);
+
+/**
+ * Get a node type string for the given numerical id.
+ */
+const char *ts_language_symbol_name(const TSLanguage *self, TSSymbol symbol);
+
+/**
+ * Get the numerical id for the given node type string.
+ */
+TSSymbol ts_language_symbol_for_name(
+  const TSLanguage *self,
+  const char *string,
+  uint32_t length,
+  bool is_named
+);
+
+/**
+ * Get the number of distinct field names in the language.
+ */
+uint32_t ts_language_field_count(const TSLanguage *self);
+
+/**
+ * Get the field name string for the given numerical id.
+ */
+const char *ts_language_field_name_for_id(const TSLanguage *self, TSFieldId id);
+
+/**
+ * Get the numerical id for the given field name string.
+ */
+TSFieldId ts_language_field_id_for_name(const TSLanguage *self, const char *name, uint32_t name_length);
+
+/**
+ * Check whether the given node type id belongs to named nodes, anonymous nodes,
+ * or a hidden nodes.
+ *
+ * See also [`ts_node_is_named`]. Hidden nodes are never returned from the API.
+ */
+TSSymbolType ts_language_symbol_type(const TSLanguage *self, TSSymbol symbol);
+
+/**
+ * Get the ABI version number for this language. This version number is used
+ * to ensure that languages were generated by a compatible version of
+ * Tree-sitter.
+ *
+ * See also [`ts_parser_set_language`].
+ */
+uint32_t ts_language_version(const TSLanguage *self);
+
+/**
+ * Get the next parse state. Combine this with lookahead iterators to generate
+ * completion suggestions or valid symbols in error nodes. Use
+ * [`ts_node_grammar_symbol`] for valid symbols.
+*/
+TSStateId ts_language_next_state(const TSLanguage *self, TSStateId state, TSSymbol symbol);
+
+/********************************/
+/* Section - Lookahead Iterator */
+/********************************/
+
+/**
+ * Create a new lookahead iterator for the given language and parse state.
+ *
+ * This returns `NULL` if state is invalid for the language.
+ *
+ * Repeatedly using [`ts_lookahead_iterator_next`] and
+ * [`ts_lookahead_iterator_current_symbol`] will generate valid symbols in the
+ * given parse state. Newly created lookahead iterators will contain the `ERROR`
+ * symbol.
+ *
+ * Lookahead iterators can be useful to generate suggestions and improve syntax
+ * error diagnostics. To get symbols valid in an ERROR node, use the lookahead
+ * iterator on its first leaf node state. For `MISSING` nodes, a lookahead
+ * iterator created on the previous non-extra leaf node may be appropriate.
+*/
+TSLookaheadIterator *ts_lookahead_iterator_new(const TSLanguage *self, TSStateId state);
+
+/**
+ * Delete a lookahead iterator freeing all the memory used.
+*/
+void ts_lookahead_iterator_delete(TSLookaheadIterator *self);
+
+/**
+ * Reset the lookahead iterator to another state.
+ *
+ * This returns `true` if the iterator was reset to the given state and `false`
+ * otherwise.
+*/
+bool ts_lookahead_iterator_reset_state(TSLookaheadIterator *self, TSStateId state);
+
+/**
+ * Reset the lookahead iterator.
+ *
+ * This returns `true` if the language was set successfully and `false`
+ * otherwise.
+*/
+bool ts_lookahead_iterator_reset(TSLookaheadIterator *self, const TSLanguage *language, TSStateId state);
+
+/**
+ * Get the current language of the lookahead iterator.
+*/
+const TSLanguage *ts_lookahead_iterator_language(const TSLookaheadIterator *self);
+
+/**
+ * Advance the lookahead iterator to the next symbol.
+ *
+ * This returns `true` if there is a new symbol and `false` otherwise.
+*/
+bool ts_lookahead_iterator_next(TSLookaheadIterator *self);
+
+/**
+ * Get the current symbol of the lookahead iterator;
+*/
+TSSymbol ts_lookahead_iterator_current_symbol(const TSLookaheadIterator *self);
+
+/**
+ * Get the current symbol type of the lookahead iterator as a null terminated
+ * string.
+*/
+const char *ts_lookahead_iterator_current_symbol_name(const TSLookaheadIterator *self);
+
+/*************************************/
+/* Section - WebAssembly Integration */
+/************************************/
+
+typedef struct wasm_engine_t TSWasmEngine;
+typedef struct TSWasmStore TSWasmStore;
+
+typedef enum {
+  TSWasmErrorKindNone = 0,
+  TSWasmErrorKindParse,
+  TSWasmErrorKindCompile,
+  TSWasmErrorKindInstantiate,
+  TSWasmErrorKindAllocate,
+} TSWasmErrorKind;
+
+typedef struct {
+  TSWasmErrorKind kind;
+  char *message;
+} TSWasmError;
+
+/**
+ * Create a Wasm store.
+ */
+TSWasmStore *ts_wasm_store_new(
+  TSWasmEngine *engine,
+  TSWasmError *error
+);
+
+/**
+ * Free the memory associated with the given Wasm store.
+ */
+void ts_wasm_store_delete(TSWasmStore *);
+
+/**
+ * Create a language from a buffer of Wasm. The resulting language behaves
+ * like any other Tree-sitter language, except that in order to use it with
+ * a parser, that parser must have a Wasm store. Note that the language
+ * can be used with any Wasm store, it doesn't need to be the same store that
+ * was used to originally load it.
+ */
+const TSLanguage *ts_wasm_store_load_language(
+  TSWasmStore *,
+  const char *name,
+  const char *wasm,
+  uint32_t wasm_len,
+  TSWasmError *error
+);
+
+/**
+ * Get the number of languages instantiated in the given wasm store.
+ */
+size_t ts_wasm_store_language_count(const TSWasmStore *);
+
+/**
+ * Check if the language came from a Wasm module. If so, then in order to use
+ * this language with a Parser, that parser must have a Wasm store assigned.
+ */
+bool ts_language_is_wasm(const TSLanguage *);
+
+/**
+ * Assign the given Wasm store to the parser. A parser must have a Wasm store
+ * in order to use Wasm languages.
+ */
+void ts_parser_set_wasm_store(TSParser *, TSWasmStore *);
+
+/**
+ * Remove the parser's current Wasm store and return it. This returns NULL if
+ * the parser doesn't have a Wasm store.
+ */
+TSWasmStore *ts_parser_take_wasm_store(TSParser *);
+
+/**********************************/
+/* Section - Global Configuration */
+/**********************************/
+
+/**
+ * Set the allocation functions used by the library.
+ *
+ * By default, Tree-sitter uses the standard libc allocation functions,
+ * but aborts the process when an allocation fails. This function lets
+ * you supply alternative allocation functions at runtime.
+ *
+ * If you pass `NULL` for any parameter, Tree-sitter will switch back to
+ * its default implementation of that function.
+ *
+ * If you call this function after the library has already been used, then
+ * you must ensure that either:
+ *  1. All the existing objects have been freed.
+ *  2. The new allocator shares its state with the old one, so it is capable
+ *     of freeing memory that was allocated by the old allocator.
+ */
+void ts_set_allocator(
+  void *(*new_malloc)(size_t),
+	void *(*new_calloc)(size_t, size_t),
+	void *(*new_realloc)(void *, size_t),
+	void (*new_free)(void *)
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#ifndef TREE_SITTER_HIDE_SYMBOLS
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC visibility pop
+#endif
+#endif
+
+#endif  // TREE_SITTER_API_H_
diff --git a/vendor/tree-sitter/lib/src/alloc.c b/vendor/tree-sitter/lib/src/alloc.c
new file mode 100644
--- /dev/null
+++ b/vendor/tree-sitter/lib/src/alloc.c
@@ -0,0 +1,48 @@
+#include "alloc.h"
+#include "tree_sitter/api.h"
+#include <stdlib.h>
+
+static void *ts_malloc_default(size_t size) {
+  void *result = malloc(size);
+  if (size > 0 && !result) {
+    fprintf(stderr, "tree-sitter failed to allocate %zu bytes", size);
+    abort();
+  }
+  return result;
+}
+
+static void *ts_calloc_default(size_t count, size_t size) {
+  void *result = calloc(count, size);
+  if (count > 0 && !result) {
+    fprintf(stderr, "tree-sitter failed to allocate %zu bytes", count * size);
+    abort();
+  }
+  return result;
+}
+
+static void *ts_realloc_default(void *buffer, size_t size) {
+  void *result = realloc(buffer, size);
+  if (size > 0 && !result) {
+    fprintf(stderr, "tree-sitter failed to reallocate %zu bytes", size);
+    abort();
+  }
+  return result;
+}
+
+// Allow clients to override allocation functions dynamically
+TS_PUBLIC void *(*ts_current_malloc)(size_t) = ts_malloc_default;
+TS_PUBLIC void *(*ts_current_calloc)(size_t, size_t) = ts_calloc_default;
+TS_PUBLIC void *(*ts_current_realloc)(void *, size_t) = ts_realloc_default;
+TS_PUBLIC void (*ts_current_free)(void *) = free;
+
+void ts_set_allocator(
+  void *(*new_malloc)(size_t size),
+  void *(*new_calloc)(size_t count, size_t size),
+  void *(*new_realloc)(void *ptr, size_t size),
+  void (*new_free)(void *ptr)
+) {
+  ts_current_malloc = new_malloc ? new_malloc : ts_malloc_default;
+  ts_current_calloc = new_calloc ? new_calloc : ts_calloc_default;
+  ts_current_realloc = new_realloc ? new_realloc : ts_realloc_default;
+  ts_current_free = new_free ? new_free : free;
+}
diff --git a/vendor/tree-sitter/lib/src/alloc.h b/vendor/tree-sitter/lib/src/alloc.h
new file mode 100644
--- /dev/null
+++ b/vendor/tree-sitter/lib/src/alloc.h
@@ -0,0 +1,41 @@
+#ifndef TREE_SITTER_ALLOC_H_
+#define TREE_SITTER_ALLOC_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#if defined(TREE_SITTER_HIDDEN_SYMBOLS) || defined(_WIN32)
+#define TS_PUBLIC
+#else
+#define TS_PUBLIC __attribute__((visibility("default")))
+#endif
+
+TS_PUBLIC extern void *(*ts_current_malloc)(size_t size);
+TS_PUBLIC extern void *(*ts_current_calloc)(size_t count, size_t size);
+TS_PUBLIC extern void *(*ts_current_realloc)(void *ptr, size_t size);
+TS_PUBLIC extern void (*ts_current_free)(void *ptr);
+
+// Allow clients to override allocation functions
+#ifndef ts_malloc
+#define ts_malloc  ts_current_malloc
+#endif
+#ifndef ts_calloc
+#define ts_calloc  ts_current_calloc
+#endif
+#ifndef ts_realloc
+#define ts_realloc ts_current_realloc
+#endif
+#ifndef ts_free
+#define ts_free    ts_current_free
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // TREE_SITTER_ALLOC_H_
diff --git a/vendor/tree-sitter/lib/src/array.h b/vendor/tree-sitter/lib/src/array.h
new file mode 100644
--- /dev/null
+++ b/vendor/tree-sitter/lib/src/array.h
@@ -0,0 +1,290 @@
+#ifndef TREE_SITTER_ARRAY_H_
+#define TREE_SITTER_ARRAY_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "./alloc.h"
+#include "./ts_assert.h"
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef _MSC_VER
+#pragma warning(disable : 4101)
+#elif defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-variable"
+#endif
+
+#define Array(T)       \
+  struct {             \
+    T *contents;       \
+    uint32_t size;     \
+    uint32_t capacity; \
+  }
+
+/// Initialize an array.
+#define array_init(self) \
+  ((self)->size = 0, (self)->capacity = 0, (self)->contents = NULL)
+
+/// Create an empty array.
+#define array_new() \
+  { NULL, 0, 0 }
+
+/// Get a pointer to the element at a given `index` in the array.
+#define array_get(self, _index) \
+  (ts_assert((uint32_t)(_index) < (self)->size), &(self)->contents[_index])
+
+/// Get a pointer to the first element in the array.
+#define array_front(self) array_get(self, 0)
+
+/// Get a pointer to the last element in the array.
+#define array_back(self) array_get(self, (self)->size - 1)
+
+/// Clear the array, setting its size to zero. Note that this does not free any
+/// memory allocated for the array's contents.
+#define array_clear(self) ((self)->size = 0)
+
+/// Reserve `new_capacity` elements of space in the array. If `new_capacity` is
+/// less than the array's current capacity, this function has no effect.
+#define array_reserve(self, new_capacity) \
+  _array__reserve((Array *)(self), array_elem_size(self), new_capacity)
+
+/// Free any memory allocated for this array. Note that this does not free any
+/// memory allocated for the array's contents.
+#define array_delete(self) _array__delete((Array *)(self))
+
+/// Push a new `element` onto the end of the array.
+#define array_push(self, element)                            \
+  (_array__grow((Array *)(self), 1, array_elem_size(self)), \
+   (self)->contents[(self)->size++] = (element))
+
+/// Increase the array's size by `count` elements.
+/// New elements are zero-initialized.
+#define array_grow_by(self, count) \
+  do { \
+    if ((count) == 0) break; \
+    _array__grow((Array *)(self), count, array_elem_size(self)); \
+    memset((self)->contents + (self)->size, 0, (count) * array_elem_size(self)); \
+    (self)->size += (count); \
+  } while (0)
+
+/// Append all elements from one array to the end of another.
+#define array_push_all(self, other)                                       \
+  array_extend((self), (other)->size, (other)->contents)
+
+/// Append `count` elements to the end of the array, reading their values from the
+/// `contents` pointer.
+#define array_extend(self, count, contents)                    \
+  _array__splice(                                               \
+    (Array *)(self), array_elem_size(self), (self)->size, \
+    0, count,  contents                                        \
+  )
+
+/// Remove `old_count` elements from the array starting at the given `index`. At
+/// the same index, insert `new_count` new elements, reading their values from the
+/// `new_contents` pointer.
+#define array_splice(self, _index, old_count, new_count, new_contents)  \
+  _array__splice(                                                       \
+    (Array *)(self), array_elem_size(self), _index,                \
+    old_count, new_count, new_contents                                 \
+  )
+
+/// Insert one `element` into the array at the given `index`.
+#define array_insert(self, _index, element) \
+  _array__splice((Array *)(self), array_elem_size(self), _index, 0, 1, &(element))
+
+/// Remove one element from the array at the given `index`.
+#define array_erase(self, _index) \
+  _array__erase((Array *)(self), array_elem_size(self), _index)
+
+/// Pop the last element off the array, returning the element by value.
+#define array_pop(self) ((self)->contents[--(self)->size])
+
+/// Assign the contents of one array to another, reallocating if necessary.
+#define array_assign(self, other) \
+  _array__assign((Array *)(self), (const Array *)(other), array_elem_size(self))
+
+/// Swap one array with another
+#define array_swap(self, other) \
+  _array__swap((Array *)(self), (Array *)(other))
+
+/// Get the size of the array contents
+#define array_elem_size(self) (sizeof *(self)->contents)
+
+/// Search a sorted array for a given `needle` value, using the given `compare`
+/// callback to determine the order.
+///
+/// If an existing element is found to be equal to `needle`, then the `index`
+/// out-parameter is set to the existing value's index, and the `exists`
+/// out-parameter is set to true. Otherwise, `index` is set to an index where
+/// `needle` should be inserted in order to preserve the sorting, and `exists`
+/// is set to false.
+#define array_search_sorted_with(self, compare, needle, _index, _exists) \
+  _array__search_sorted(self, 0, compare, , needle, _index, _exists)
+
+/// Search a sorted array for a given `needle` value, using integer comparisons
+/// of a given struct field (specified with a leading dot) to determine the order.
+///
+/// See also `array_search_sorted_with`.
+#define array_search_sorted_by(self, field, needle, _index, _exists) \
+  _array__search_sorted(self, 0, _compare_int, field, needle, _index, _exists)
+
+/// Insert a given `value` into a sorted array, using the given `compare`
+/// callback to determine the order.
+#define array_insert_sorted_with(self, compare, value) \
+  do { \
+    unsigned _index, _exists; \
+    array_search_sorted_with(self, compare, &(value), &_index, &_exists); \
+    if (!_exists) array_insert(self, _index, value); \
+  } while (0)
+
+/// Insert a given `value` into a sorted array, using integer comparisons of
+/// a given struct field (specified with a leading dot) to determine the order.
+///
+/// See also `array_search_sorted_by`.
+#define array_insert_sorted_by(self, field, value) \
+  do { \
+    unsigned _index, _exists; \
+    array_search_sorted_by(self, field, (value) field, &_index, &_exists); \
+    if (!_exists) array_insert(self, _index, value); \
+  } while (0)
+
+// Private
+
+typedef Array(void) Array;
+
+/// This is not what you're looking for, see `array_delete`.
+static inline void _array__delete(Array *self) {
+  if (self->contents) {
+    ts_free(self->contents);
+    self->contents = NULL;
+    self->size = 0;
+    self->capacity = 0;
+  }
+}
+
+/// This is not what you're looking for, see `array_erase`.
+static inline void _array__erase(Array *self, size_t element_size,
+                                uint32_t index) {
+  ts_assert(index < self->size);
+  char *contents = (char *)self->contents;
+  memmove(contents + index * element_size, contents + (index + 1) * element_size,
+          (self->size - index - 1) * element_size);
+  self->size--;
+}
+
+/// This is not what you're looking for, see `array_reserve`.
+static inline void _array__reserve(Array *self, size_t element_size, uint32_t new_capacity) {
+  if (new_capacity > self->capacity) {
+    if (self->contents) {
+      self->contents = ts_realloc(self->contents, new_capacity * element_size);
+    } else {
+      self->contents = ts_malloc(new_capacity * element_size);
+    }
+    self->capacity = new_capacity;
+  }
+}
+
+/// This is not what you're looking for, see `array_assign`.
+static inline void _array__assign(Array *self, const Array *other, size_t element_size) {
+  _array__reserve(self, element_size, other->size);
+  self->size = other->size;
+  memcpy(self->contents, other->contents, self->size * element_size);
+}
+
+/// This is not what you're looking for, see `array_swap`.
+static inline void _array__swap(Array *self, Array *other) {
+  Array swap = *other;
+  *other = *self;
+  *self = swap;
+}
+
+/// This is not what you're looking for, see `array_push` or `array_grow_by`.
+static inline void _array__grow(Array *self, uint32_t count, size_t element_size) {
+  uint32_t new_size = self->size + count;
+  if (new_size > self->capacity) {
+    uint32_t new_capacity = self->capacity * 2;
+    if (new_capacity < 8) new_capacity = 8;
+    if (new_capacity < new_size) new_capacity = new_size;
+    _array__reserve(self, element_size, new_capacity);
+  }
+}
+
+/// This is not what you're looking for, see `array_splice`.
+static inline void _array__splice(Array *self, size_t element_size,
+                                 uint32_t index, uint32_t old_count,
+                                 uint32_t new_count, const void *elements) {
+  uint32_t new_size = self->size + new_count - old_count;
+  uint32_t old_end = index + old_count;
+  uint32_t new_end = index + new_count;
+  ts_assert(old_end <= self->size);
+
+  _array__reserve(self, element_size, new_size);
+
+  char *contents = (char *)self->contents;
+  if (self->size > old_end) {
+    memmove(
+      contents + new_end * element_size,
+      contents + old_end * element_size,
+      (self->size - old_end) * element_size
+    );
+  }
+  if (new_count > 0) {
+    if (elements) {
+      memcpy(
+        (contents + index * element_size),
+        elements,
+        new_count * element_size
+      );
+    } else {
+      memset(
+        (contents + index * element_size),
+        0,
+        new_count * element_size
+      );
+    }
+  }
+  self->size += new_count - old_count;
+}
+
+/// A binary search routine, based on Rust's `std::slice::binary_search_by`.
+/// This is not what you're looking for, see `array_search_sorted_with` or `array_search_sorted_by`.
+#define _array__search_sorted(self, start, compare, suffix, needle, _index, _exists) \
+  do { \
+    *(_index) = start; \
+    *(_exists) = false; \
+    uint32_t size = (self)->size - *(_index); \
+    if (size == 0) break; \
+    int comparison; \
+    while (size > 1) { \
+      uint32_t half_size = size / 2; \
+      uint32_t mid_index = *(_index) + half_size; \
+      comparison = compare(&((self)->contents[mid_index] suffix), (needle)); \
+      if (comparison <= 0) *(_index) = mid_index; \
+      size -= half_size; \
+    } \
+    comparison = compare(&((self)->contents[*(_index)] suffix), (needle)); \
+    if (comparison == 0) *(_exists) = true; \
+    else if (comparison < 0) *(_index) += 1; \
+  } while (0)
+
+/// Helper macro for the `_sorted_by` routines below. This takes the left (existing)
+/// parameter by reference in order to work with the generic sorting function above.
+#define _compare_int(a, b) ((int)*(a) - (int)(b))
+
+#ifdef _MSC_VER
+#pragma warning(default : 4101)
+#elif defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  // TREE_SITTER_ARRAY_H_
diff --git a/vendor/tree-sitter/lib/src/atomic.h b/vendor/tree-sitter/lib/src/atomic.h
new file mode 100644
--- /dev/null
+++ b/vendor/tree-sitter/lib/src/atomic.h
@@ -0,0 +1,68 @@
+#ifndef TREE_SITTER_ATOMIC_H_
+#define TREE_SITTER_ATOMIC_H_
+
+#include <stddef.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+#ifdef __TINYC__
+
+static inline size_t atomic_load(const volatile size_t *p) {
+  return *p;
+}
+
+static inline uint32_t atomic_inc(volatile uint32_t *p) {
+  *p += 1;
+  return *p;
+}
+
+static inline uint32_t atomic_dec(volatile uint32_t *p) {
+  *p-= 1;
+  return *p;
+}
+
+#elif defined(_WIN32)
+
+#include <windows.h>
+
+static inline size_t atomic_load(const volatile size_t *p) {
+  return *p;
+}
+
+static inline uint32_t atomic_inc(volatile uint32_t *p) {
+  return InterlockedIncrement((long volatile *)p);
+}
+
+static inline uint32_t atomic_dec(volatile uint32_t *p) {
+  return InterlockedDecrement((long volatile *)p);
+}
+
+#else
+
+static inline size_t atomic_load(const volatile size_t *p) {
+#ifdef __ATOMIC_RELAXED
+  return __atomic_load_n(p, __ATOMIC_RELAXED);
+#else
+  return __sync_fetch_and_add((volatile size_t *)p, 0);
+#endif
+}
+
+static inline uint32_t atomic_inc(volatile uint32_t *p) {
+  #ifdef __ATOMIC_RELAXED
+    return __atomic_add_fetch(p, 1U, __ATOMIC_SEQ_CST);
+  #else
+    return __sync_add_and_fetch(p, 1U);
+  #endif
+}
+
+static inline uint32_t atomic_dec(volatile uint32_t *p) {
+  #ifdef __ATOMIC_RELAXED
+    return __atomic_sub_fetch(p, 1U, __ATOMIC_SEQ_CST);
+  #else
+    return __sync_sub_and_fetch(p, 1U);
+  #endif
+}
+
+#endif
+
+#endif  // TREE_SITTER_ATOMIC_H_
diff --git a/vendor/tree-sitter/lib/src/clock.h b/vendor/tree-sitter/lib/src/clock.h
new file mode 100644
--- /dev/null
+++ b/vendor/tree-sitter/lib/src/clock.h
@@ -0,0 +1,146 @@
+#ifndef TREE_SITTER_CLOCK_H_
+#define TREE_SITTER_CLOCK_H_
+
+#include <stdbool.h>
+#include <stdint.h>
+
+typedef uint64_t TSDuration;
+
+#ifdef _WIN32
+
+// Windows:
+// * Represent a time as a performance counter value.
+// * Represent a duration as a number of performance counter ticks.
+
+#include <windows.h>
+typedef uint64_t TSClock;
+
+static inline TSDuration duration_from_micros(uint64_t micros) {
+  LARGE_INTEGER frequency;
+  QueryPerformanceFrequency(&frequency);
+  return micros * (uint64_t)frequency.QuadPart / 1000000;
+}
+
+static inline uint64_t duration_to_micros(TSDuration self) {
+  LARGE_INTEGER frequency;
+  QueryPerformanceFrequency(&frequency);
+  return self * 1000000 / (uint64_t)frequency.QuadPart;
+}
+
+static inline TSClock clock_null(void) {
+  return 0;
+}
+
+static inline TSClock clock_now(void) {
+  LARGE_INTEGER result;
+  QueryPerformanceCounter(&result);
+  return (uint64_t)result.QuadPart;
+}
+
+static inline TSClock clock_after(TSClock base, TSDuration duration) {
+  return base + duration;
+}
+
+static inline bool clock_is_null(TSClock self) {
+  return !self;
+}
+
+static inline bool clock_is_gt(TSClock self, TSClock other) {
+  return self > other;
+}
+
+#elif defined(CLOCK_MONOTONIC) && !defined(__APPLE__)
+
+// POSIX with monotonic clock support (Linux)
+// * Represent a time as a monotonic (seconds, nanoseconds) pair.
+// * Represent a duration as a number of microseconds.
+//
+// On these platforms, parse timeouts will correspond accurately to
+// real time, regardless of what other processes are running.
+
+#include <time.h>
+typedef struct timespec TSClock;
+
+static inline TSDuration duration_from_micros(uint64_t micros) {
+  return micros;
+}
+
+static inline uint64_t duration_to_micros(TSDuration self) {
+  return self;
+}
+
+static inline TSClock clock_now(void) {
+  TSClock result;
+  clock_gettime(CLOCK_MONOTONIC, &result);
+  return result;
+}
+
+static inline TSClock clock_null(void) {
+  return (TSClock) {0, 0};
+}
+
+static inline TSClock clock_after(TSClock base, TSDuration duration) {
+  TSClock result = base;
+  result.tv_sec += duration / 1000000;
+  result.tv_nsec += (duration % 1000000) * 1000;
+  if (result.tv_nsec >= 1000000000) {
+    result.tv_nsec -= 1000000000;
+    ++(result.tv_sec);
+  }
+  return result;
+}
+
+static inline bool clock_is_null(TSClock self) {
+  return !self.tv_sec && !self.tv_nsec;
+}
+
+static inline bool clock_is_gt(TSClock self, TSClock other) {
+  if (self.tv_sec > other.tv_sec) return true;
+  if (self.tv_sec < other.tv_sec) return false;
+  return self.tv_nsec > other.tv_nsec;
+}
+
+#else
+
+// macOS or POSIX without monotonic clock support
+// * Represent a time as a process clock value.
+// * Represent a duration as a number of process clock ticks.
+//
+// On these platforms, parse timeouts may be affected by other processes,
+// which is not ideal, but is better than using a non-monotonic time API
+// like `gettimeofday`.
+
+#include <time.h>
+typedef uint64_t TSClock;
+
+static inline TSDuration duration_from_micros(uint64_t micros) {
+  return micros * (uint64_t)CLOCKS_PER_SEC / 1000000;
+}
+
+static inline uint64_t duration_to_micros(TSDuration self) {
+  return self * 1000000 / (uint64_t)CLOCKS_PER_SEC;
+}
+
+static inline TSClock clock_null(void) {
+  return 0;
+}
+
+static inline TSClock clock_now(void) {
+  return (uint64_t)clock();
+}
+
+static inline TSClock clock_after(TSClock base, TSDuration duration) {
+  return base + duration;
+}
+
+static inline bool clock_is_null(TSClock self) {
+  return !self;
+}
+
+static inline bool clock_is_gt(TSClock self, TSClock other) {
+  return self > other;
+}
+
+#endif
+
+#endif  // TREE_SITTER_CLOCK_H_
diff --git a/vendor/tree-sitter/lib/src/error_costs.h b/vendor/tree-sitter/lib/src/error_costs.h
new file mode 100644
--- /dev/null
+++ b/vendor/tree-sitter/lib/src/error_costs.h
@@ -0,0 +1,11 @@
+#ifndef TREE_SITTER_ERROR_COSTS_H_
+#define TREE_SITTER_ERROR_COSTS_H_
+
+#define ERROR_STATE 0
+#define ERROR_COST_PER_RECOVERY 500
+#define ERROR_COST_PER_MISSING_TREE 110
+#define ERROR_COST_PER_SKIPPED_TREE 100
+#define ERROR_COST_PER_SKIPPED_LINE 30
+#define ERROR_COST_PER_SKIPPED_CHAR 1
+
+#endif
diff --git a/vendor/tree-sitter/lib/src/get_changed_ranges.c b/vendor/tree-sitter/lib/src/get_changed_ranges.c
new file mode 100644
--- /dev/null
+++ b/vendor/tree-sitter/lib/src/get_changed_ranges.c
@@ -0,0 +1,501 @@
+#include "./get_changed_ranges.h"
+#include "./subtree.h"
+#include "./language.h"
+#include "./error_costs.h"
+#include "./tree_cursor.h"
+#include "./ts_assert.h"
+
+// #define DEBUG_GET_CHANGED_RANGES
+
+static void ts_range_array_add(
+  TSRangeArray *self,
+  Length start,
+  Length end
+) {
+  if (self->size > 0) {
+    TSRange *last_range = array_back(self);
+    if (start.bytes <= last_range->end_byte) {
+      last_range->end_byte = end.bytes;
+      last_range->end_point = end.extent;
+      return;
+    }
+  }
+
+  if (start.bytes < end.bytes) {
+    TSRange range = { start.extent, end.extent, start.bytes, end.bytes };
+    array_push(self, range);
+  }
+}
+
+bool ts_range_array_intersects(
+  const TSRangeArray *self,
+  unsigned start_index,
+  uint32_t start_byte,
+  uint32_t end_byte
+) {
+  for (unsigned i = start_index; i < self->size; i++) {
+    TSRange *range = &self->contents[i];
+    if (range->end_byte > start_byte) {
+      if (range->start_byte >= end_byte) break;
+      return true;
+    }
+  }
+  return false;
+}
+
+void ts_range_array_get_changed_ranges(
+  const TSRange *old_ranges, unsigned old_range_count,
+  const TSRange *new_ranges, unsigned new_range_count,
+  TSRangeArray *differences
+) {
+  unsigned new_index = 0;
+  unsigned old_index = 0;
+  Length current_position = length_zero();
+  bool in_old_range = false;
+  bool in_new_range = false;
+
+  while (old_index < old_range_count || new_index < new_range_count) {
+    const TSRange *old_range = &old_ranges[old_index];
+    const TSRange *new_range = &new_ranges[new_index];
+
+    Length next_old_position;
+    if (in_old_range) {
+      next_old_position = (Length) {old_range->end_byte, old_range->end_point};
+    } else if (old_index < old_range_count) {
+      next_old_position = (Length) {old_range->start_byte, old_range->start_point};
+    } else {
+      next_old_position = LENGTH_MAX;
+    }
+
+    Length next_new_position;
+    if (in_new_range) {
+      next_new_position = (Length) {new_range->end_byte, new_range->end_point};
+    } else if (new_index < new_range_count) {
+      next_new_position = (Length) {new_range->start_byte, new_range->start_point};
+    } else {
+      next_new_position = LENGTH_MAX;
+    }
+
+    if (next_old_position.bytes < next_new_position.bytes) {
+      if (in_old_range != in_new_range) {
+        ts_range_array_add(differences, current_position, next_old_position);
+      }
+      if (in_old_range) old_index++;
+      current_position = next_old_position;
+      in_old_range = !in_old_range;
+    } else if (next_new_position.bytes < next_old_position.bytes) {
+      if (in_old_range != in_new_range) {
+        ts_range_array_add(differences, current_position, next_new_position);
+      }
+      if (in_new_range) new_index++;
+      current_position = next_new_position;
+      in_new_range = !in_new_range;
+    } else {
+      if (in_old_range != in_new_range) {
+        ts_range_array_add(differences, current_position, next_new_position);
+      }
+      if (in_old_range) old_index++;
+      if (in_new_range) new_index++;
+      in_old_range = !in_old_range;
+      in_new_range = !in_new_range;
+      current_position = next_new_position;
+    }
+  }
+}
+
+typedef struct {
+  TreeCursor cursor;
+  const TSLanguage *language;
+  unsigned visible_depth;
+  bool in_padding;
+} Iterator;
+
+static Iterator iterator_new(
+  TreeCursor *cursor,
+  const Subtree *tree,
+  const TSLanguage *language
+) {
+  array_clear(&cursor->stack);
+  array_push(&cursor->stack, ((TreeCursorEntry) {
+    .subtree = tree,
+    .position = length_zero(),
+    .child_index = 0,
+    .structural_child_index = 0,
+  }));
+  return (Iterator) {
+    .cursor = *cursor,
+    .language = language,
+    .visible_depth = 1,
+    .in_padding = false,
+  };
+}
+
+static bool iterator_done(Iterator *self) {
+  return self->cursor.stack.size == 0;
+}
+
+static Length iterator_start_position(Iterator *self) {
+  TreeCursorEntry entry = *array_back(&self->cursor.stack);
+  if (self->in_padding) {
+    return entry.position;
+  } else {
+    return length_add(entry.position, ts_subtree_padding(*entry.subtree));
+  }
+}
+
+static Length iterator_end_position(Iterator *self) {
+  TreeCursorEntry entry = *array_back(&self->cursor.stack);
+  Length result = length_add(entry.position, ts_subtree_padding(*entry.subtree));
+  if (self->in_padding) {
+    return result;
+  } else {
+    return length_add(result, ts_subtree_size(*entry.subtree));
+  }
+}
+
+static bool iterator_tree_is_visible(const Iterator *self) {
+  TreeCursorEntry entry = *array_back(&self->cursor.stack);
+  if (ts_subtree_visible(*entry.subtree)) return true;
+  if (self->cursor.stack.size > 1) {
+    Subtree parent = *self->cursor.stack.contents[self->cursor.stack.size - 2].subtree;
+    return ts_language_alias_at(
+      self->language,
+      parent.ptr->production_id,
+      entry.structural_child_index
+    ) != 0;
+  }
+  return false;
+}
+
+static void iterator_get_visible_state(
+  const Iterator *self,
+  Subtree *tree,
+  TSSymbol *alias_symbol,
+  uint32_t *start_byte
+) {
+  uint32_t i = self->cursor.stack.size - 1;
+
+  if (self->in_padding) {
+    if (i == 0) return;
+    i--;
+  }
+
+  for (; i + 1 > 0; i--) {
+    TreeCursorEntry entry = self->cursor.stack.contents[i];
+
+    if (i > 0) {
+      const Subtree *parent = self->cursor.stack.contents[i - 1].subtree;
+      *alias_symbol = ts_language_alias_at(
+        self->language,
+        parent->ptr->production_id,
+        entry.structural_child_index
+      );
+    }
+
+    if (ts_subtree_visible(*entry.subtree) || *alias_symbol) {
+      *tree = *entry.subtree;
+      *start_byte = entry.position.bytes;
+      break;
+    }
+  }
+}
+
+static void iterator_ascend(Iterator *self) {
+  if (iterator_done(self)) return;
+  if (iterator_tree_is_visible(self) && !self->in_padding) self->visible_depth--;
+  if (array_back(&self->cursor.stack)->child_index > 0) self->in_padding = false;
+  self->cursor.stack.size--;
+}
+
+static bool iterator_descend(Iterator *self, uint32_t goal_position) {
+  if (self->in_padding) return false;
+
+  bool did_descend = false;
+  do {
+    did_descend = false;
+    TreeCursorEntry entry = *array_back(&self->cursor.stack);
+    Length position = entry.position;
+    uint32_t structural_child_index = 0;
+    for (uint32_t i = 0, n = ts_subtree_child_count(*entry.subtree); i < n; i++) {
+      const Subtree *child = &ts_subtree_children(*entry.subtree)[i];
+      Length child_left = length_add(position, ts_subtree_padding(*child));
+      Length child_right = length_add(child_left, ts_subtree_size(*child));
+
+      if (child_right.bytes > goal_position) {
+        array_push(&self->cursor.stack, ((TreeCursorEntry) {
+          .subtree = child,
+          .position = position,
+          .child_index = i,
+          .structural_child_index = structural_child_index,
+        }));
+
+        if (iterator_tree_is_visible(self)) {
+          if (child_left.bytes > goal_position) {
+            self->in_padding = true;
+          } else {
+            self->visible_depth++;
+          }
+          return true;
+        }
+
+        did_descend = true;
+        break;
+      }
+
+      position = child_right;
+      if (!ts_subtree_extra(*child)) structural_child_index++;
+    }
+  } while (did_descend);
+
+  return false;
+}
+
+static void iterator_advance(Iterator *self) {
+  if (self->in_padding) {
+    self->in_padding = false;
+    if (iterator_tree_is_visible(self)) {
+      self->visible_depth++;
+    } else {
+      iterator_descend(self, 0);
+    }
+    return;
+  }
+
+  for (;;) {
+    if (iterator_tree_is_visible(self)) self->visible_depth--;
+    TreeCursorEntry entry = array_pop(&self->cursor.stack);
+    if (iterator_done(self)) return;
+
+    const Subtree *parent = array_back(&self->cursor.stack)->subtree;
+    uint32_t child_index = entry.child_index + 1;
+    if (ts_subtree_child_count(*parent) > child_index) {
+      Length position = length_add(entry.position, ts_subtree_total_size(*entry.subtree));
+      uint32_t structural_child_index = entry.structural_child_index;
+      if (!ts_subtree_extra(*entry.subtree)) structural_child_index++;
+      const Subtree *next_child = &ts_subtree_children(*parent)[child_index];
+
+      array_push(&self->cursor.stack, ((TreeCursorEntry) {
+        .subtree = next_child,
+        .position = position,
+        .child_index = child_index,
+        .structural_child_index = structural_child_index,
+      }));
+
+      if (iterator_tree_is_visible(self)) {
+        if (ts_subtree_padding(*next_child).bytes > 0) {
+          self->in_padding = true;
+        } else {
+          self->visible_depth++;
+        }
+      } else {
+        iterator_descend(self, 0);
+      }
+      break;
+    }
+  }
+}
+
+typedef enum {
+  IteratorDiffers,
+  IteratorMayDiffer,
+  IteratorMatches,
+} IteratorComparison;
+
+static IteratorComparison iterator_compare(
+  const Iterator *old_iter,
+  const Iterator *new_iter
+) {
+  Subtree old_tree = NULL_SUBTREE;
+  Subtree new_tree = NULL_SUBTREE;
+  uint32_t old_start = 0;
+  uint32_t new_start = 0;
+  TSSymbol old_alias_symbol = 0;
+  TSSymbol new_alias_symbol = 0;
+  iterator_get_visible_state(old_iter, &old_tree, &old_alias_symbol, &old_start);
+  iterator_get_visible_state(new_iter, &new_tree, &new_alias_symbol, &new_start);
+
+  if (!old_tree.ptr && !new_tree.ptr) return IteratorMatches;
+  if (!old_tree.ptr || !new_tree.ptr) return IteratorDiffers;
+
+  if (
+    old_alias_symbol == new_alias_symbol &&
+    ts_subtree_symbol(old_tree) == ts_subtree_symbol(new_tree)
+  ) {
+    if (old_start == new_start &&
+        !ts_subtree_has_changes(old_tree) &&
+        ts_subtree_symbol(old_tree) != ts_builtin_sym_error &&
+        ts_subtree_size(old_tree).bytes == ts_subtree_size(new_tree).bytes &&
+        ts_subtree_parse_state(old_tree) != TS_TREE_STATE_NONE &&
+        ts_subtree_parse_state(new_tree) != TS_TREE_STATE_NONE &&
+        (ts_subtree_parse_state(old_tree) == ERROR_STATE) ==
+        (ts_subtree_parse_state(new_tree) == ERROR_STATE)) {
+      return IteratorMatches;
+    } else {
+      return IteratorMayDiffer;
+    }
+  }
+
+  return IteratorDiffers;
+}
+
+#ifdef DEBUG_GET_CHANGED_RANGES
+static inline void iterator_print_state(Iterator *self) {
+  TreeCursorEntry entry = *array_back(&self->cursor.stack);
+  TSPoint start = iterator_start_position(self).extent;
+  TSPoint end = iterator_end_position(self).extent;
+  const char *name = ts_language_symbol_name(self->language, ts_subtree_symbol(*entry.subtree));
+  printf(
+    "(%-25s %s\t depth:%u [%u, %u] - [%u, %u])",
+    name, self->in_padding ? "(p)" : "   ",
+    self->visible_depth,
+    start.row + 1, start.column,
+    end.row + 1, end.column
+  );
+}
+#endif
+
+unsigned ts_subtree_get_changed_ranges(
+  const Subtree *old_tree, const Subtree *new_tree,
+  TreeCursor *cursor1, TreeCursor *cursor2,
+  const TSLanguage *language,
+  const TSRangeArray *included_range_differences,
+  TSRange **ranges
+) {
+  TSRangeArray results = array_new();
+
+  Iterator old_iter = iterator_new(cursor1, old_tree, language);
+  Iterator new_iter = iterator_new(cursor2, new_tree, language);
+
+  unsigned included_range_difference_index = 0;
+
+  Length position = iterator_start_position(&old_iter);
+  Length next_position = iterator_start_position(&new_iter);
+  if (position.bytes < next_position.bytes) {
+    ts_range_array_add(&results, position, next_position);
+    position = next_position;
+  } else if (position.bytes > next_position.bytes) {
+    ts_range_array_add(&results, next_position, position);
+    next_position = position;
+  }
+
+  do {
+    #ifdef DEBUG_GET_CHANGED_RANGES
+    printf("At [%-2u, %-2u] Compare ", position.extent.row + 1, position.extent.column);
+    iterator_print_state(&old_iter);
+    printf("\tvs\t");
+    iterator_print_state(&new_iter);
+    puts("");
+    #endif
+
+    // Compare the old and new subtrees.
+    IteratorComparison comparison = iterator_compare(&old_iter, &new_iter);
+
+    // Even if the two subtrees appear to be identical, they could differ
+    // internally if they contain a range of text that was previously
+    // excluded from the parse, and is now included, or vice-versa.
+    if (comparison == IteratorMatches && ts_range_array_intersects(
+      included_range_differences,
+      included_range_difference_index,
+      position.bytes,
+      iterator_end_position(&old_iter).bytes
+    )) {
+      comparison = IteratorMayDiffer;
+    }
+
+    bool is_changed = false;
+    switch (comparison) {
+      // If the subtrees are definitely identical, move to the end
+      // of both subtrees.
+      case IteratorMatches:
+        next_position = iterator_end_position(&old_iter);
+        break;
+
+      // If the subtrees might differ internally, descend into both
+      // subtrees, finding the first child that spans the current position.
+      case IteratorMayDiffer:
+        if (iterator_descend(&old_iter, position.bytes)) {
+          if (!iterator_descend(&new_iter, position.bytes)) {
+            is_changed = true;
+            next_position = iterator_end_position(&old_iter);
+          }
+        } else if (iterator_descend(&new_iter, position.bytes)) {
+          is_changed = true;
+          next_position = iterator_end_position(&new_iter);
+        } else {
+          next_position = length_min(
+            iterator_end_position(&old_iter),
+            iterator_end_position(&new_iter)
+          );
+        }
+        break;
+
+      // If the subtrees are different, record a change and then move
+      // to the end of both subtrees.
+      case IteratorDiffers:
+        is_changed = true;
+        next_position = length_min(
+          iterator_end_position(&old_iter),
+          iterator_end_position(&new_iter)
+        );
+        break;
+    }
+
+    // Ensure that both iterators are caught up to the current position.
+    while (
+      !iterator_done(&old_iter) &&
+      iterator_end_position(&old_iter).bytes <= next_position.bytes
+    ) iterator_advance(&old_iter);
+    while (
+      !iterator_done(&new_iter) &&
+      iterator_end_position(&new_iter).bytes <= next_position.bytes
+    ) iterator_advance(&new_iter);
+
+    // Ensure that both iterators are at the same depth in the tree.
+    while (old_iter.visible_depth > new_iter.visible_depth) {
+      iterator_ascend(&old_iter);
+    }
+    while (new_iter.visible_depth > old_iter.visible_depth) {
+      iterator_ascend(&new_iter);
+    }
+
+    if (is_changed) {
+      #ifdef DEBUG_GET_CHANGED_RANGES
+      printf(
+        "  change: [[%u, %u] - [%u, %u]]\n",
+        position.extent.row + 1, position.extent.column,
+        next_position.extent.row + 1, next_position.extent.column
+      );
+      #endif
+
+      ts_range_array_add(&results, position, next_position);
+    }
+
+    position = next_position;
+
+    // Keep track of the current position in the included range differences
+    // array in order to avoid scanning the entire array on each iteration.
+    while (included_range_difference_index < included_range_differences->size) {
+      const TSRange *range = &included_range_differences->contents[
+        included_range_difference_index
+      ];
+      if (range->end_byte <= position.bytes) {
+        included_range_difference_index++;
+      } else {
+        break;
+      }
+    }
+  } while (!iterator_done(&old_iter) && !iterator_done(&new_iter));
+
+  Length old_size = ts_subtree_total_size(*old_tree);
+  Length new_size = ts_subtree_total_size(*new_tree);
+  if (old_size.bytes < new_size.bytes) {
+    ts_range_array_add(&results, old_size, new_size);
+  } else if (new_size.bytes < old_size.bytes) {
+    ts_range_array_add(&results, new_size, old_size);
+  }
+
+  *cursor1 = old_iter.cursor;
+  *cursor2 = new_iter.cursor;
+  *ranges = results.contents;
+  return results.size;
+}
diff --git a/vendor/tree-sitter/lib/src/get_changed_ranges.h b/vendor/tree-sitter/lib/src/get_changed_ranges.h
new file mode 100644
--- /dev/null
+++ b/vendor/tree-sitter/lib/src/get_changed_ranges.h
@@ -0,0 +1,36 @@
+#ifndef TREE_SITTER_GET_CHANGED_RANGES_H_
+#define TREE_SITTER_GET_CHANGED_RANGES_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "./tree_cursor.h"
+#include "./subtree.h"
+
+typedef Array(TSRange) TSRangeArray;
+
+void ts_range_array_get_changed_ranges(
+  const TSRange *old_ranges, unsigned old_range_count,
+  const TSRange *new_ranges, unsigned new_range_count,
+  TSRangeArray *differences
+);
+
+bool ts_range_array_intersects(
+  const TSRangeArray *self, unsigned start_index,
+  uint32_t start_byte, uint32_t end_byte
+);
+
+unsigned ts_subtree_get_changed_ranges(
+  const Subtree *old_tree, const Subtree *new_tree,
+  TreeCursor *cursor1, TreeCursor *cursor2,
+  const TSLanguage *language,
+  const TSRangeArray *included_range_differences,
+  TSRange **ranges
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  // TREE_SITTER_GET_CHANGED_RANGES_H_
diff --git a/vendor/tree-sitter/lib/src/host.h b/vendor/tree-sitter/lib/src/host.h
new file mode 100644
--- /dev/null
+++ b/vendor/tree-sitter/lib/src/host.h
@@ -0,0 +1,21 @@
+
+// Determine endian and pointer size based on known defines.
+// TS_BIG_ENDIAN and TS_PTR_SIZE can be set as -D compiler arguments
+// to override this.
+
+#if !defined(TS_BIG_ENDIAN)
+#if (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) \
+  || (defined( __APPLE_CC__) && (defined(__ppc__) || defined(__ppc64__)))
+#define TS_BIG_ENDIAN 1
+#else
+#define TS_BIG_ENDIAN 0
+#endif
+#endif
+
+#if !defined(TS_PTR_SIZE)
+#if UINTPTR_MAX == 0xFFFFFFFF
+#define TS_PTR_SIZE 32
+#else
+#define TS_PTR_SIZE 64
+#endif
+#endif
diff --git a/vendor/tree-sitter/lib/src/language.c b/vendor/tree-sitter/lib/src/language.c
new file mode 100644
--- /dev/null
+++ b/vendor/tree-sitter/lib/src/language.c
@@ -0,0 +1,223 @@
+#include "./language.h"
+#include "./wasm_store.h"
+#include "tree_sitter/api.h"
+#include <string.h>
+
+const TSLanguage *ts_language_copy(const TSLanguage *self) {
+  if (self && ts_language_is_wasm(self)) {
+    ts_wasm_language_retain(self);
+  }
+  return self;
+}
+
+void ts_language_delete(const TSLanguage *self) {
+  if (self && ts_language_is_wasm(self)) {
+    ts_wasm_language_release(self);
+  }
+}
+
+uint32_t ts_language_symbol_count(const TSLanguage *self) {
+  return self->symbol_count + self->alias_count;
+}
+
+uint32_t ts_language_state_count(const TSLanguage *self) {
+  return self->state_count;
+}
+
+uint32_t ts_language_version(const TSLanguage *self) {
+  return self->version;
+}
+
+uint32_t ts_language_field_count(const TSLanguage *self) {
+  return self->field_count;
+}
+
+void ts_language_table_entry(
+  const TSLanguage *self,
+  TSStateId state,
+  TSSymbol symbol,
+  TableEntry *result
+) {
+  if (symbol == ts_builtin_sym_error || symbol == ts_builtin_sym_error_repeat) {
+    result->action_count = 0;
+    result->is_reusable = false;
+    result->actions = NULL;
+  } else {
+    ts_assert(symbol < self->token_count);
+    uint32_t action_index = ts_language_lookup(self, state, symbol);
+    const TSParseActionEntry *entry = &self->parse_actions[action_index];
+    result->action_count = entry->entry.count;
+    result->is_reusable = entry->entry.reusable;
+    result->actions = (const TSParseAction *)(entry + 1);
+  }
+}
+
+TSSymbolMetadata ts_language_symbol_metadata(
+  const TSLanguage *self,
+  TSSymbol symbol
+) {
+  if (symbol == ts_builtin_sym_error)  {
+    return (TSSymbolMetadata) {.visible = true, .named = true};
+  } else if (symbol == ts_builtin_sym_error_repeat) {
+    return (TSSymbolMetadata) {.visible = false, .named = false};
+  } else {
+    return self->symbol_metadata[symbol];
+  }
+}
+
+TSSymbol ts_language_public_symbol(
+  const TSLanguage *self,
+  TSSymbol symbol
+) {
+  if (symbol == ts_builtin_sym_error) return symbol;
+  return self->public_symbol_map[symbol];
+}
+
+TSStateId ts_language_next_state(
+  const TSLanguage *self,
+  TSStateId state,
+  TSSymbol symbol
+) {
+  if (symbol == ts_builtin_sym_error || symbol == ts_builtin_sym_error_repeat) {
+    return 0;
+  } else if (symbol < self->token_count) {
+    uint32_t count;
+    const TSParseAction *actions = ts_language_actions(self, state, symbol, &count);
+    if (count > 0) {
+      TSParseAction action = actions[count - 1];
+      if (action.type == TSParseActionTypeShift) {
+        return action.shift.extra ? state : action.shift.state;
+      }
+    }
+    return 0;
+  } else {
+    return ts_language_lookup(self, state, symbol);
+  }
+}
+
+const char *ts_language_symbol_name(
+  const TSLanguage *self,
+  TSSymbol symbol
+) {
+  if (symbol == ts_builtin_sym_error) {
+    return "ERROR";
+  } else if (symbol == ts_builtin_sym_error_repeat) {
+    return "_ERROR";
+  } else if (symbol < ts_language_symbol_count(self)) {
+    return self->symbol_names[symbol];
+  } else {
+    return NULL;
+  }
+}
+
+TSSymbol ts_language_symbol_for_name(
+  const TSLanguage *self,
+  const char *string,
+  uint32_t length,
+  bool is_named
+) {
+  if (!strncmp(string, "ERROR", length)) return ts_builtin_sym_error;
+  uint16_t count = (uint16_t)ts_language_symbol_count(self);
+  for (TSSymbol i = 0; i < count; i++) {
+    TSSymbolMetadata metadata = ts_language_symbol_metadata(self, i);
+    if ((!metadata.visible && !metadata.supertype) || metadata.named != is_named) continue;
+    const char *symbol_name = self->symbol_names[i];
+    if (!strncmp(symbol_name, string, length) && !symbol_name[length]) {
+      return self->public_symbol_map[i];
+    }
+  }
+  return 0;
+}
+
+TSSymbolType ts_language_symbol_type(
+  const TSLanguage *self,
+  TSSymbol symbol
+) {
+  TSSymbolMetadata metadata = ts_language_symbol_metadata(self, symbol);
+  if (metadata.named && metadata.visible) {
+    return TSSymbolTypeRegular;
+  } else if (metadata.visible) {
+    return TSSymbolTypeAnonymous;
+  } else if (metadata.supertype) {
+    return TSSymbolTypeSupertype;
+  } else {
+    return TSSymbolTypeAuxiliary;
+  }
+}
+
+const char *ts_language_field_name_for_id(
+  const TSLanguage *self,
+  TSFieldId id
+) {
+  uint32_t count = ts_language_field_count(self);
+  if (count && id <= count) {
+    return self->field_names[id];
+  } else {
+    return NULL;
+  }
+}
+
+TSFieldId ts_language_field_id_for_name(
+  const TSLanguage *self,
+  const char *name,
+  uint32_t name_length
+) {
+  uint16_t count = (uint16_t)ts_language_field_count(self);
+  for (TSSymbol i = 1; i < count + 1; i++) {
+    switch (strncmp(name, self->field_names[i], name_length)) {
+      case 0:
+        if (self->field_names[i][name_length] == 0) return i;
+        break;
+      case -1:
+        return 0;
+      default:
+        break;
+    }
+  }
+  return 0;
+}
+
+TSLookaheadIterator *ts_lookahead_iterator_new(const TSLanguage *self, TSStateId state) {
+  if (state >= self->state_count) return NULL;
+  LookaheadIterator *iterator = ts_malloc(sizeof(LookaheadIterator));
+  *iterator = ts_language_lookaheads(self, state);
+  return (TSLookaheadIterator *)iterator;
+}
+
+void ts_lookahead_iterator_delete(TSLookaheadIterator *self) {
+  ts_free(self);
+}
+
+bool ts_lookahead_iterator_reset_state(TSLookaheadIterator * self, TSStateId state) {
+  LookaheadIterator *iterator = (LookaheadIterator *)self;
+  if (state >= iterator->language->state_count) return false;
+  *iterator = ts_language_lookaheads(iterator->language, state);
+  return true;
+}
+
+const TSLanguage *ts_lookahead_iterator_language(const TSLookaheadIterator *self) {
+  const LookaheadIterator *iterator = (const LookaheadIterator *)self;
+  return iterator->language;
+}
+
+bool ts_lookahead_iterator_reset(TSLookaheadIterator *self, const TSLanguage *language, TSStateId state) {
+  if (state >= language->state_count) return false;
+  LookaheadIterator *iterator = (LookaheadIterator *)self;
+  *iterator = ts_language_lookaheads(language, state);
+  return true;
+}
+
+bool ts_lookahead_iterator_next(TSLookaheadIterator *self) {
+  LookaheadIterator *iterator = (LookaheadIterator *)self;
+  return ts_lookahead_iterator__next(iterator);
+}
+
+TSSymbol ts_lookahead_iterator_current_symbol(const TSLookaheadIterator *self) {
+  const LookaheadIterator *iterator = (const LookaheadIterator *)self;
+  return iterator->symbol;
+}
+
+const char *ts_lookahead_iterator_current_symbol_name(const TSLookaheadIterator *self) {
+  const LookaheadIterator *iterator = (const LookaheadIterator *)self;
+  return ts_language_symbol_name(iterator->language, iterator->symbol);
+}
diff --git a/vendor/tree-sitter/lib/src/language.h b/vendor/tree-sitter/lib/src/language.h
new file mode 100644
--- /dev/null
+++ b/vendor/tree-sitter/lib/src/language.h
@@ -0,0 +1,297 @@
+#ifndef TREE_SITTER_LANGUAGE_H_
+#define TREE_SITTER_LANGUAGE_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "./subtree.h"
+#include "./parser.h"
+
+#define ts_builtin_sym_error_repeat (ts_builtin_sym_error - 1)
+
+#define LANGUAGE_VERSION_WITH_PRIMARY_STATES 14
+#define LANGUAGE_VERSION_USABLE_VIA_WASM 13
+
+typedef struct {
+  const TSParseAction *actions;
+  uint32_t action_count;
+  bool is_reusable;
+} TableEntry;
+
+typedef struct {
+  const TSLanguage *language;
+  const uint16_t *data;
+  const uint16_t *group_end;
+  TSStateId state;
+  uint16_t table_value;
+  uint16_t section_index;
+  uint16_t group_count;
+  bool is_small_state;
+
+  const TSParseAction *actions;
+  TSSymbol symbol;
+  TSStateId next_state;
+  uint16_t action_count;
+} LookaheadIterator;
+
+void ts_language_table_entry(const TSLanguage *self, TSStateId state, TSSymbol symbol, TableEntry *result);
+
+TSSymbolMetadata ts_language_symbol_metadata(const TSLanguage *self, TSSymbol symbol);
+
+TSSymbol ts_language_public_symbol(const TSLanguage *self, TSSymbol symbol);
+
+static inline bool ts_language_is_symbol_external(const TSLanguage *self, TSSymbol symbol) {
+  return 0 < symbol && symbol < self->external_token_count + 1;
+}
+
+static inline const TSParseAction *ts_language_actions(
+  const TSLanguage *self,
+  TSStateId state,
+  TSSymbol symbol,
+  uint32_t *count
+) {
+  TableEntry entry;
+  ts_language_table_entry(self, state, symbol, &entry);
+  *count = entry.action_count;
+  return entry.actions;
+}
+
+static inline bool ts_language_has_reduce_action(
+  const TSLanguage *self,
+  TSStateId state,
+  TSSymbol symbol
+) {
+  TableEntry entry;
+  ts_language_table_entry(self, state, symbol, &entry);
+  return entry.action_count > 0 && entry.actions[0].type == TSParseActionTypeReduce;
+}
+
+// Lookup the table value for a given symbol and state.
+//
+// For non-terminal symbols, the table value represents a successor state.
+// For terminal symbols, it represents an index in the actions table.
+// For 'large' parse states, this is a direct lookup. For 'small' parse
+// states, this requires searching through the symbol groups to find
+// the given symbol.
+static inline uint16_t ts_language_lookup(
+  const TSLanguage *self,
+  TSStateId state,
+  TSSymbol symbol
+) {
+  if (state >= self->large_state_count) {
+    uint32_t index = self->small_parse_table_map[state - self->large_state_count];
+    const uint16_t *data = &self->small_parse_table[index];
+    uint16_t group_count = *(data++);
+    for (unsigned i = 0; i < group_count; i++) {
+      uint16_t section_value = *(data++);
+      uint16_t symbol_count = *(data++);
+      for (unsigned j = 0; j < symbol_count; j++) {
+        if (*(data++) == symbol) return section_value;
+      }
+    }
+    return 0;
+  } else {
+    return self->parse_table[state * self->symbol_count + symbol];
+  }
+}
+
+static inline bool ts_language_has_actions(
+  const TSLanguage *self,
+  TSStateId state,
+  TSSymbol symbol
+) {
+  return ts_language_lookup(self, state, symbol) != 0;
+}
+
+// Iterate over all of the symbols that are valid in the given state.
+//
+// For 'large' parse states, this just requires iterating through
+// all possible symbols and checking the parse table for each one.
+// For 'small' parse states, this exploits the structure of the
+// table to only visit the valid symbols.
+static inline LookaheadIterator ts_language_lookaheads(
+  const TSLanguage *self,
+  TSStateId state
+) {
+  bool is_small_state = state >= self->large_state_count;
+  const uint16_t *data;
+  const uint16_t *group_end = NULL;
+  uint16_t group_count = 0;
+  if (is_small_state) {
+    uint32_t index = self->small_parse_table_map[state - self->large_state_count];
+    data = &self->small_parse_table[index];
+    group_end = data + 1;
+    group_count = *data;
+  } else {
+    data = &self->parse_table[state * self->symbol_count] - 1;
+  }
+  return (LookaheadIterator) {
+    .language = self,
+    .data = data,
+    .group_end = group_end,
+    .group_count = group_count,
+    .is_small_state = is_small_state,
+    .symbol = UINT16_MAX,
+    .next_state = 0,
+  };
+}
+
+static inline bool ts_lookahead_iterator__next(LookaheadIterator *self) {
+  // For small parse states, valid symbols are listed explicitly,
+  // grouped by their value. There's no need to look up the actions
+  // again until moving to the next group.
+  if (self->is_small_state) {
+    self->data++;
+    if (self->data == self->group_end) {
+      if (self->group_count == 0) return false;
+      self->group_count--;
+      self->table_value = *(self->data++);
+      unsigned symbol_count = *(self->data++);
+      self->group_end = self->data + symbol_count;
+      self->symbol = *self->data;
+    } else {
+      self->symbol = *self->data;
+      return true;
+    }
+  }
+
+  // For large parse states, iterate through every symbol until one
+  // is found that has valid actions.
+  else {
+    do {
+      self->data++;
+      self->symbol++;
+      if (self->symbol >= self->language->symbol_count) return false;
+      self->table_value = *self->data;
+    } while (!self->table_value);
+  }
+
+  // Depending on if the symbols is terminal or non-terminal, the table value either
+  // represents a list of actions or a successor state.
+  if (self->symbol < self->language->token_count) {
+    const TSParseActionEntry *entry = &self->language->parse_actions[self->table_value];
+    self->action_count = entry->entry.count;
+    self->actions = (const TSParseAction *)(entry + 1);
+    self->next_state = 0;
+  } else {
+    self->action_count = 0;
+    self->next_state = self->table_value;
+  }
+  return true;
+}
+
+// Whether the state is a "primary state". If this returns false, it indicates that there exists
+// another state that behaves identically to this one with respect to query analysis.
+static inline bool ts_language_state_is_primary(
+  const TSLanguage *self,
+  TSStateId state
+) {
+  if (self->version >= LANGUAGE_VERSION_WITH_PRIMARY_STATES) {
+    return state == self->primary_state_ids[state];
+  } else {
+    return true;
+  }
+}
+
+static inline const bool *ts_language_enabled_external_tokens(
+  const TSLanguage *self,
+  unsigned external_scanner_state
+) {
+  if (external_scanner_state == 0) {
+    return NULL;
+  } else {
+    return self->external_scanner.states + self->external_token_count * external_scanner_state;
+  }
+}
+
+static inline const TSSymbol *ts_language_alias_sequence(
+  const TSLanguage *self,
+  uint32_t production_id
+) {
+  return production_id ?
+    &self->alias_sequences[production_id * self->max_alias_sequence_length] :
+    NULL;
+}
+
+static inline TSSymbol ts_language_alias_at(
+  const TSLanguage *self,
+  uint32_t production_id,
+  uint32_t child_index
+) {
+  return production_id ?
+    self->alias_sequences[production_id * self->max_alias_sequence_length + child_index] :
+    0;
+}
+
+static inline void ts_language_field_map(
+  const TSLanguage *self,
+  uint32_t production_id,
+  const TSFieldMapEntry **start,
+  const TSFieldMapEntry **end
+) {
+  if (self->field_count == 0) {
+    *start = NULL;
+    *end = NULL;
+    return;
+  }
+
+  TSFieldMapSlice slice = self->field_map_slices[production_id];
+  *start = &self->field_map_entries[slice.index];
+  *end = &self->field_map_entries[slice.index] + slice.length;
+}
+
+static inline void ts_language_aliases_for_symbol(
+  const TSLanguage *self,
+  TSSymbol original_symbol,
+  const TSSymbol **start,
+  const TSSymbol **end
+) {
+  *start = &self->public_symbol_map[original_symbol];
+  *end = *start + 1;
+
+  unsigned idx = 0;
+  for (;;) {
+    TSSymbol symbol = self->alias_map[idx++];
+    if (symbol == 0 || symbol > original_symbol) break;
+    uint16_t count = self->alias_map[idx++];
+    if (symbol == original_symbol) {
+      *start = &self->alias_map[idx];
+      *end = &self->alias_map[idx + count];
+      break;
+    }
+    idx += count;
+  }
+}
+
+static inline void ts_language_write_symbol_as_dot_string(
+  const TSLanguage *self,
+  FILE *f,
+  TSSymbol symbol
+) {
+  const char *name = ts_language_symbol_name(self, symbol);
+  for (const char *chr = name; *chr; chr++) {
+    switch (*chr) {
+      case '"':
+      case '\\':
+        fputc('\\', f);
+        fputc(*chr, f);
+        break;
+      case '\n':
+        fputs("\\n", f);
+        break;
+      case '\t':
+        fputs("\\t", f);
+        break;
+      default:
+        fputc(*chr, f);
+        break;
+    }
+  }
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  // TREE_SITTER_LANGUAGE_H_
diff --git a/vendor/tree-sitter/lib/src/length.h b/vendor/tree-sitter/lib/src/length.h
new file mode 100644
--- /dev/null
+++ b/vendor/tree-sitter/lib/src/length.h
@@ -0,0 +1,52 @@
+#ifndef TREE_SITTER_LENGTH_H_
+#define TREE_SITTER_LENGTH_H_
+
+#include <stdlib.h>
+#include <stdbool.h>
+#include "./point.h"
+#include "tree_sitter/api.h"
+
+typedef struct {
+  uint32_t bytes;
+  TSPoint extent;
+} Length;
+
+static const Length LENGTH_UNDEFINED = {0, {0, 1}};
+static const Length LENGTH_MAX = {UINT32_MAX, {UINT32_MAX, UINT32_MAX}};
+
+static inline bool length_is_undefined(Length length) {
+  return length.bytes == 0 && length.extent.column != 0;
+}
+
+static inline Length length_min(Length len1, Length len2) {
+  return (len1.bytes < len2.bytes) ? len1 : len2;
+}
+
+static inline Length length_add(Length len1, Length len2) {
+  Length result;
+  result.bytes = len1.bytes + len2.bytes;
+  result.extent = point_add(len1.extent, len2.extent);
+  return result;
+}
+
+static inline Length length_sub(Length len1, Length len2) {
+  Length result;
+  result.bytes = len1.bytes - len2.bytes;
+  result.extent = point_sub(len1.extent, len2.extent);
+  return result;
+}
+
+static inline Length length_zero(void) {
+  Length result = {0, {0, 0}};
+  return result;
+}
+
+static inline Length length_saturating_sub(Length len1, Length len2) {
+  if (len1.bytes > len2.bytes) {
+    return length_sub(len1, len2);
+  } else {
+    return length_zero();
+  }
+}
+
+#endif
diff --git a/vendor/tree-sitter/lib/src/lexer.c b/vendor/tree-sitter/lib/src/lexer.c
new file mode 100644
--- /dev/null
+++ b/vendor/tree-sitter/lib/src/lexer.c
@@ -0,0 +1,432 @@
+#include <stdio.h>
+#include "./lexer.h"
+#include "./subtree.h"
+#include "./length.h"
+#include "./unicode.h"
+#include <stdarg.h>
+
+#define LOG(message, character)              \
+  if (self->logger.log) {                    \
+    snprintf(                                \
+      self->debug_buffer,                    \
+      TREE_SITTER_SERIALIZATION_BUFFER_SIZE, \
+      32 <= character && character < 127 ?   \
+        message " character:'%c'" :          \
+        message " character:%d",             \
+      character                              \
+    );                                       \
+    self->logger.log(                        \
+      self->logger.payload,                  \
+      TSLogTypeLex,                          \
+      self->debug_buffer                     \
+    );                                       \
+  }
+
+static const int32_t BYTE_ORDER_MARK = 0xFEFF;
+
+static const TSRange DEFAULT_RANGE = {
+  .start_point = {
+    .row = 0,
+    .column = 0,
+  },
+  .end_point = {
+    .row = UINT32_MAX,
+    .column = UINT32_MAX,
+  },
+  .start_byte = 0,
+  .end_byte = UINT32_MAX
+};
+
+// Check if the lexer has reached EOF. This state is stored
+// by setting the lexer's `current_included_range_index` such that
+// it has consumed all of its available ranges.
+static bool ts_lexer__eof(const TSLexer *_self) {
+  Lexer *self = (Lexer *)_self;
+  return self->current_included_range_index == self->included_range_count;
+}
+
+// Clear the currently stored chunk of source code, because the lexer's
+// position has changed.
+static void ts_lexer__clear_chunk(Lexer *self) {
+  self->chunk = NULL;
+  self->chunk_size = 0;
+  self->chunk_start = 0;
+}
+
+// Call the lexer's input callback to obtain a new chunk of source code
+// for the current position.
+static void ts_lexer__get_chunk(Lexer *self) {
+  self->chunk_start = self->current_position.bytes;
+  self->chunk = self->input.read(
+    self->input.payload,
+    self->current_position.bytes,
+    self->current_position.extent,
+    &self->chunk_size
+  );
+  if (!self->chunk_size) {
+    self->current_included_range_index = self->included_range_count;
+    self->chunk = NULL;
+  }
+}
+
+// Decode the next unicode character in the current chunk of source code.
+// This assumes that the lexer has already retrieved a chunk of source
+// code that spans the current position.
+static void ts_lexer__get_lookahead(Lexer *self) {
+  uint32_t position_in_chunk = self->current_position.bytes - self->chunk_start;
+  uint32_t size = self->chunk_size - position_in_chunk;
+
+  if (size == 0) {
+    self->lookahead_size = 1;
+    self->data.lookahead = '\0';
+    return;
+  }
+
+  const uint8_t *chunk = (const uint8_t *)self->chunk + position_in_chunk;
+  UnicodeDecodeFunction decode = self->input.encoding == TSInputEncodingUTF8
+    ? ts_decode_utf8
+    : ts_decode_utf16;
+
+  self->lookahead_size = decode(chunk, size, &self->data.lookahead);
+
+  // If this chunk ended in the middle of a multi-byte character,
+  // try again with a fresh chunk.
+  if (self->data.lookahead == TS_DECODE_ERROR && size < 4) {
+    ts_lexer__get_chunk(self);
+    chunk = (const uint8_t *)self->chunk;
+    size = self->chunk_size;
+    self->lookahead_size = decode(chunk, size, &self->data.lookahead);
+  }
+
+  if (self->data.lookahead == TS_DECODE_ERROR) {
+    self->lookahead_size = 1;
+  }
+}
+
+static void ts_lexer_goto(Lexer *self, Length position) {
+  self->current_position = position;
+
+  // Move to the first valid position at or after the given position.
+  bool found_included_range = false;
+  for (unsigned i = 0; i < self->included_range_count; i++) {
+    TSRange *included_range = &self->included_ranges[i];
+    if (
+      included_range->end_byte > self->current_position.bytes &&
+      included_range->end_byte > included_range->start_byte
+    ) {
+      if (included_range->start_byte >= self->current_position.bytes) {
+        self->current_position = (Length) {
+          .bytes = included_range->start_byte,
+          .extent = included_range->start_point,
+        };
+      }
+
+      self->current_included_range_index = i;
+      found_included_range = true;
+      break;
+    }
+  }
+
+  if (found_included_range) {
+    // If the current position is outside of the current chunk of text,
+    // then clear out the current chunk of text.
+    if (self->chunk && (
+      self->current_position.bytes < self->chunk_start ||
+      self->current_position.bytes >= self->chunk_start + self->chunk_size
+    )) {
+      ts_lexer__clear_chunk(self);
+    }
+
+    self->lookahead_size = 0;
+    self->data.lookahead = '\0';
+  }
+
+  // If the given position is beyond any of included ranges, move to the EOF
+  // state - past the end of the included ranges.
+  else {
+    self->current_included_range_index = self->included_range_count;
+    TSRange *last_included_range = &self->included_ranges[self->included_range_count - 1];
+    self->current_position = (Length) {
+      .bytes = last_included_range->end_byte,
+      .extent = last_included_range->end_point,
+    };
+    ts_lexer__clear_chunk(self);
+    self->lookahead_size = 1;
+    self->data.lookahead = '\0';
+  }
+}
+
+// Intended to be called only from functions that control logging.
+static void ts_lexer__do_advance(Lexer *self, bool skip) {
+  if (self->lookahead_size) {
+    self->current_position.bytes += self->lookahead_size;
+    if (self->data.lookahead == '\n') {
+      self->current_position.extent.row++;
+      self->current_position.extent.column = 0;
+    } else {
+      self->current_position.extent.column += self->lookahead_size;
+    }
+  }
+
+  const TSRange *current_range = &self->included_ranges[self->current_included_range_index];
+  while (
+    self->current_position.bytes >= current_range->end_byte ||
+    current_range->end_byte == current_range->start_byte
+  ) {
+    if (self->current_included_range_index < self->included_range_count) {
+      self->current_included_range_index++;
+    }
+    if (self->current_included_range_index < self->included_range_count) {
+      current_range++;
+      self->current_position = (Length) {
+        current_range->start_byte,
+        current_range->start_point,
+      };
+    } else {
+      current_range = NULL;
+      break;
+    }
+  }
+
+  if (skip) self->token_start_position = self->current_position;
+
+  if (current_range) {
+    if (
+      self->current_position.bytes < self->chunk_start ||
+      self->current_position.bytes >= self->chunk_start + self->chunk_size
+    ) {
+      ts_lexer__get_chunk(self);
+    }
+    ts_lexer__get_lookahead(self);
+  } else {
+    ts_lexer__clear_chunk(self);
+    self->data.lookahead = '\0';
+    self->lookahead_size = 1;
+  }
+}
+
+// Advance to the next character in the source code, retrieving a new
+// chunk of source code if needed.
+static void ts_lexer__advance(TSLexer *_self, bool skip) {
+  Lexer *self = (Lexer *)_self;
+  if (!self->chunk) return;
+
+  if (skip) {
+    LOG("skip", self->data.lookahead)
+  } else {
+    LOG("consume", self->data.lookahead)
+  }
+
+  ts_lexer__do_advance(self, skip);
+}
+
+// Mark that a token match has completed. This can be called multiple
+// times if a longer match is found later.
+static void ts_lexer__mark_end(TSLexer *_self) {
+  Lexer *self = (Lexer *)_self;
+  if (!ts_lexer__eof(&self->data)) {
+    // If the lexer is right at the beginning of included range,
+    // then the token should be considered to end at the *end* of the
+    // previous included range, rather than here.
+    TSRange *current_included_range = &self->included_ranges[
+      self->current_included_range_index
+    ];
+    if (
+      self->current_included_range_index > 0 &&
+      self->current_position.bytes == current_included_range->start_byte
+    ) {
+      TSRange *previous_included_range = current_included_range - 1;
+      self->token_end_position = (Length) {
+        previous_included_range->end_byte,
+        previous_included_range->end_point,
+      };
+      return;
+    }
+  }
+  self->token_end_position = self->current_position;
+}
+
+static uint32_t ts_lexer__get_column(TSLexer *_self) {
+  Lexer *self = (Lexer *)_self;
+
+  uint32_t goal_byte = self->current_position.bytes;
+
+  self->did_get_column = true;
+  Length start_of_col = {
+    self->current_position.bytes - self->current_position.extent.column,
+    {self->current_position.extent.row, 0},
+  };
+  ts_lexer_goto(self, start_of_col);
+  ts_lexer__get_chunk(self);
+
+  uint32_t result = 0;
+  if (!ts_lexer__eof(_self)) {
+    ts_lexer__get_lookahead(self);
+    while (self->current_position.bytes < goal_byte && self->chunk) {
+      result++;
+      ts_lexer__do_advance(self, false);
+      if (ts_lexer__eof(_self)) break;
+    }
+  }
+
+  return result;
+}
+
+// Is the lexer at a boundary between two disjoint included ranges of
+// source code? This is exposed as an API because some languages' external
+// scanners need to perform custom actions at these boundaries.
+static bool ts_lexer__is_at_included_range_start(const TSLexer *_self) {
+  const Lexer *self = (const Lexer *)_self;
+  if (self->current_included_range_index < self->included_range_count) {
+    TSRange *current_range = &self->included_ranges[self->current_included_range_index];
+    return self->current_position.bytes == current_range->start_byte;
+  } else {
+    return false;
+  }
+}
+
+static void ts_lexer__log(const TSLexer *_self, const char *fmt, ...) {
+  Lexer *self = (Lexer *)_self;
+  va_list args;
+  va_start(args, fmt);
+  if (self->logger.log) {
+    vsnprintf(self->debug_buffer, TREE_SITTER_SERIALIZATION_BUFFER_SIZE, fmt, args);
+    self->logger.log(self->logger.payload, TSLogTypeLex, self->debug_buffer);
+  }
+  va_end(args);
+}
+
+void ts_lexer_init(Lexer *self) {
+  *self = (Lexer) {
+    .data = {
+      // The lexer's methods are stored as struct fields so that generated
+      // parsers can call them without needing to be linked against this
+      // library.
+      .advance = ts_lexer__advance,
+      .mark_end = ts_lexer__mark_end,
+      .get_column = ts_lexer__get_column,
+      .is_at_included_range_start = ts_lexer__is_at_included_range_start,
+      .eof = ts_lexer__eof,
+      .log = ts_lexer__log,
+      .lookahead = 0,
+      .result_symbol = 0,
+    },
+    .chunk = NULL,
+    .chunk_size = 0,
+    .chunk_start = 0,
+    .current_position = {0, {0, 0}},
+    .logger = {
+      .payload = NULL,
+      .log = NULL
+    },
+    .included_ranges = NULL,
+    .included_range_count = 0,
+    .current_included_range_index = 0,
+  };
+  ts_lexer_set_included_ranges(self, NULL, 0);
+}
+
+void ts_lexer_delete(Lexer *self) {
+  ts_free(self->included_ranges);
+}
+
+void ts_lexer_set_input(Lexer *self, TSInput input) {
+  self->input = input;
+  ts_lexer__clear_chunk(self);
+  ts_lexer_goto(self, self->current_position);
+}
+
+// Move the lexer to the given position. This doesn't do any work
+// if the parser is already at the given position.
+void ts_lexer_reset(Lexer *self, Length position) {
+  if (position.bytes != self->current_position.bytes) {
+    ts_lexer_goto(self, position);
+  }
+}
+
+void ts_lexer_start(Lexer *self) {
+  self->token_start_position = self->current_position;
+  self->token_end_position = LENGTH_UNDEFINED;
+  self->data.result_symbol = 0;
+  self->did_get_column = false;
+  if (!ts_lexer__eof(&self->data)) {
+    if (!self->chunk_size) ts_lexer__get_chunk(self);
+    if (!self->lookahead_size) ts_lexer__get_lookahead(self);
+    if (
+      self->current_position.bytes == 0 &&
+      self->data.lookahead == BYTE_ORDER_MARK
+    ) ts_lexer__advance(&self->data, true);
+  }
+}
+
+void ts_lexer_finish(Lexer *self, uint32_t *lookahead_end_byte) {
+  if (length_is_undefined(self->token_end_position)) {
+    ts_lexer__mark_end(&self->data);
+  }
+
+  // If the token ended at an included range boundary, then its end position
+  // will have been reset to the end of the preceding range. Reset the start
+  // position to match.
+  if (self->token_end_position.bytes < self->token_start_position.bytes) {
+    self->token_start_position = self->token_end_position;
+  }
+
+  uint32_t current_lookahead_end_byte = self->current_position.bytes + 1;
+
+  // In order to determine that a byte sequence is invalid UTF8 or UTF16,
+  // the character decoding algorithm may have looked at the following byte.
+  // Therefore, the next byte *after* the current (invalid) character
+  // affects the interpretation of the current character.
+  if (self->data.lookahead == TS_DECODE_ERROR) {
+    current_lookahead_end_byte += 4; // the maximum number of bytes read to identify an invalid code point
+  }
+
+  if (current_lookahead_end_byte > *lookahead_end_byte) {
+    *lookahead_end_byte = current_lookahead_end_byte;
+  }
+}
+
+void ts_lexer_advance_to_end(Lexer *self) {
+  while (self->chunk) {
+    ts_lexer__advance(&self->data, false);
+  }
+}
+
+void ts_lexer_mark_end(Lexer *self) {
+  ts_lexer__mark_end(&self->data);
+}
+
+bool ts_lexer_set_included_ranges(
+  Lexer *self,
+  const TSRange *ranges,
+  uint32_t count
+) {
+  if (count == 0 || !ranges) {
+    ranges = &DEFAULT_RANGE;
+    count = 1;
+  } else {
+    uint32_t previous_byte = 0;
+    for (unsigned i = 0; i < count; i++) {
+      const TSRange *range = &ranges[i];
+      if (
+        range->start_byte < previous_byte ||
+        range->end_byte < range->start_byte
+      ) return false;
+      previous_byte = range->end_byte;
+    }
+  }
+
+  size_t size = count * sizeof(TSRange);
+  self->included_ranges = ts_realloc(self->included_ranges, size);
+  memcpy(self->included_ranges, ranges, size);
+  self->included_range_count = count;
+  ts_lexer_goto(self, self->current_position);
+  return true;
+}
+
+TSRange *ts_lexer_included_ranges(const Lexer *self, uint32_t *count) {
+  *count = self->included_range_count;
+  return self->included_ranges;
+}
+
+#undef LOG
diff --git a/vendor/tree-sitter/lib/src/lexer.h b/vendor/tree-sitter/lib/src/lexer.h
new file mode 100644
--- /dev/null
+++ b/vendor/tree-sitter/lib/src/lexer.h
@@ -0,0 +1,49 @@
+#ifndef TREE_SITTER_LEXER_H_
+#define TREE_SITTER_LEXER_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "./length.h"
+#include "./subtree.h"
+#include "tree_sitter/api.h"
+#include "./parser.h"
+
+typedef struct {
+  TSLexer data;
+  Length current_position;
+  Length token_start_position;
+  Length token_end_position;
+
+  TSRange *included_ranges;
+  const char *chunk;
+  TSInput input;
+  TSLogger logger;
+
+  uint32_t included_range_count;
+  uint32_t current_included_range_index;
+  uint32_t chunk_start;
+  uint32_t chunk_size;
+  uint32_t lookahead_size;
+  bool did_get_column;
+
+  char debug_buffer[TREE_SITTER_SERIALIZATION_BUFFER_SIZE];
+} Lexer;
+
+void ts_lexer_init(Lexer *self);
+void ts_lexer_delete(Lexer *self);
+void ts_lexer_set_input(Lexer *self, TSInput input);
+void ts_lexer_reset(Lexer *self, Length position);
+void ts_lexer_start(Lexer *self);
+void ts_lexer_finish(Lexer *self, uint32_t *lookahead_end_byte);
+void ts_lexer_advance_to_end(Lexer *self);
+void ts_lexer_mark_end(Lexer *self);
+bool ts_lexer_set_included_ranges(Lexer *self, const TSRange *ranges, uint32_t count);
+TSRange *ts_lexer_included_ranges(const Lexer *self, uint32_t *count);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  // TREE_SITTER_LEXER_H_
diff --git a/vendor/tree-sitter/lib/src/lib.c b/vendor/tree-sitter/lib/src/lib.c
new file mode 100644
--- /dev/null
+++ b/vendor/tree-sitter/lib/src/lib.c
@@ -0,0 +1,14 @@
+#define _POSIX_C_SOURCE 200112L
+
+#include "./alloc.c"
+#include "./get_changed_ranges.c"
+#include "./language.c"
+#include "./lexer.c"
+#include "./node.c"
+#include "./parser.c"
+#include "./query.c"
+#include "./stack.c"
+#include "./subtree.c"
+#include "./tree_cursor.c"
+#include "./tree.c"
+#include "./wasm_store.c"
diff --git a/vendor/tree-sitter/lib/src/node.c b/vendor/tree-sitter/lib/src/node.c
new file mode 100644
--- /dev/null
+++ b/vendor/tree-sitter/lib/src/node.c
@@ -0,0 +1,920 @@
+#include <stdbool.h>
+#include "./subtree.h"
+#include "./tree.h"
+#include "./language.h"
+
+typedef struct {
+  Subtree parent;
+  const TSTree *tree;
+  Length position;
+  uint32_t child_index;
+  uint32_t structural_child_index;
+  const TSSymbol *alias_sequence;
+} NodeChildIterator;
+
+static inline bool ts_node__is_relevant(TSNode self, bool include_anonymous);
+
+// TSNode - constructors
+
+TSNode ts_node_new(
+  const TSTree *tree,
+  const Subtree *subtree,
+  Length position,
+  TSSymbol alias
+) {
+  return (TSNode) {
+    {position.bytes, position.extent.row, position.extent.column, alias},
+    subtree,
+    tree,
+  };
+}
+
+static inline TSNode ts_node__null(void) {
+  return ts_node_new(NULL, NULL, length_zero(), 0);
+}
+
+// TSNode - accessors
+
+uint32_t ts_node_start_byte(TSNode self) {
+  return self.context[0];
+}
+
+TSPoint ts_node_start_point(TSNode self) {
+  return (TSPoint) {self.context[1], self.context[2]};
+}
+
+static inline uint32_t ts_node__alias(const TSNode *self) {
+  return self->context[3];
+}
+
+static inline Subtree ts_node__subtree(TSNode self) {
+  return *(const Subtree *)self.id;
+}
+
+// NodeChildIterator
+
+static inline NodeChildIterator ts_node_iterate_children(const TSNode *node) {
+  Subtree subtree = ts_node__subtree(*node);
+  if (ts_subtree_child_count(subtree) == 0) {
+    return (NodeChildIterator) {NULL_SUBTREE, node->tree, length_zero(), 0, 0, NULL};
+  }
+  const TSSymbol *alias_sequence = ts_language_alias_sequence(
+    node->tree->language,
+    subtree.ptr->production_id
+  );
+  return (NodeChildIterator) {
+    .tree = node->tree,
+    .parent = subtree,
+    .position = {ts_node_start_byte(*node), ts_node_start_point(*node)},
+    .child_index = 0,
+    .structural_child_index = 0,
+    .alias_sequence = alias_sequence,
+  };
+}
+
+static inline bool ts_node_child_iterator_done(NodeChildIterator *self) {
+  return self->child_index == self->parent.ptr->child_count;
+}
+
+static inline bool ts_node_child_iterator_next(
+  NodeChildIterator *self,
+  TSNode *result
+) {
+  if (!self->parent.ptr || ts_node_child_iterator_done(self)) return false;
+  const Subtree *child = &ts_subtree_children(self->parent)[self->child_index];
+  TSSymbol alias_symbol = 0;
+  if (!ts_subtree_extra(*child)) {
+    if (self->alias_sequence) {
+      alias_symbol = self->alias_sequence[self->structural_child_index];
+    }
+    self->structural_child_index++;
+  }
+  if (self->child_index > 0) {
+    self->position = length_add(self->position, ts_subtree_padding(*child));
+  }
+  *result = ts_node_new(
+    self->tree,
+    child,
+    self->position,
+    alias_symbol
+  );
+  self->position = length_add(self->position, ts_subtree_size(*child));
+  self->child_index++;
+  return true;
+}
+
+// This will return true if the next sibling is a zero-width token that is adjacent to the current node and is relevant
+static inline bool ts_node_child_iterator_next_sibling_is_empty_adjacent(NodeChildIterator *self, TSNode previous) {
+  if (!self->parent.ptr || ts_node_child_iterator_done(self)) return false;
+  if (self->child_index == 0) return false;
+  const Subtree *child = &ts_subtree_children(self->parent)[self->child_index];
+  TSSymbol alias = 0;
+  if (!ts_subtree_extra(*child)) {
+    if (self->alias_sequence) {
+      alias = self->alias_sequence[self->structural_child_index];
+    }
+  }
+  TSNode next = ts_node_new(self->tree, child, self->position, alias);
+  return ts_node_end_byte(previous) == ts_node_end_byte(next) && ts_node__is_relevant(next, true);
+}
+
+// TSNode - private
+
+static inline bool ts_node__is_relevant(TSNode self, bool include_anonymous) {
+  Subtree tree = ts_node__subtree(self);
+  if (include_anonymous) {
+    return ts_subtree_visible(tree) || ts_node__alias(&self);
+  } else {
+    TSSymbol alias = ts_node__alias(&self);
+    if (alias) {
+      return ts_language_symbol_metadata(self.tree->language, alias).named;
+    } else {
+      return ts_subtree_visible(tree) && ts_subtree_named(tree);
+    }
+  }
+}
+
+static inline uint32_t ts_node__relevant_child_count(
+  TSNode self,
+  bool include_anonymous
+) {
+  Subtree tree = ts_node__subtree(self);
+  if (ts_subtree_child_count(tree) > 0) {
+    if (include_anonymous) {
+      return tree.ptr->visible_child_count;
+    } else {
+      return tree.ptr->named_child_count;
+    }
+  } else {
+    return 0;
+  }
+}
+
+static inline TSNode ts_node__child(
+  TSNode self,
+  uint32_t child_index,
+  bool include_anonymous
+) {
+  TSNode result = self;
+  bool did_descend = true;
+
+  while (did_descend) {
+    did_descend = false;
+
+    TSNode child;
+    uint32_t index = 0;
+    NodeChildIterator iterator = ts_node_iterate_children(&result);
+    while (ts_node_child_iterator_next(&iterator, &child)) {
+      if (ts_node__is_relevant(child, include_anonymous)) {
+        if (index == child_index) {
+          return child;
+        }
+        index++;
+      } else {
+        uint32_t grandchild_index = child_index - index;
+        uint32_t grandchild_count = ts_node__relevant_child_count(child, include_anonymous);
+        if (grandchild_index < grandchild_count) {
+          did_descend = true;
+          result = child;
+          child_index = grandchild_index;
+          break;
+        }
+        index += grandchild_count;
+      }
+    }
+  }
+
+  return ts_node__null();
+}
+
+static bool ts_subtree_has_trailing_empty_descendant(
+  Subtree self,
+  Subtree other
+) {
+  for (unsigned i = ts_subtree_child_count(self) - 1; i + 1 > 0; i--) {
+    Subtree child = ts_subtree_children(self)[i];
+    if (ts_subtree_total_bytes(child) > 0) break;
+    if (child.ptr == other.ptr || ts_subtree_has_trailing_empty_descendant(child, other)) {
+      return true;
+    }
+  }
+  return false;
+}
+
+static inline TSNode ts_node__prev_sibling(TSNode self, bool include_anonymous) {
+  Subtree self_subtree = ts_node__subtree(self);
+  bool self_is_empty = ts_subtree_total_bytes(self_subtree) == 0;
+  uint32_t target_end_byte = ts_node_end_byte(self);
+
+  TSNode node = ts_node_parent(self);
+  TSNode earlier_node = ts_node__null();
+  bool earlier_node_is_relevant = false;
+
+  while (!ts_node_is_null(node)) {
+    TSNode earlier_child = ts_node__null();
+    bool earlier_child_is_relevant = false;
+    bool found_child_containing_target = false;
+
+    TSNode child;
+    NodeChildIterator iterator = ts_node_iterate_children(&node);
+    while (ts_node_child_iterator_next(&iterator, &child)) {
+      if (child.id == self.id) break;
+      if (iterator.position.bytes > target_end_byte) {
+        found_child_containing_target = true;
+        break;
+      }
+
+      if (iterator.position.bytes == target_end_byte &&
+          (!self_is_empty ||
+           ts_subtree_has_trailing_empty_descendant(ts_node__subtree(child), self_subtree))) {
+        found_child_containing_target = true;
+        break;
+      }
+
+      if (ts_node__is_relevant(child, include_anonymous)) {
+        earlier_child = child;
+        earlier_child_is_relevant = true;
+      } else if (ts_node__relevant_child_count(child, include_anonymous) > 0) {
+        earlier_child = child;
+        earlier_child_is_relevant = false;
+      }
+    }
+
+    if (found_child_containing_target) {
+      if (!ts_node_is_null(earlier_child)) {
+        earlier_node = earlier_child;
+        earlier_node_is_relevant = earlier_child_is_relevant;
+      }
+      node = child;
+    } else if (earlier_child_is_relevant) {
+      return earlier_child;
+    } else if (!ts_node_is_null(earlier_child)) {
+      node = earlier_child;
+    } else if (earlier_node_is_relevant) {
+      return earlier_node;
+    } else {
+      node = earlier_node;
+      earlier_node = ts_node__null();
+      earlier_node_is_relevant = false;
+    }
+  }
+
+  return ts_node__null();
+}
+
+static inline TSNode ts_node__next_sibling(TSNode self, bool include_anonymous) {
+  uint32_t target_end_byte = ts_node_end_byte(self);
+
+  TSNode node = ts_node_parent(self);
+  TSNode later_node = ts_node__null();
+  bool later_node_is_relevant = false;
+
+  while (!ts_node_is_null(node)) {
+    TSNode later_child = ts_node__null();
+    bool later_child_is_relevant = false;
+    TSNode child_containing_target = ts_node__null();
+
+    TSNode child;
+    NodeChildIterator iterator = ts_node_iterate_children(&node);
+    while (ts_node_child_iterator_next(&iterator, &child)) {
+      if (iterator.position.bytes < target_end_byte) continue;
+      if (ts_node_start_byte(child) <= ts_node_start_byte(self)) {
+        if (ts_node__subtree(child).ptr != ts_node__subtree(self).ptr) {
+          child_containing_target = child;
+        }
+      } else if (ts_node__is_relevant(child, include_anonymous)) {
+        later_child = child;
+        later_child_is_relevant = true;
+        break;
+      } else if (ts_node__relevant_child_count(child, include_anonymous) > 0) {
+        later_child = child;
+        later_child_is_relevant = false;
+        break;
+      }
+    }
+
+    if (!ts_node_is_null(child_containing_target)) {
+      if (!ts_node_is_null(later_child)) {
+        later_node = later_child;
+        later_node_is_relevant = later_child_is_relevant;
+      }
+      node = child_containing_target;
+    } else if (later_child_is_relevant) {
+      return later_child;
+    } else if (!ts_node_is_null(later_child)) {
+      node = later_child;
+    } else if (later_node_is_relevant) {
+      return later_node;
+    } else {
+      node = later_node;
+    }
+  }
+
+  return ts_node__null();
+}
+
+static inline TSNode ts_node__first_child_for_byte(
+  TSNode self,
+  uint32_t goal,
+  bool include_anonymous
+) {
+  TSNode node = self;
+  bool did_descend = true;
+
+  NodeChildIterator last_iterator;
+  bool has_last_iterator = false;
+
+  while (did_descend) {
+    did_descend = false;
+
+    TSNode child;
+    NodeChildIterator iterator = ts_node_iterate_children(&node);
+  loop:
+    while (ts_node_child_iterator_next(&iterator, &child)) {
+      if (ts_node_end_byte(child) > goal) {
+        if (ts_node__is_relevant(child, include_anonymous)) {
+          return child;
+        } else if (ts_node_child_count(child) > 0) {
+          if (iterator.child_index < ts_subtree_child_count(ts_node__subtree(child))) {
+            last_iterator = iterator;
+            has_last_iterator = true;
+          }
+          did_descend = true;
+          node = child;
+          break;
+        }
+      }
+    }
+
+    if (!did_descend && has_last_iterator) {
+      iterator = last_iterator;
+      has_last_iterator = false;
+      goto loop;
+    }
+  }
+
+  return ts_node__null();
+}
+
+static inline TSNode ts_node__descendant_for_byte_range(
+  TSNode self,
+  uint32_t range_start,
+  uint32_t range_end,
+  bool include_anonymous
+) {
+  TSNode node = self;
+  TSNode last_visible_node = self;
+
+  bool did_descend = true;
+  while (did_descend) {
+    did_descend = false;
+
+    TSNode child;
+    NodeChildIterator iterator = ts_node_iterate_children(&node);
+    while (ts_node_child_iterator_next(&iterator, &child)) {
+      uint32_t node_end = iterator.position.bytes;
+
+      // The end of this node must extend far enough forward to touch
+      // the end of the range
+      if (node_end < range_end) continue;
+
+      // ...and exceed the start of the range, unless the node itself is
+      // empty, in which case it must at least be equal to the start of the range.
+      bool is_empty = ts_node_start_byte(child) == node_end;
+      if (is_empty ? node_end < range_start : node_end <= range_start) continue;
+
+      // The start of this node must extend far enough backward to
+      // touch the start of the range.
+      if (range_start < ts_node_start_byte(child)) break;
+
+      node = child;
+      if (ts_node__is_relevant(node, include_anonymous)) {
+        last_visible_node = node;
+      }
+      did_descend = true;
+      break;
+    }
+  }
+
+  return last_visible_node;
+}
+
+static inline TSNode ts_node__descendant_for_point_range(
+  TSNode self,
+  TSPoint range_start,
+  TSPoint range_end,
+  bool include_anonymous
+) {
+  TSNode node = self;
+  TSNode last_visible_node = self;
+
+  bool did_descend = true;
+  while (did_descend) {
+    did_descend = false;
+
+    TSNode child;
+    NodeChildIterator iterator = ts_node_iterate_children(&node);
+    while (ts_node_child_iterator_next(&iterator, &child)) {
+      TSPoint node_end = iterator.position.extent;
+
+      // The end of this node must extend far enough forward to touch
+      // the end of the range
+      if (point_lt(node_end, range_end)) continue;
+
+      // ...and exceed the start of the range, unless the node itself is
+      // empty, in which case it must at least be equal to the start of the range.
+      bool is_empty =  point_eq(ts_node_start_point(child), node_end);
+      if (is_empty ? point_lt(node_end, range_start) : point_lte(node_end, range_start)) {
+        continue;
+      }
+
+      // The start of this node must extend far enough backward to
+      // touch the start of the range.
+      if (point_lt(range_start, ts_node_start_point(child))) break;
+
+      node = child;
+      if (ts_node__is_relevant(node, include_anonymous)) {
+        last_visible_node = node;
+      }
+      did_descend = true;
+      break;
+    }
+  }
+
+  return last_visible_node;
+}
+
+// TSNode - public
+
+uint32_t ts_node_end_byte(TSNode self) {
+  return ts_node_start_byte(self) + ts_subtree_size(ts_node__subtree(self)).bytes;
+}
+
+TSPoint ts_node_end_point(TSNode self) {
+  return point_add(ts_node_start_point(self), ts_subtree_size(ts_node__subtree(self)).extent);
+}
+
+TSSymbol ts_node_symbol(TSNode self) {
+  TSSymbol symbol = ts_node__alias(&self);
+  if (!symbol) symbol = ts_subtree_symbol(ts_node__subtree(self));
+  return ts_language_public_symbol(self.tree->language, symbol);
+}
+
+const char *ts_node_type(TSNode self) {
+  TSSymbol symbol = ts_node__alias(&self);
+  if (!symbol) symbol = ts_subtree_symbol(ts_node__subtree(self));
+  return ts_language_symbol_name(self.tree->language, symbol);
+}
+
+const TSLanguage *ts_node_language(TSNode self) {
+  return self.tree->language;
+}
+
+TSSymbol ts_node_grammar_symbol(TSNode self) {
+  return ts_subtree_symbol(ts_node__subtree(self));
+}
+
+const char *ts_node_grammar_type(TSNode self) {
+  TSSymbol symbol = ts_subtree_symbol(ts_node__subtree(self));
+  return ts_language_symbol_name(self.tree->language, symbol);
+}
+
+char *ts_node_string(TSNode self) {
+  TSSymbol alias_symbol = ts_node__alias(&self);
+  return ts_subtree_string(
+    ts_node__subtree(self),
+    alias_symbol,
+    ts_language_symbol_metadata(self.tree->language, alias_symbol).visible,
+    self.tree->language,
+    false
+  );
+}
+
+bool ts_node_eq(TSNode self, TSNode other) {
+  return self.tree == other.tree && self.id == other.id;
+}
+
+bool ts_node_is_null(TSNode self) {
+  return self.id == 0;
+}
+
+bool ts_node_is_extra(TSNode self) {
+  return ts_subtree_extra(ts_node__subtree(self));
+}
+
+bool ts_node_is_named(TSNode self) {
+  TSSymbol alias = ts_node__alias(&self);
+  return alias
+    ? ts_language_symbol_metadata(self.tree->language, alias).named
+    : ts_subtree_named(ts_node__subtree(self));
+}
+
+bool ts_node_is_missing(TSNode self) {
+  return ts_subtree_missing(ts_node__subtree(self));
+}
+
+bool ts_node_has_changes(TSNode self) {
+  return ts_subtree_has_changes(ts_node__subtree(self));
+}
+
+bool ts_node_has_error(TSNode self) {
+  return ts_subtree_error_cost(ts_node__subtree(self)) > 0;
+}
+
+bool ts_node_is_error(TSNode self) {
+  TSSymbol symbol = ts_node_symbol(self);
+  return symbol == ts_builtin_sym_error;
+}
+
+uint32_t ts_node_descendant_count(TSNode self) {
+  return ts_subtree_visible_descendant_count(ts_node__subtree(self)) + 1;
+}
+
+TSStateId ts_node_parse_state(TSNode self) {
+  return ts_subtree_parse_state(ts_node__subtree(self));
+}
+
+TSStateId ts_node_next_parse_state(TSNode self) {
+  const TSLanguage *language = self.tree->language;
+  uint16_t state = ts_node_parse_state(self);
+  if (state == TS_TREE_STATE_NONE) {
+    return TS_TREE_STATE_NONE;
+  }
+  uint16_t symbol = ts_node_grammar_symbol(self);
+  return ts_language_next_state(language, state, symbol);
+}
+
+TSNode ts_node_parent(TSNode self) {
+  TSNode node = ts_tree_root_node(self.tree);
+  if (node.id == self.id) return ts_node__null();
+
+  while (true) {
+   TSNode next_node = ts_node_child_containing_descendant(node, self);
+   if (ts_node_is_null(next_node)) break;
+   node = next_node;
+  }
+
+  return node;
+}
+
+TSNode ts_node_child_containing_descendant(TSNode self, TSNode descendant) {
+  uint32_t start_byte = ts_node_start_byte(descendant);
+  uint32_t end_byte = ts_node_end_byte(descendant);
+
+  do {
+    NodeChildIterator iter = ts_node_iterate_children(&self);
+    do {
+      if (
+        !ts_node_child_iterator_next(&iter, &self)
+        || ts_node_start_byte(self) > start_byte
+        || self.id == descendant.id
+      ) {
+        return ts_node__null();
+      }
+
+      // Here we check the current self node and *all* of its zero-width token siblings that follow.
+      // If any of these nodes contain the target subnode, we return that node. Otherwise, we restore the node we started at
+      // for the loop condition, and that will continue with the next *non-zero-width* sibling.
+      TSNode old = self;
+      // While the next sibling is a zero-width token
+      while (ts_node_child_iterator_next_sibling_is_empty_adjacent(&iter, self)) {
+        TSNode current_node = ts_node_child_containing_descendant(self, descendant);
+        // If the target child is in self, return it
+        if (!ts_node_is_null(current_node)) {
+          return current_node;
+        }
+        ts_node_child_iterator_next(&iter, &self);
+        if (self.id == descendant.id) {
+          return ts_node__null();
+        }
+      }
+      self = old;
+    } while (iter.position.bytes < end_byte || ts_node_child_count(self) == 0);
+  } while (!ts_node__is_relevant(self, true));
+
+  return self;
+}
+
+TSNode ts_node_child_with_descendant(TSNode self, TSNode descendant) {
+  uint32_t start_byte = ts_node_start_byte(descendant);
+  uint32_t end_byte = ts_node_end_byte(descendant);
+
+  do {
+    NodeChildIterator iter = ts_node_iterate_children(&self);
+    do {
+      if (
+        !ts_node_child_iterator_next(&iter, &self)
+        || ts_node_start_byte(self) > start_byte
+      ) {
+        return ts_node__null();
+      }
+      if (self.id == descendant.id) {
+        return self;
+      }
+
+      // Here we check the current self node and *all* of its zero-width token siblings that follow.
+      // If any of these nodes contain the target subnode, we return that node. Otherwise, we restore the node we started at
+      // for the loop condition, and that will continue with the next *non-zero-width* sibling.
+      TSNode old = self;
+      // While the next sibling is a zero-width token
+      while (ts_node_child_iterator_next_sibling_is_empty_adjacent(&iter, self)) {
+        TSNode current_node = ts_node_child_with_descendant(self, descendant);
+        // If the target child is in self, return it
+        if (!ts_node_is_null(current_node)) {
+          return current_node;
+        }
+        ts_node_child_iterator_next(&iter, &self);
+        if (self.id == descendant.id) {
+          return self;
+        }
+      }
+      self = old;
+    } while (iter.position.bytes < end_byte || ts_node_child_count(self) == 0);
+  } while (!ts_node__is_relevant(self, true));
+
+  return self;
+}
+
+TSNode ts_node_child(TSNode self, uint32_t child_index) {
+  return ts_node__child(self, child_index, true);
+}
+
+TSNode ts_node_named_child(TSNode self, uint32_t child_index) {
+  return ts_node__child(self, child_index, false);
+}
+
+TSNode ts_node_child_by_field_id(TSNode self, TSFieldId field_id) {
+recur:
+  if (!field_id || ts_node_child_count(self) == 0) return ts_node__null();
+
+  const TSFieldMapEntry *field_map, *field_map_end;
+  ts_language_field_map(
+    self.tree->language,
+    ts_node__subtree(self).ptr->production_id,
+    &field_map,
+    &field_map_end
+  );
+  if (field_map == field_map_end) return ts_node__null();
+
+  // The field mappings are sorted by their field id. Scan all
+  // the mappings to find the ones for the given field id.
+  while (field_map->field_id < field_id) {
+    field_map++;
+    if (field_map == field_map_end) return ts_node__null();
+  }
+  while (field_map_end[-1].field_id > field_id) {
+    field_map_end--;
+    if (field_map == field_map_end) return ts_node__null();
+  }
+
+  TSNode child;
+  NodeChildIterator iterator = ts_node_iterate_children(&self);
+  while (ts_node_child_iterator_next(&iterator, &child)) {
+    if (!ts_subtree_extra(ts_node__subtree(child))) {
+      uint32_t index = iterator.structural_child_index - 1;
+      if (index < field_map->child_index) continue;
+
+      // Hidden nodes' fields are "inherited" by their visible parent.
+      if (field_map->inherited) {
+
+        // If this is the *last* possible child node for this field,
+        // then perform a tail call to avoid recursion.
+        if (field_map + 1 == field_map_end) {
+          self = child;
+          goto recur;
+        }
+
+        // Otherwise, descend into this child, but if it doesn't contain
+        // the field, continue searching subsequent children.
+        else {
+          TSNode result = ts_node_child_by_field_id(child, field_id);
+          if (result.id) return result;
+          field_map++;
+          if (field_map == field_map_end) return ts_node__null();
+        }
+      }
+
+      else if (ts_node__is_relevant(child, true)) {
+        return child;
+      }
+
+      // If the field refers to a hidden node with visible children,
+      // return the first visible child.
+      else if (ts_node_child_count(child) > 0 ) {
+        return ts_node_child(child, 0);
+      }
+
+      // Otherwise, continue searching subsequent children.
+      else {
+        field_map++;
+        if (field_map == field_map_end) return ts_node__null();
+      }
+    }
+  }
+
+  return ts_node__null();
+}
+
+static inline const char *ts_node__field_name_from_language(TSNode self, uint32_t structural_child_index) {
+    const TSFieldMapEntry *field_map, *field_map_end;
+    ts_language_field_map(
+      self.tree->language,
+      ts_node__subtree(self).ptr->production_id,
+      &field_map,
+      &field_map_end
+    );
+    for (; field_map != field_map_end; field_map++) {
+      if (!field_map->inherited && field_map->child_index == structural_child_index) {
+        return self.tree->language->field_names[field_map->field_id];
+      }
+    }
+    return NULL;
+}
+
+const char *ts_node_field_name_for_child(TSNode self, uint32_t child_index) {
+  TSNode result = self;
+  bool did_descend = true;
+  const char *inherited_field_name = NULL;
+
+  while (did_descend) {
+    did_descend = false;
+
+    TSNode child;
+    uint32_t index = 0;
+    NodeChildIterator iterator = ts_node_iterate_children(&result);
+    while (ts_node_child_iterator_next(&iterator, &child)) {
+      if (ts_node__is_relevant(child, true)) {
+        if (index == child_index) {
+          if (ts_node_is_extra(child)) {
+            return NULL;
+          }
+          const char *field_name = ts_node__field_name_from_language(result, iterator.structural_child_index - 1);
+          if (field_name) return field_name;
+          return inherited_field_name;
+        }
+        index++;
+      } else {
+        uint32_t grandchild_index = child_index - index;
+        uint32_t grandchild_count = ts_node__relevant_child_count(child, true);
+        if (grandchild_index < grandchild_count) {
+          const char *field_name = ts_node__field_name_from_language(result, iterator.structural_child_index - 1);
+          if (field_name) inherited_field_name = field_name;
+
+          did_descend = true;
+          result = child;
+          child_index = grandchild_index;
+          break;
+        }
+        index += grandchild_count;
+      }
+    }
+  }
+
+  return NULL;
+}
+
+const char *ts_node_field_name_for_named_child(TSNode self, uint32_t named_child_index) {
+  TSNode result = self;
+  bool did_descend = true;
+  const char *inherited_field_name = NULL;
+
+  while (did_descend) {
+    did_descend = false;
+
+    TSNode child;
+    uint32_t index = 0;
+    NodeChildIterator iterator = ts_node_iterate_children(&result);
+    while (ts_node_child_iterator_next(&iterator, &child)) {
+      if (ts_node__is_relevant(child, false)) {
+        if (index == named_child_index) {
+          if (ts_node_is_extra(child)) {
+            return NULL;
+          }
+          const char *field_name = ts_node__field_name_from_language(result, iterator.structural_child_index - 1);
+          if (field_name) return field_name;
+          return inherited_field_name;
+        }
+        index++;
+      } else {
+        uint32_t named_grandchild_index = named_child_index - index;
+        uint32_t grandchild_count = ts_node__relevant_child_count(child, false);
+        if (named_grandchild_index < grandchild_count) {
+          const char *field_name = ts_node__field_name_from_language(result, iterator.structural_child_index - 1);
+          if (field_name) inherited_field_name = field_name;
+
+          did_descend = true;
+          result = child;
+          named_child_index = named_grandchild_index;
+          break;
+        }
+        index += grandchild_count;
+      }
+    }
+  }
+
+  return NULL;
+}
+
+TSNode ts_node_child_by_field_name(
+  TSNode self,
+  const char *name,
+  uint32_t name_length
+) {
+  TSFieldId field_id = ts_language_field_id_for_name(
+    self.tree->language,
+    name,
+    name_length
+  );
+  return ts_node_child_by_field_id(self, field_id);
+}
+
+uint32_t ts_node_child_count(TSNode self) {
+  Subtree tree = ts_node__subtree(self);
+  if (ts_subtree_child_count(tree) > 0) {
+    return tree.ptr->visible_child_count;
+  } else {
+    return 0;
+  }
+}
+
+uint32_t ts_node_named_child_count(TSNode self) {
+  Subtree tree = ts_node__subtree(self);
+  if (ts_subtree_child_count(tree) > 0) {
+    return tree.ptr->named_child_count;
+  } else {
+    return 0;
+  }
+}
+
+TSNode ts_node_next_sibling(TSNode self) {
+  return ts_node__next_sibling(self, true);
+}
+
+TSNode ts_node_next_named_sibling(TSNode self) {
+  return ts_node__next_sibling(self, false);
+}
+
+TSNode ts_node_prev_sibling(TSNode self) {
+  return ts_node__prev_sibling(self, true);
+}
+
+TSNode ts_node_prev_named_sibling(TSNode self) {
+  return ts_node__prev_sibling(self, false);
+}
+
+TSNode ts_node_first_child_for_byte(TSNode self, uint32_t byte) {
+  return ts_node__first_child_for_byte(self, byte, true);
+}
+
+TSNode ts_node_first_named_child_for_byte(TSNode self, uint32_t byte) {
+  return ts_node__first_child_for_byte(self, byte, false);
+}
+
+TSNode ts_node_descendant_for_byte_range(
+  TSNode self,
+  uint32_t start,
+  uint32_t end
+) {
+  return ts_node__descendant_for_byte_range(self, start, end, true);
+}
+
+TSNode ts_node_named_descendant_for_byte_range(
+  TSNode self,
+  uint32_t start,
+  uint32_t end
+) {
+  return ts_node__descendant_for_byte_range(self, start, end, false);
+}
+
+TSNode ts_node_descendant_for_point_range(
+  TSNode self,
+  TSPoint start,
+  TSPoint end
+) {
+  return ts_node__descendant_for_point_range(self, start, end, true);
+}
+
+TSNode ts_node_named_descendant_for_point_range(
+  TSNode self,
+  TSPoint start,
+  TSPoint end
+) {
+  return ts_node__descendant_for_point_range(self, start, end, false);
+}
+
+void ts_node_edit(TSNode *self, const TSInputEdit *edit) {
+  uint32_t start_byte = ts_node_start_byte(*self);
+  TSPoint start_point = ts_node_start_point(*self);
+
+  if (start_byte >= edit->old_end_byte) {
+    start_byte = edit->new_end_byte + (start_byte - edit->old_end_byte);
+    start_point = point_add(edit->new_end_point, point_sub(start_point, edit->old_end_point));
+  } else if (start_byte > edit->start_byte) {
+    start_byte = edit->new_end_byte;
+    start_point = edit->new_end_point;
+  }
+
+  self->context[0] = start_byte;
+  self->context[1] = start_point.row;
+  self->context[2] = start_point.column;
+}
diff --git a/vendor/tree-sitter/lib/src/parser.c b/vendor/tree-sitter/lib/src/parser.c
new file mode 100644
--- /dev/null
+++ b/vendor/tree-sitter/lib/src/parser.c
@@ -0,0 +1,2167 @@
+#define _POSIX_C_SOURCE 200112L
+
+#include <time.h>
+#include <stdio.h>
+#include <limits.h>
+#include <stdbool.h>
+#include <inttypes.h>
+#include "tree_sitter/api.h"
+#include "./alloc.h"
+#include "./array.h"
+#include "./atomic.h"
+#include "./clock.h"
+#include "./error_costs.h"
+#include "./get_changed_ranges.h"
+#include "./language.h"
+#include "./length.h"
+#include "./lexer.h"
+#include "./reduce_action.h"
+#include "./reusable_node.h"
+#include "./stack.h"
+#include "./subtree.h"
+#include "./tree.h"
+#include "./ts_assert.h"
+#include "./wasm_store.h"
+
+#define LOG(...)                                                                            \
+  if (self->lexer.logger.log || self->dot_graph_file) {                                     \
+    snprintf(self->lexer.debug_buffer, TREE_SITTER_SERIALIZATION_BUFFER_SIZE, __VA_ARGS__); \
+    ts_parser__log(self);                                                                   \
+  }
+
+#define LOG_LOOKAHEAD(symbol_name, size)                      \
+  if (self->lexer.logger.log || self->dot_graph_file) {       \
+    char *buf = self->lexer.debug_buffer;                     \
+    const char *symbol = symbol_name;                         \
+    int off = snprintf(                                       \
+      buf,                                                    \
+      TREE_SITTER_SERIALIZATION_BUFFER_SIZE,                  \
+      "lexed_lookahead sym:"                                  \
+    );                                                        \
+    for (                                                     \
+      int i = 0;                                              \
+      symbol[i] != '\0'                                       \
+      && off < TREE_SITTER_SERIALIZATION_BUFFER_SIZE;         \
+      i++                                                     \
+    ) {                                                       \
+      switch (symbol[i]) {                                    \
+      case '\t': buf[off++] = '\\'; buf[off++] = 't'; break;  \
+      case '\n': buf[off++] = '\\'; buf[off++] = 'n'; break;  \
+      case '\v': buf[off++] = '\\'; buf[off++] = 'v'; break;  \
+      case '\f': buf[off++] = '\\'; buf[off++] = 'f'; break;  \
+      case '\r': buf[off++] = '\\'; buf[off++] = 'r'; break;  \
+      case '\\': buf[off++] = '\\'; buf[off++] = '\\'; break; \
+      default:   buf[off++] = symbol[i]; break;               \
+      }                                                       \
+    }                                                         \
+    snprintf(                                                 \
+      buf + off,                                              \
+      TREE_SITTER_SERIALIZATION_BUFFER_SIZE - off,            \
+      ", size:%u",                                            \
+      size                                                    \
+    );                                                        \
+    ts_parser__log(self);                                     \
+  }
+
+#define LOG_STACK()                                                              \
+  if (self->dot_graph_file) {                                                    \
+    ts_stack_print_dot_graph(self->stack, self->language, self->dot_graph_file); \
+    fputs("\n\n", self->dot_graph_file);                                         \
+  }
+
+#define LOG_TREE(tree)                                                      \
+  if (self->dot_graph_file) {                                               \
+    ts_subtree_print_dot_graph(tree, self->language, self->dot_graph_file); \
+    fputs("\n", self->dot_graph_file);                                      \
+  }
+
+#define SYM_NAME(symbol) ts_language_symbol_name(self->language, symbol)
+
+#define TREE_NAME(tree) SYM_NAME(ts_subtree_symbol(tree))
+
+static const unsigned MAX_VERSION_COUNT = 6;
+static const unsigned MAX_VERSION_COUNT_OVERFLOW = 4;
+static const unsigned MAX_SUMMARY_DEPTH = 16;
+static const unsigned MAX_COST_DIFFERENCE = 16 * ERROR_COST_PER_SKIPPED_TREE;
+static const unsigned OP_COUNT_PER_PARSER_TIMEOUT_CHECK = 100;
+
+typedef struct {
+  Subtree token;
+  Subtree last_external_token;
+  uint32_t byte_index;
+} TokenCache;
+
+struct TSParser {
+  Lexer lexer;
+  Stack *stack;
+  SubtreePool tree_pool;
+  const TSLanguage *language;
+  TSWasmStore *wasm_store;
+  ReduceActionSet reduce_actions;
+  Subtree finished_tree;
+  SubtreeArray trailing_extras;
+  SubtreeArray trailing_extras2;
+  SubtreeArray scratch_trees;
+  TokenCache token_cache;
+  ReusableNode reusable_node;
+  void *external_scanner_payload;
+  FILE *dot_graph_file;
+  TSClock end_clock;
+  TSDuration timeout_duration;
+  unsigned accept_count;
+  unsigned operation_count;
+  const volatile size_t *cancellation_flag;
+  Subtree old_tree;
+  TSRangeArray included_range_differences;
+  unsigned included_range_difference_index;
+  bool has_scanner_error;
+};
+
+typedef struct {
+  unsigned cost;
+  unsigned node_count;
+  int dynamic_precedence;
+  bool is_in_error;
+} ErrorStatus;
+
+typedef enum {
+  ErrorComparisonTakeLeft,
+  ErrorComparisonPreferLeft,
+  ErrorComparisonNone,
+  ErrorComparisonPreferRight,
+  ErrorComparisonTakeRight,
+} ErrorComparison;
+
+typedef struct {
+  const char *string;
+  uint32_t length;
+} TSStringInput;
+
+// StringInput
+
+static const char *ts_string_input_read(
+  void *_self,
+  uint32_t byte,
+  TSPoint point,
+  uint32_t *length
+) {
+  (void)point;
+  TSStringInput *self = (TSStringInput *)_self;
+  if (byte >= self->length) {
+    *length = 0;
+    return "";
+  } else {
+    *length = self->length - byte;
+    return self->string + byte;
+  }
+}
+
+// Parser - Private
+
+static void ts_parser__log(TSParser *self) {
+  if (self->lexer.logger.log) {
+    self->lexer.logger.log(
+      self->lexer.logger.payload,
+      TSLogTypeParse,
+      self->lexer.debug_buffer
+    );
+  }
+
+  if (self->dot_graph_file) {
+    fprintf(self->dot_graph_file, "graph {\nlabel=\"");
+    for (char *chr = &self->lexer.debug_buffer[0]; *chr != 0; chr++) {
+      if (*chr == '"' || *chr == '\\') fputc('\\', self->dot_graph_file);
+      fputc(*chr, self->dot_graph_file);
+    }
+    fprintf(self->dot_graph_file, "\"\n}\n\n");
+  }
+}
+
+static bool ts_parser__breakdown_top_of_stack(
+  TSParser *self,
+  StackVersion version
+) {
+  bool did_break_down = false;
+  bool pending = false;
+
+  do {
+    StackSliceArray pop = ts_stack_pop_pending(self->stack, version);
+    if (!pop.size) break;
+
+    did_break_down = true;
+    pending = false;
+    for (uint32_t i = 0; i < pop.size; i++) {
+      StackSlice slice = pop.contents[i];
+      TSStateId state = ts_stack_state(self->stack, slice.version);
+      Subtree parent = *array_front(&slice.subtrees);
+
+      for (uint32_t j = 0, n = ts_subtree_child_count(parent); j < n; j++) {
+        Subtree child = ts_subtree_children(parent)[j];
+        pending = ts_subtree_child_count(child) > 0;
+
+        if (ts_subtree_is_error(child)) {
+          state = ERROR_STATE;
+        } else if (!ts_subtree_extra(child)) {
+          state = ts_language_next_state(self->language, state, ts_subtree_symbol(child));
+        }
+
+        ts_subtree_retain(child);
+        ts_stack_push(self->stack, slice.version, child, pending, state);
+      }
+
+      for (uint32_t j = 1; j < slice.subtrees.size; j++) {
+        Subtree tree = slice.subtrees.contents[j];
+        ts_stack_push(self->stack, slice.version, tree, false, state);
+      }
+
+      ts_subtree_release(&self->tree_pool, parent);
+      array_delete(&slice.subtrees);
+
+      LOG("breakdown_top_of_stack tree:%s", TREE_NAME(parent));
+      LOG_STACK();
+    }
+  } while (pending);
+
+  return did_break_down;
+}
+
+static void ts_parser__breakdown_lookahead(
+  TSParser *self,
+  Subtree *lookahead,
+  TSStateId state,
+  ReusableNode *reusable_node
+) {
+  bool did_descend = false;
+  Subtree tree = reusable_node_tree(reusable_node);
+  while (ts_subtree_child_count(tree) > 0 && ts_subtree_parse_state(tree) != state) {
+    LOG("state_mismatch sym:%s", TREE_NAME(tree));
+    reusable_node_descend(reusable_node);
+    tree = reusable_node_tree(reusable_node);
+    did_descend = true;
+  }
+
+  if (did_descend) {
+    ts_subtree_release(&self->tree_pool, *lookahead);
+    *lookahead = tree;
+    ts_subtree_retain(*lookahead);
+  }
+}
+
+static ErrorComparison ts_parser__compare_versions(
+  TSParser *self,
+  ErrorStatus a,
+  ErrorStatus b
+) {
+  (void)self;
+  if (!a.is_in_error && b.is_in_error) {
+    if (a.cost < b.cost) {
+      return ErrorComparisonTakeLeft;
+    } else {
+      return ErrorComparisonPreferLeft;
+    }
+  }
+
+  if (a.is_in_error && !b.is_in_error) {
+    if (b.cost < a.cost) {
+      return ErrorComparisonTakeRight;
+    } else {
+      return ErrorComparisonPreferRight;
+    }
+  }
+
+  if (a.cost < b.cost) {
+    if ((b.cost - a.cost) * (1 + a.node_count) > MAX_COST_DIFFERENCE) {
+      return ErrorComparisonTakeLeft;
+    } else {
+      return ErrorComparisonPreferLeft;
+    }
+  }
+
+  if (b.cost < a.cost) {
+    if ((a.cost - b.cost) * (1 + b.node_count) > MAX_COST_DIFFERENCE) {
+      return ErrorComparisonTakeRight;
+    } else {
+      return ErrorComparisonPreferRight;
+    }
+  }
+
+  if (a.dynamic_precedence > b.dynamic_precedence) return ErrorComparisonPreferLeft;
+  if (b.dynamic_precedence > a.dynamic_precedence) return ErrorComparisonPreferRight;
+  return ErrorComparisonNone;
+}
+
+static ErrorStatus ts_parser__version_status(
+  TSParser *self,
+  StackVersion version
+) {
+  unsigned cost = ts_stack_error_cost(self->stack, version);
+  bool is_paused = ts_stack_is_paused(self->stack, version);
+  if (is_paused) cost += ERROR_COST_PER_SKIPPED_TREE;
+  return (ErrorStatus) {
+    .cost = cost,
+    .node_count = ts_stack_node_count_since_error(self->stack, version),
+    .dynamic_precedence = ts_stack_dynamic_precedence(self->stack, version),
+    .is_in_error = is_paused || ts_stack_state(self->stack, version) == ERROR_STATE
+  };
+}
+
+static bool ts_parser__better_version_exists(
+  TSParser *self,
+  StackVersion version,
+  bool is_in_error,
+  unsigned cost
+) {
+  if (self->finished_tree.ptr && ts_subtree_error_cost(self->finished_tree) <= cost) {
+    return true;
+  }
+
+  Length position = ts_stack_position(self->stack, version);
+  ErrorStatus status = {
+    .cost = cost,
+    .is_in_error = is_in_error,
+    .dynamic_precedence = ts_stack_dynamic_precedence(self->stack, version),
+    .node_count = ts_stack_node_count_since_error(self->stack, version),
+  };
+
+  for (StackVersion i = 0, n = ts_stack_version_count(self->stack); i < n; i++) {
+    if (i == version ||
+        !ts_stack_is_active(self->stack, i) ||
+        ts_stack_position(self->stack, i).bytes < position.bytes) continue;
+    ErrorStatus status_i = ts_parser__version_status(self, i);
+    switch (ts_parser__compare_versions(self, status, status_i)) {
+      case ErrorComparisonTakeRight:
+        return true;
+      case ErrorComparisonPreferRight:
+        if (ts_stack_can_merge(self->stack, i, version)) return true;
+        break;
+      default:
+        break;
+    }
+  }
+
+  return false;
+}
+
+static bool ts_parser__call_main_lex_fn(TSParser *self, TSLexMode lex_mode) {
+  if (ts_language_is_wasm(self->language)) {
+    return ts_wasm_store_call_lex_main(self->wasm_store, lex_mode.lex_state);
+  } else {
+    return self->language->lex_fn(&self->lexer.data, lex_mode.lex_state);
+  }
+}
+
+static bool ts_parser__call_keyword_lex_fn(TSParser *self, TSLexMode lex_mode) {
+  if (ts_language_is_wasm(self->language)) {
+    return ts_wasm_store_call_lex_keyword(self->wasm_store, 0);
+  } else {
+    return self->language->keyword_lex_fn(&self->lexer.data, 0);
+  }
+}
+
+static void ts_parser__external_scanner_create(
+  TSParser *self
+) {
+  if (self->language && self->language->external_scanner.states) {
+    if (ts_language_is_wasm(self->language)) {
+      self->external_scanner_payload = (void *)(uintptr_t)ts_wasm_store_call_scanner_create(
+        self->wasm_store
+      );
+      if (ts_wasm_store_has_error(self->wasm_store)) {
+        self->has_scanner_error = true;
+      }
+    } else if (self->language->external_scanner.create) {
+      self->external_scanner_payload = self->language->external_scanner.create();
+    }
+  }
+}
+
+static void ts_parser__external_scanner_destroy(
+  TSParser *self
+) {
+  if (
+    self->language &&
+    self->external_scanner_payload &&
+    self->language->external_scanner.destroy &&
+    !ts_language_is_wasm(self->language)
+  ) {
+    self->language->external_scanner.destroy(
+      self->external_scanner_payload
+    );
+  }
+  self->external_scanner_payload = NULL;
+}
+
+static unsigned ts_parser__external_scanner_serialize(
+  TSParser *self
+) {
+  if (ts_language_is_wasm(self->language)) {
+    return ts_wasm_store_call_scanner_serialize(
+      self->wasm_store,
+      (uintptr_t)self->external_scanner_payload,
+      self->lexer.debug_buffer
+    );
+  } else {
+    uint32_t length = self->language->external_scanner.serialize(
+      self->external_scanner_payload,
+      self->lexer.debug_buffer
+    );
+    ts_assert(length <= TREE_SITTER_SERIALIZATION_BUFFER_SIZE);
+    return length;
+  }
+}
+
+static void ts_parser__external_scanner_deserialize(
+  TSParser *self,
+  Subtree external_token
+) {
+  const char *data = NULL;
+  uint32_t length = 0;
+  if (external_token.ptr) {
+    data = ts_external_scanner_state_data(&external_token.ptr->external_scanner_state);
+    length = external_token.ptr->external_scanner_state.length;
+  }
+
+  if (ts_language_is_wasm(self->language)) {
+    ts_wasm_store_call_scanner_deserialize(
+      self->wasm_store,
+      (uintptr_t)self->external_scanner_payload,
+      data,
+      length
+    );
+    if (ts_wasm_store_has_error(self->wasm_store)) {
+      self->has_scanner_error = true;
+    }
+  } else {
+    self->language->external_scanner.deserialize(
+      self->external_scanner_payload,
+      data,
+      length
+    );
+  }
+}
+
+static bool ts_parser__external_scanner_scan(
+  TSParser *self,
+  TSStateId external_lex_state
+) {
+  if (ts_language_is_wasm(self->language)) {
+    bool result = ts_wasm_store_call_scanner_scan(
+      self->wasm_store,
+      (uintptr_t)self->external_scanner_payload,
+      external_lex_state * self->language->external_token_count
+    );
+    if (ts_wasm_store_has_error(self->wasm_store)) {
+      self->has_scanner_error = true;
+    }
+    return result;
+  } else {
+    const bool *valid_external_tokens = ts_language_enabled_external_tokens(
+      self->language,
+      external_lex_state
+    );
+    return self->language->external_scanner.scan(
+      self->external_scanner_payload,
+      &self->lexer.data,
+      valid_external_tokens
+    );
+  }
+}
+
+static bool ts_parser__can_reuse_first_leaf(
+  TSParser *self,
+  TSStateId state,
+  Subtree tree,
+  TableEntry *table_entry
+) {
+  TSLexMode current_lex_mode = self->language->lex_modes[state];
+  TSSymbol leaf_symbol = ts_subtree_leaf_symbol(tree);
+  TSStateId leaf_state = ts_subtree_leaf_parse_state(tree);
+  TSLexMode leaf_lex_mode = self->language->lex_modes[leaf_state];
+
+  // At the end of a non-terminal extra node, the lexer normally returns
+  // NULL, which indicates that the parser should look for a reduce action
+  // at symbol `0`. Avoid reusing tokens in this situation to ensure that
+  // the same thing happens when incrementally reparsing.
+  if (current_lex_mode.lex_state == (uint16_t)(-1)) return false;
+
+  // If the token was created in a state with the same set of lookaheads, it is reusable.
+  if (
+    table_entry->action_count > 0 &&
+    memcmp(&leaf_lex_mode, &current_lex_mode, sizeof(TSLexMode)) == 0 &&
+    (
+      leaf_symbol != self->language->keyword_capture_token ||
+      (!ts_subtree_is_keyword(tree) && ts_subtree_parse_state(tree) == state)
+    )
+  ) return true;
+
+  // Empty tokens are not reusable in states with different lookaheads.
+  if (ts_subtree_size(tree).bytes == 0 && leaf_symbol != ts_builtin_sym_end) return false;
+
+  // If the current state allows external tokens or other tokens that conflict with this
+  // token, this token is not reusable.
+  return current_lex_mode.external_lex_state == 0 && table_entry->is_reusable;
+}
+
+static Subtree ts_parser__lex(
+  TSParser *self,
+  StackVersion version,
+  TSStateId parse_state
+) {
+  TSLexMode lex_mode = self->language->lex_modes[parse_state];
+  if (lex_mode.lex_state == (uint16_t)-1) {
+    LOG("no_lookahead_after_non_terminal_extra");
+    return NULL_SUBTREE;
+  }
+
+  const Length start_position = ts_stack_position(self->stack, version);
+  const Subtree external_token = ts_stack_last_external_token(self->stack, version);
+
+  bool found_external_token = false;
+  bool error_mode = parse_state == ERROR_STATE;
+  bool skipped_error = false;
+  bool called_get_column = false;
+  int32_t first_error_character = 0;
+  Length error_start_position = length_zero();
+  Length error_end_position = length_zero();
+  uint32_t lookahead_end_byte = 0;
+  uint32_t external_scanner_state_len = 0;
+  bool external_scanner_state_changed = false;
+  ts_lexer_reset(&self->lexer, start_position);
+
+  for (;;) {
+    bool found_token = false;
+    Length current_position = self->lexer.current_position;
+
+    if (lex_mode.external_lex_state != 0) {
+      LOG(
+        "lex_external state:%d, row:%u, column:%u",
+        lex_mode.external_lex_state,
+        current_position.extent.row,
+        current_position.extent.column
+      );
+      ts_lexer_start(&self->lexer);
+      ts_parser__external_scanner_deserialize(self, external_token);
+      found_token = ts_parser__external_scanner_scan(self, lex_mode.external_lex_state);
+      if (self->has_scanner_error) return NULL_SUBTREE;
+      ts_lexer_finish(&self->lexer, &lookahead_end_byte);
+
+      if (found_token) {
+        external_scanner_state_len = ts_parser__external_scanner_serialize(self);
+        external_scanner_state_changed = !ts_external_scanner_state_eq(
+          ts_subtree_external_scanner_state(external_token),
+          self->lexer.debug_buffer,
+          external_scanner_state_len
+        );
+
+        // When recovering from an error, ignore any zero-length external tokens
+        // unless they have changed the external scanner's state. This helps to
+        // avoid infinite loops which could otherwise occur, because the lexer is
+        // looking for any possible token, instead of looking for the specific set of
+        // tokens that are valid in some parse state.
+        //
+        // Note that it's possible that the token end position may be *before* the
+        // original position of the lexer because of the way that tokens are positioned
+        // at included range boundaries: when a token is terminated at the start of
+        // an included range, it is marked as ending at the *end* of the preceding
+        // included range.
+        if (
+          self->lexer.token_end_position.bytes <= current_position.bytes &&
+          (error_mode || !ts_stack_has_advanced_since_error(self->stack, version)) &&
+          !external_scanner_state_changed
+        ) {
+          LOG(
+            "ignore_empty_external_token symbol:%s",
+            SYM_NAME(self->language->external_scanner.symbol_map[self->lexer.data.result_symbol])
+          )
+          found_token = false;
+        }
+      }
+
+      if (found_token) {
+        found_external_token = true;
+        called_get_column = self->lexer.did_get_column;
+        break;
+      }
+
+      ts_lexer_reset(&self->lexer, current_position);
+    }
+
+    LOG(
+      "lex_internal state:%d, row:%u, column:%u",
+      lex_mode.lex_state,
+      current_position.extent.row,
+      current_position.extent.column
+    );
+    ts_lexer_start(&self->lexer);
+    found_token = ts_parser__call_main_lex_fn(self, lex_mode);
+    ts_lexer_finish(&self->lexer, &lookahead_end_byte);
+    if (found_token) break;
+
+    if (!error_mode) {
+      error_mode = true;
+      lex_mode = self->language->lex_modes[ERROR_STATE];
+      ts_lexer_reset(&self->lexer, start_position);
+      continue;
+    }
+
+    if (!skipped_error) {
+      LOG("skip_unrecognized_character");
+      skipped_error = true;
+      error_start_position = self->lexer.token_start_position;
+      error_end_position = self->lexer.token_start_position;
+      first_error_character = self->lexer.data.lookahead;
+    }
+
+    if (self->lexer.current_position.bytes == error_end_position.bytes) {
+      if (self->lexer.data.eof(&self->lexer.data)) {
+        self->lexer.data.result_symbol = ts_builtin_sym_error;
+        break;
+      }
+      self->lexer.data.advance(&self->lexer.data, false);
+    }
+
+    error_end_position = self->lexer.current_position;
+  }
+
+  Subtree result;
+  if (skipped_error) {
+    Length padding = length_sub(error_start_position, start_position);
+    Length size = length_sub(error_end_position, error_start_position);
+    uint32_t lookahead_bytes = lookahead_end_byte - error_end_position.bytes;
+    result = ts_subtree_new_error(
+      &self->tree_pool,
+      first_error_character,
+      padding,
+      size,
+      lookahead_bytes,
+      parse_state,
+      self->language
+    );
+  } else {
+    bool is_keyword = false;
+    TSSymbol symbol = self->lexer.data.result_symbol;
+    Length padding = length_sub(self->lexer.token_start_position, start_position);
+    Length size = length_sub(self->lexer.token_end_position, self->lexer.token_start_position);
+    uint32_t lookahead_bytes = lookahead_end_byte - self->lexer.token_end_position.bytes;
+
+    if (found_external_token) {
+      symbol = self->language->external_scanner.symbol_map[symbol];
+    } else if (symbol == self->language->keyword_capture_token && symbol != 0) {
+      uint32_t end_byte = self->lexer.token_end_position.bytes;
+      ts_lexer_reset(&self->lexer, self->lexer.token_start_position);
+      ts_lexer_start(&self->lexer);
+
+      is_keyword = ts_parser__call_keyword_lex_fn(self, lex_mode);
+
+      if (
+        is_keyword &&
+        self->lexer.token_end_position.bytes == end_byte &&
+        ts_language_has_actions(self->language, parse_state, self->lexer.data.result_symbol)
+      ) {
+        symbol = self->lexer.data.result_symbol;
+      }
+    }
+
+    result = ts_subtree_new_leaf(
+      &self->tree_pool,
+      symbol,
+      padding,
+      size,
+      lookahead_bytes,
+      parse_state,
+      found_external_token,
+      called_get_column,
+      is_keyword,
+      self->language
+    );
+
+    if (found_external_token) {
+      MutableSubtree mut_result = ts_subtree_to_mut_unsafe(result);
+      ts_external_scanner_state_init(
+        &mut_result.ptr->external_scanner_state,
+        self->lexer.debug_buffer,
+        external_scanner_state_len
+      );
+      mut_result.ptr->has_external_scanner_state_change = external_scanner_state_changed;
+    }
+  }
+
+  LOG_LOOKAHEAD(
+    SYM_NAME(ts_subtree_symbol(result)),
+    ts_subtree_total_size(result).bytes
+  );
+  return result;
+}
+
+static Subtree ts_parser__get_cached_token(
+  TSParser *self,
+  TSStateId state,
+  size_t position,
+  Subtree last_external_token,
+  TableEntry *table_entry
+) {
+  TokenCache *cache = &self->token_cache;
+  if (
+    cache->token.ptr && cache->byte_index == position &&
+    ts_subtree_external_scanner_state_eq(cache->last_external_token, last_external_token)
+  ) {
+    ts_language_table_entry(self->language, state, ts_subtree_symbol(cache->token), table_entry);
+    if (ts_parser__can_reuse_first_leaf(self, state, cache->token, table_entry)) {
+      ts_subtree_retain(cache->token);
+      return cache->token;
+    }
+  }
+  return NULL_SUBTREE;
+}
+
+static void ts_parser__set_cached_token(
+  TSParser *self,
+  uint32_t byte_index,
+  Subtree last_external_token,
+  Subtree token
+) {
+  TokenCache *cache = &self->token_cache;
+  if (token.ptr) ts_subtree_retain(token);
+  if (last_external_token.ptr) ts_subtree_retain(last_external_token);
+  if (cache->token.ptr) ts_subtree_release(&self->tree_pool, cache->token);
+  if (cache->last_external_token.ptr) ts_subtree_release(&self->tree_pool, cache->last_external_token);
+  cache->token = token;
+  cache->byte_index = byte_index;
+  cache->last_external_token = last_external_token;
+}
+
+static bool ts_parser__has_included_range_difference(
+  const TSParser *self,
+  uint32_t start_position,
+  uint32_t end_position
+) {
+  return ts_range_array_intersects(
+    &self->included_range_differences,
+    self->included_range_difference_index,
+    start_position,
+    end_position
+  );
+}
+
+static Subtree ts_parser__reuse_node(
+  TSParser *self,
+  StackVersion version,
+  TSStateId *state,
+  uint32_t position,
+  Subtree last_external_token,
+  TableEntry *table_entry
+) {
+  Subtree result;
+  while ((result = reusable_node_tree(&self->reusable_node)).ptr) {
+    uint32_t byte_offset = reusable_node_byte_offset(&self->reusable_node);
+    uint32_t end_byte_offset = byte_offset + ts_subtree_total_bytes(result);
+
+    // Do not reuse an EOF node if the included ranges array has changes
+    // later on in the file.
+    if (ts_subtree_is_eof(result)) end_byte_offset = UINT32_MAX;
+
+    if (byte_offset > position) {
+      LOG("before_reusable_node symbol:%s", TREE_NAME(result));
+      break;
+    }
+
+    if (byte_offset < position) {
+      LOG("past_reusable_node symbol:%s", TREE_NAME(result));
+      if (end_byte_offset <= position || !reusable_node_descend(&self->reusable_node)) {
+        reusable_node_advance(&self->reusable_node);
+      }
+      continue;
+    }
+
+    if (!ts_subtree_external_scanner_state_eq(self->reusable_node.last_external_token, last_external_token)) {
+      LOG("reusable_node_has_different_external_scanner_state symbol:%s", TREE_NAME(result));
+      reusable_node_advance(&self->reusable_node);
+      continue;
+    }
+
+    const char *reason = NULL;
+    if (ts_subtree_has_changes(result)) {
+      reason = "has_changes";
+    } else if (ts_subtree_is_error(result)) {
+      reason = "is_error";
+    } else if (ts_subtree_missing(result)) {
+      reason = "is_missing";
+    } else if (ts_subtree_is_fragile(result)) {
+      reason = "is_fragile";
+    } else if (ts_parser__has_included_range_difference(self, byte_offset, end_byte_offset)) {
+      reason = "contains_different_included_range";
+    }
+
+    if (reason) {
+      LOG("cant_reuse_node_%s tree:%s", reason, TREE_NAME(result));
+      if (!reusable_node_descend(&self->reusable_node)) {
+        reusable_node_advance(&self->reusable_node);
+        ts_parser__breakdown_top_of_stack(self, version);
+        *state = ts_stack_state(self->stack, version);
+      }
+      continue;
+    }
+
+    TSSymbol leaf_symbol = ts_subtree_leaf_symbol(result);
+    ts_language_table_entry(self->language, *state, leaf_symbol, table_entry);
+    if (!ts_parser__can_reuse_first_leaf(self, *state, result, table_entry)) {
+      LOG(
+        "cant_reuse_node symbol:%s, first_leaf_symbol:%s",
+        TREE_NAME(result),
+        SYM_NAME(leaf_symbol)
+      );
+      reusable_node_advance_past_leaf(&self->reusable_node);
+      break;
+    }
+
+    LOG("reuse_node symbol:%s", TREE_NAME(result));
+    ts_subtree_retain(result);
+    return result;
+  }
+
+  return NULL_SUBTREE;
+}
+
+// Determine if a given tree should be replaced by an alternative tree.
+//
+// The decision is based on the trees' error costs (if any), their dynamic precedence,
+// and finally, as a default, by a recursive comparison of the trees' symbols.
+static bool ts_parser__select_tree(TSParser *self, Subtree left, Subtree right) {
+  if (!left.ptr) return true;
+  if (!right.ptr) return false;
+
+  if (ts_subtree_error_cost(right) < ts_subtree_error_cost(left)) {
+    LOG("select_smaller_error symbol:%s, over_symbol:%s", TREE_NAME(right), TREE_NAME(left));
+    return true;
+  }
+
+  if (ts_subtree_error_cost(left) < ts_subtree_error_cost(right)) {
+    LOG("select_smaller_error symbol:%s, over_symbol:%s", TREE_NAME(left), TREE_NAME(right));
+    return false;
+  }
+
+  if (ts_subtree_dynamic_precedence(right) > ts_subtree_dynamic_precedence(left)) {
+    LOG("select_higher_precedence symbol:%s, prec:%" PRId32 ", over_symbol:%s, other_prec:%" PRId32,
+        TREE_NAME(right), ts_subtree_dynamic_precedence(right), TREE_NAME(left),
+        ts_subtree_dynamic_precedence(left));
+    return true;
+  }
+
+  if (ts_subtree_dynamic_precedence(left) > ts_subtree_dynamic_precedence(right)) {
+    LOG("select_higher_precedence symbol:%s, prec:%" PRId32 ", over_symbol:%s, other_prec:%" PRId32,
+        TREE_NAME(left), ts_subtree_dynamic_precedence(left), TREE_NAME(right),
+        ts_subtree_dynamic_precedence(right));
+    return false;
+  }
+
+  if (ts_subtree_error_cost(left) > 0) return true;
+
+  int comparison = ts_subtree_compare(left, right, &self->tree_pool);
+  switch (comparison) {
+    case -1:
+      LOG("select_earlier symbol:%s, over_symbol:%s", TREE_NAME(left), TREE_NAME(right));
+      return false;
+      break;
+    case 1:
+      LOG("select_earlier symbol:%s, over_symbol:%s", TREE_NAME(right), TREE_NAME(left));
+      return true;
+    default:
+      LOG("select_existing symbol:%s, over_symbol:%s", TREE_NAME(left), TREE_NAME(right));
+      return false;
+  }
+}
+
+// Determine if a given tree's children should be replaced by an alternative
+// array of children.
+static bool ts_parser__select_children(
+  TSParser *self,
+  Subtree left,
+  const SubtreeArray *children
+) {
+  array_assign(&self->scratch_trees, children);
+
+  // Create a temporary subtree using the scratch trees array. This node does
+  // not perform any allocation except for possibly growing the array to make
+  // room for its own heap data. The scratch tree is never explicitly released,
+  // so the same 'scratch trees' array can be reused again later.
+  MutableSubtree scratch_tree = ts_subtree_new_node(
+    ts_subtree_symbol(left),
+    &self->scratch_trees,
+    0,
+    self->language
+  );
+
+  return ts_parser__select_tree(
+    self,
+    left,
+    ts_subtree_from_mut(scratch_tree)
+  );
+}
+
+static void ts_parser__shift(
+  TSParser *self,
+  StackVersion version,
+  TSStateId state,
+  Subtree lookahead,
+  bool extra
+) {
+  bool is_leaf = ts_subtree_child_count(lookahead) == 0;
+  Subtree subtree_to_push = lookahead;
+  if (extra != ts_subtree_extra(lookahead) && is_leaf) {
+    MutableSubtree result = ts_subtree_make_mut(&self->tree_pool, lookahead);
+    ts_subtree_set_extra(&result, extra);
+    subtree_to_push = ts_subtree_from_mut(result);
+  }
+
+  ts_stack_push(self->stack, version, subtree_to_push, !is_leaf, state);
+  if (ts_subtree_has_external_tokens(subtree_to_push)) {
+    ts_stack_set_last_external_token(
+      self->stack, version, ts_subtree_last_external_token(subtree_to_push)
+    );
+  }
+}
+
+static StackVersion ts_parser__reduce(
+  TSParser *self,
+  StackVersion version,
+  TSSymbol symbol,
+  uint32_t count,
+  int dynamic_precedence,
+  uint16_t production_id,
+  bool is_fragile,
+  bool end_of_non_terminal_extra
+) {
+  uint32_t initial_version_count = ts_stack_version_count(self->stack);
+
+  // Pop the given number of nodes from the given version of the parse stack.
+  // If stack versions have previously merged, then there may be more than one
+  // path back through the stack. For each path, create a new parent node to
+  // contain the popped children, and push it onto the stack in place of the
+  // children.
+  StackSliceArray pop = ts_stack_pop_count(self->stack, version, count);
+  uint32_t removed_version_count = 0;
+  for (uint32_t i = 0; i < pop.size; i++) {
+    StackSlice slice = pop.contents[i];
+    StackVersion slice_version = slice.version - removed_version_count;
+
+    // This is where new versions are added to the parse stack. The versions
+    // will all be sorted and truncated at the end of the outer parsing loop.
+    // Allow the maximum version count to be temporarily exceeded, but only
+    // by a limited threshold.
+    if (slice_version > MAX_VERSION_COUNT + MAX_VERSION_COUNT_OVERFLOW) {
+      ts_stack_remove_version(self->stack, slice_version);
+      ts_subtree_array_delete(&self->tree_pool, &slice.subtrees);
+      removed_version_count++;
+      while (i + 1 < pop.size) {
+        StackSlice next_slice = pop.contents[i + 1];
+        if (next_slice.version != slice.version) break;
+        ts_subtree_array_delete(&self->tree_pool, &next_slice.subtrees);
+        i++;
+      }
+      continue;
+    }
+
+    // Extra tokens on top of the stack should not be included in this new parent
+    // node. They will be re-pushed onto the stack after the parent node is
+    // created and pushed.
+    SubtreeArray children = slice.subtrees;
+    ts_subtree_array_remove_trailing_extras(&children, &self->trailing_extras);
+
+    MutableSubtree parent = ts_subtree_new_node(
+      symbol, &children, production_id, self->language
+    );
+
+    // This pop operation may have caused multiple stack versions to collapse
+    // into one, because they all diverged from a common state. In that case,
+    // choose one of the arrays of trees to be the parent node's children, and
+    // delete the rest of the tree arrays.
+    while (i + 1 < pop.size) {
+      StackSlice next_slice = pop.contents[i + 1];
+      if (next_slice.version != slice.version) break;
+      i++;
+
+      SubtreeArray next_slice_children = next_slice.subtrees;
+      ts_subtree_array_remove_trailing_extras(&next_slice_children, &self->trailing_extras2);
+
+      if (ts_parser__select_children(
+        self,
+        ts_subtree_from_mut(parent),
+        &next_slice_children
+      )) {
+        ts_subtree_array_clear(&self->tree_pool, &self->trailing_extras);
+        ts_subtree_release(&self->tree_pool, ts_subtree_from_mut(parent));
+        array_swap(&self->trailing_extras, &self->trailing_extras2);
+        parent = ts_subtree_new_node(
+          symbol, &next_slice_children, production_id, self->language
+        );
+      } else {
+        array_clear(&self->trailing_extras2);
+        ts_subtree_array_delete(&self->tree_pool, &next_slice.subtrees);
+      }
+    }
+
+    TSStateId state = ts_stack_state(self->stack, slice_version);
+    TSStateId next_state = ts_language_next_state(self->language, state, symbol);
+    if (end_of_non_terminal_extra && next_state == state) {
+      parent.ptr->extra = true;
+    }
+    if (is_fragile || pop.size > 1 || initial_version_count > 1) {
+      parent.ptr->fragile_left = true;
+      parent.ptr->fragile_right = true;
+      parent.ptr->parse_state = TS_TREE_STATE_NONE;
+    } else {
+      parent.ptr->parse_state = state;
+    }
+    parent.ptr->dynamic_precedence += dynamic_precedence;
+
+    // Push the parent node onto the stack, along with any extra tokens that
+    // were previously on top of the stack.
+    ts_stack_push(self->stack, slice_version, ts_subtree_from_mut(parent), false, next_state);
+    for (uint32_t j = 0; j < self->trailing_extras.size; j++) {
+      ts_stack_push(self->stack, slice_version, self->trailing_extras.contents[j], false, next_state);
+    }
+
+    for (StackVersion j = 0; j < slice_version; j++) {
+      if (j == version) continue;
+      if (ts_stack_merge(self->stack, j, slice_version)) {
+        removed_version_count++;
+        break;
+      }
+    }
+  }
+
+  // Return the first new stack version that was created.
+  return ts_stack_version_count(self->stack) > initial_version_count
+    ? initial_version_count
+    : STACK_VERSION_NONE;
+}
+
+static void ts_parser__accept(
+  TSParser *self,
+  StackVersion version,
+  Subtree lookahead
+) {
+  ts_assert(ts_subtree_is_eof(lookahead));
+  ts_stack_push(self->stack, version, lookahead, false, 1);
+
+  StackSliceArray pop = ts_stack_pop_all(self->stack, version);
+  for (uint32_t i = 0; i < pop.size; i++) {
+    SubtreeArray trees = pop.contents[i].subtrees;
+
+    Subtree root = NULL_SUBTREE;
+    for (uint32_t j = trees.size - 1; j + 1 > 0; j--) {
+      Subtree tree = trees.contents[j];
+      if (!ts_subtree_extra(tree)) {
+        ts_assert(!tree.data.is_inline);
+        uint32_t child_count = ts_subtree_child_count(tree);
+        const Subtree *children = ts_subtree_children(tree);
+        for (uint32_t k = 0; k < child_count; k++) {
+          ts_subtree_retain(children[k]);
+        }
+        array_splice(&trees, j, 1, child_count, children);
+        root = ts_subtree_from_mut(ts_subtree_new_node(
+          ts_subtree_symbol(tree),
+          &trees,
+          tree.ptr->production_id,
+          self->language
+        ));
+        ts_subtree_release(&self->tree_pool, tree);
+        break;
+      }
+    }
+
+    ts_assert(root.ptr);
+    self->accept_count++;
+
+    if (self->finished_tree.ptr) {
+      if (ts_parser__select_tree(self, self->finished_tree, root)) {
+        ts_subtree_release(&self->tree_pool, self->finished_tree);
+        self->finished_tree = root;
+      } else {
+        ts_subtree_release(&self->tree_pool, root);
+      }
+    } else {
+      self->finished_tree = root;
+    }
+  }
+
+  ts_stack_remove_version(self->stack, pop.contents[0].version);
+  ts_stack_halt(self->stack, version);
+}
+
+static bool ts_parser__do_all_potential_reductions(
+  TSParser *self,
+  StackVersion starting_version,
+  TSSymbol lookahead_symbol
+) {
+  uint32_t initial_version_count = ts_stack_version_count(self->stack);
+
+  bool can_shift_lookahead_symbol = false;
+  StackVersion version = starting_version;
+  for (unsigned i = 0; true; i++) {
+    uint32_t version_count = ts_stack_version_count(self->stack);
+    if (version >= version_count) break;
+
+    bool merged = false;
+    for (StackVersion j = initial_version_count; j < version; j++) {
+      if (ts_stack_merge(self->stack, j, version)) {
+        merged = true;
+        break;
+      }
+    }
+    if (merged) continue;
+
+    TSStateId state = ts_stack_state(self->stack, version);
+    bool has_shift_action = false;
+    array_clear(&self->reduce_actions);
+
+    TSSymbol first_symbol, end_symbol;
+    if (lookahead_symbol != 0) {
+      first_symbol = lookahead_symbol;
+      end_symbol = lookahead_symbol + 1;
+    } else {
+      first_symbol = 1;
+      end_symbol = self->language->token_count;
+    }
+
+    for (TSSymbol symbol = first_symbol; symbol < end_symbol; symbol++) {
+      TableEntry entry;
+      ts_language_table_entry(self->language, state, symbol, &entry);
+      for (uint32_t j = 0; j < entry.action_count; j++) {
+        TSParseAction action = entry.actions[j];
+        switch (action.type) {
+          case TSParseActionTypeShift:
+          case TSParseActionTypeRecover:
+            if (!action.shift.extra && !action.shift.repetition) has_shift_action = true;
+            break;
+          case TSParseActionTypeReduce:
+            if (action.reduce.child_count > 0)
+              ts_reduce_action_set_add(&self->reduce_actions, (ReduceAction) {
+                .symbol = action.reduce.symbol,
+                .count = action.reduce.child_count,
+                .dynamic_precedence = action.reduce.dynamic_precedence,
+                .production_id = action.reduce.production_id,
+              });
+            break;
+          default:
+            break;
+        }
+      }
+    }
+
+    StackVersion reduction_version = STACK_VERSION_NONE;
+    for (uint32_t j = 0; j < self->reduce_actions.size; j++) {
+      ReduceAction action = self->reduce_actions.contents[j];
+
+      reduction_version = ts_parser__reduce(
+        self, version, action.symbol, action.count,
+        action.dynamic_precedence, action.production_id,
+        true, false
+      );
+    }
+
+    if (has_shift_action) {
+      can_shift_lookahead_symbol = true;
+    } else if (reduction_version != STACK_VERSION_NONE && i < MAX_VERSION_COUNT) {
+      ts_stack_renumber_version(self->stack, reduction_version, version);
+      continue;
+    } else if (lookahead_symbol != 0) {
+      ts_stack_remove_version(self->stack, version);
+    }
+
+    if (version == starting_version) {
+      version = version_count;
+    } else {
+      version++;
+    }
+  }
+
+  return can_shift_lookahead_symbol;
+}
+
+static bool ts_parser__recover_to_state(
+  TSParser *self,
+  StackVersion version,
+  unsigned depth,
+  TSStateId goal_state
+) {
+  StackSliceArray pop = ts_stack_pop_count(self->stack, version, depth);
+  StackVersion previous_version = STACK_VERSION_NONE;
+
+  for (unsigned i = 0; i < pop.size; i++) {
+    StackSlice slice = pop.contents[i];
+
+    if (slice.version == previous_version) {
+      ts_subtree_array_delete(&self->tree_pool, &slice.subtrees);
+      array_erase(&pop, i--);
+      continue;
+    }
+
+    if (ts_stack_state(self->stack, slice.version) != goal_state) {
+      ts_stack_halt(self->stack, slice.version);
+      ts_subtree_array_delete(&self->tree_pool, &slice.subtrees);
+      array_erase(&pop, i--);
+      continue;
+    }
+
+    SubtreeArray error_trees = ts_stack_pop_error(self->stack, slice.version);
+    if (error_trees.size > 0) {
+      ts_assert(error_trees.size == 1);
+      Subtree error_tree = error_trees.contents[0];
+      uint32_t error_child_count = ts_subtree_child_count(error_tree);
+      if (error_child_count > 0) {
+        array_splice(&slice.subtrees, 0, 0, error_child_count, ts_subtree_children(error_tree));
+        for (unsigned j = 0; j < error_child_count; j++) {
+          ts_subtree_retain(slice.subtrees.contents[j]);
+        }
+      }
+      ts_subtree_array_delete(&self->tree_pool, &error_trees);
+    }
+
+    ts_subtree_array_remove_trailing_extras(&slice.subtrees, &self->trailing_extras);
+
+    if (slice.subtrees.size > 0) {
+      Subtree error = ts_subtree_new_error_node(&slice.subtrees, true, self->language);
+      ts_stack_push(self->stack, slice.version, error, false, goal_state);
+    } else {
+      array_delete(&slice.subtrees);
+    }
+
+    for (unsigned j = 0; j < self->trailing_extras.size; j++) {
+      Subtree tree = self->trailing_extras.contents[j];
+      ts_stack_push(self->stack, slice.version, tree, false, goal_state);
+    }
+
+    previous_version = slice.version;
+  }
+
+  return previous_version != STACK_VERSION_NONE;
+}
+
+static void ts_parser__recover(
+  TSParser *self,
+  StackVersion version,
+  Subtree lookahead
+) {
+  bool did_recover = false;
+  unsigned previous_version_count = ts_stack_version_count(self->stack);
+  Length position = ts_stack_position(self->stack, version);
+  StackSummary *summary = ts_stack_get_summary(self->stack, version);
+  unsigned node_count_since_error = ts_stack_node_count_since_error(self->stack, version);
+  unsigned current_error_cost = ts_stack_error_cost(self->stack, version);
+
+  // When the parser is in the error state, there are two strategies for recovering with a
+  // given lookahead token:
+  // 1. Find a previous state on the stack in which that lookahead token would be valid. Then,
+  //    create a new stack version that is in that state again. This entails popping all of the
+  //    subtrees that have been pushed onto the stack since that previous state, and wrapping
+  //    them in an ERROR node.
+  // 2. Wrap the lookahead token in an ERROR node, push that ERROR node onto the stack, and
+  //    move on to the next lookahead token, remaining in the error state.
+  //
+  // First, try the strategy 1. Upon entering the error state, the parser recorded a summary
+  // of the previous parse states and their depths. Look at each state in the summary, to see
+  // if the current lookahead token would be valid in that state.
+  if (summary && !ts_subtree_is_error(lookahead)) {
+    for (unsigned i = 0; i < summary->size; i++) {
+      StackSummaryEntry entry = summary->contents[i];
+
+      if (entry.state == ERROR_STATE) continue;
+      if (entry.position.bytes == position.bytes) continue;
+      unsigned depth = entry.depth;
+      if (node_count_since_error > 0) depth++;
+
+      // Do not recover in ways that create redundant stack versions.
+      bool would_merge = false;
+      for (unsigned j = 0; j < previous_version_count; j++) {
+        if (
+          ts_stack_state(self->stack, j) == entry.state &&
+          ts_stack_position(self->stack, j).bytes == position.bytes
+        ) {
+          would_merge = true;
+          break;
+        }
+      }
+      if (would_merge) continue;
+
+      // Do not recover if the result would clearly be worse than some existing stack version.
+      unsigned new_cost =
+        current_error_cost +
+        entry.depth * ERROR_COST_PER_SKIPPED_TREE +
+        (position.bytes - entry.position.bytes) * ERROR_COST_PER_SKIPPED_CHAR +
+        (position.extent.row - entry.position.extent.row) * ERROR_COST_PER_SKIPPED_LINE;
+      if (ts_parser__better_version_exists(self, version, false, new_cost)) break;
+
+      // If the current lookahead token is valid in some previous state, recover to that state.
+      // Then stop looking for further recoveries.
+      if (ts_language_has_actions(self->language, entry.state, ts_subtree_symbol(lookahead))) {
+        if (ts_parser__recover_to_state(self, version, depth, entry.state)) {
+          did_recover = true;
+          LOG("recover_to_previous state:%u, depth:%u", entry.state, depth);
+          LOG_STACK();
+          break;
+        }
+      }
+    }
+  }
+
+  // In the process of attempting to recover, some stack versions may have been created
+  // and subsequently halted. Remove those versions.
+  for (unsigned i = previous_version_count; i < ts_stack_version_count(self->stack); i++) {
+    if (!ts_stack_is_active(self->stack, i)) {
+      ts_stack_remove_version(self->stack, i--);
+    }
+  }
+
+  // If strategy 1 succeeded, a new stack version will have been created which is able to handle
+  // the current lookahead token. Now, in addition, try strategy 2 described above: skip the
+  // current lookahead token by wrapping it in an ERROR node.
+
+  // Don't pursue this additional strategy if there are already too many stack versions.
+  if (did_recover && ts_stack_version_count(self->stack) > MAX_VERSION_COUNT) {
+    ts_stack_halt(self->stack, version);
+    ts_subtree_release(&self->tree_pool, lookahead);
+    return;
+  }
+
+  if (
+    did_recover &&
+    ts_subtree_has_external_scanner_state_change(lookahead)
+  ) {
+    ts_stack_halt(self->stack, version);
+    ts_subtree_release(&self->tree_pool, lookahead);
+    return;
+  }
+
+  // If the parser is still in the error state at the end of the file, just wrap everything
+  // in an ERROR node and terminate.
+  if (ts_subtree_is_eof(lookahead)) {
+    LOG("recover_eof");
+    SubtreeArray children = array_new();
+    Subtree parent = ts_subtree_new_error_node(&children, false, self->language);
+    ts_stack_push(self->stack, version, parent, false, 1);
+    ts_parser__accept(self, version, lookahead);
+    return;
+  }
+
+  // Do not recover if the result would clearly be worse than some existing stack version.
+  unsigned new_cost =
+    current_error_cost + ERROR_COST_PER_SKIPPED_TREE +
+    ts_subtree_total_bytes(lookahead) * ERROR_COST_PER_SKIPPED_CHAR +
+    ts_subtree_total_size(lookahead).extent.row * ERROR_COST_PER_SKIPPED_LINE;
+  if (ts_parser__better_version_exists(self, version, false, new_cost)) {
+    ts_stack_halt(self->stack, version);
+    ts_subtree_release(&self->tree_pool, lookahead);
+    return;
+  }
+
+  // If the current lookahead token is an extra token, mark it as extra. This means it won't
+  // be counted in error cost calculations.
+  unsigned n;
+  const TSParseAction *actions = ts_language_actions(self->language, 1, ts_subtree_symbol(lookahead), &n);
+  if (n > 0 && actions[n - 1].type == TSParseActionTypeShift && actions[n - 1].shift.extra) {
+    MutableSubtree mutable_lookahead = ts_subtree_make_mut(&self->tree_pool, lookahead);
+    ts_subtree_set_extra(&mutable_lookahead, true);
+    lookahead = ts_subtree_from_mut(mutable_lookahead);
+  }
+
+  // Wrap the lookahead token in an ERROR.
+  LOG("skip_token symbol:%s", TREE_NAME(lookahead));
+  SubtreeArray children = array_new();
+  array_reserve(&children, 1);
+  array_push(&children, lookahead);
+  MutableSubtree error_repeat = ts_subtree_new_node(
+    ts_builtin_sym_error_repeat,
+    &children,
+    0,
+    self->language
+  );
+
+  // If other tokens have already been skipped, so there is already an ERROR at the top of the
+  // stack, then pop that ERROR off the stack and wrap the two ERRORs together into one larger
+  // ERROR.
+  if (node_count_since_error > 0) {
+    StackSliceArray pop = ts_stack_pop_count(self->stack, version, 1);
+
+    // TODO: Figure out how to make this condition occur.
+    // See https://github.com/atom/atom/issues/18450#issuecomment-439579778
+    // If multiple stack versions have merged at this point, just pick one of the errors
+    // arbitrarily and discard the rest.
+    if (pop.size > 1) {
+      for (unsigned i = 1; i < pop.size; i++) {
+        ts_subtree_array_delete(&self->tree_pool, &pop.contents[i].subtrees);
+      }
+      while (ts_stack_version_count(self->stack) > pop.contents[0].version + 1) {
+        ts_stack_remove_version(self->stack, pop.contents[0].version + 1);
+      }
+    }
+
+    ts_stack_renumber_version(self->stack, pop.contents[0].version, version);
+    array_push(&pop.contents[0].subtrees, ts_subtree_from_mut(error_repeat));
+    error_repeat = ts_subtree_new_node(
+      ts_builtin_sym_error_repeat,
+      &pop.contents[0].subtrees,
+      0,
+      self->language
+    );
+  }
+
+  // Push the new ERROR onto the stack.
+  ts_stack_push(self->stack, version, ts_subtree_from_mut(error_repeat), false, ERROR_STATE);
+  if (ts_subtree_has_external_tokens(lookahead)) {
+    ts_stack_set_last_external_token(
+      self->stack, version, ts_subtree_last_external_token(lookahead)
+    );
+  }
+}
+
+static void ts_parser__handle_error(
+  TSParser *self,
+  StackVersion version,
+  Subtree lookahead
+) {
+  uint32_t previous_version_count = ts_stack_version_count(self->stack);
+
+  // Perform any reductions that can happen in this state, regardless of the lookahead. After
+  // skipping one or more invalid tokens, the parser might find a token that would have allowed
+  // a reduction to take place.
+  ts_parser__do_all_potential_reductions(self, version, 0);
+  uint32_t version_count = ts_stack_version_count(self->stack);
+  Length position = ts_stack_position(self->stack, version);
+
+  // Push a discontinuity onto the stack. Merge all of the stack versions that
+  // were created in the previous step.
+  bool did_insert_missing_token = false;
+  for (StackVersion v = version; v < version_count;) {
+    if (!did_insert_missing_token) {
+      TSStateId state = ts_stack_state(self->stack, v);
+      for (
+        TSSymbol missing_symbol = 1;
+        missing_symbol < (uint16_t)self->language->token_count;
+        missing_symbol++
+      ) {
+        TSStateId state_after_missing_symbol = ts_language_next_state(
+          self->language, state, missing_symbol
+        );
+        if (state_after_missing_symbol == 0 || state_after_missing_symbol == state) {
+          continue;
+        }
+
+        if (ts_language_has_reduce_action(
+          self->language,
+          state_after_missing_symbol,
+          ts_subtree_leaf_symbol(lookahead)
+        )) {
+          // In case the parser is currently outside of any included range, the lexer will
+          // snap to the beginning of the next included range. The missing token's padding
+          // must be assigned to position it within the next included range.
+          ts_lexer_reset(&self->lexer, position);
+          ts_lexer_mark_end(&self->lexer);
+          Length padding = length_sub(self->lexer.token_end_position, position);
+          uint32_t lookahead_bytes = ts_subtree_total_bytes(lookahead) + ts_subtree_lookahead_bytes(lookahead);
+
+          StackVersion version_with_missing_tree = ts_stack_copy_version(self->stack, v);
+          Subtree missing_tree = ts_subtree_new_missing_leaf(
+            &self->tree_pool, missing_symbol,
+            padding, lookahead_bytes,
+            self->language
+          );
+          ts_stack_push(
+            self->stack, version_with_missing_tree,
+            missing_tree, false,
+            state_after_missing_symbol
+          );
+
+          if (ts_parser__do_all_potential_reductions(
+            self, version_with_missing_tree,
+            ts_subtree_leaf_symbol(lookahead)
+          )) {
+            LOG(
+              "recover_with_missing symbol:%s, state:%u",
+              SYM_NAME(missing_symbol),
+              ts_stack_state(self->stack, version_with_missing_tree)
+            );
+            did_insert_missing_token = true;
+            break;
+          }
+        }
+      }
+    }
+
+    ts_stack_push(self->stack, v, NULL_SUBTREE, false, ERROR_STATE);
+    v = (v == version) ? previous_version_count : v + 1;
+  }
+
+  for (unsigned i = previous_version_count; i < version_count; i++) {
+    bool did_merge = ts_stack_merge(self->stack, version, previous_version_count);
+    ts_assert(did_merge);
+  }
+
+  ts_stack_record_summary(self->stack, version, MAX_SUMMARY_DEPTH);
+
+  // Begin recovery with the current lookahead node, rather than waiting for the
+  // next turn of the parse loop. This ensures that the tree accounts for the
+  // current lookahead token's "lookahead bytes" value, which describes how far
+  // the lexer needed to look ahead beyond the content of the token in order to
+  // recognize it.
+  if (ts_subtree_child_count(lookahead) > 0) {
+    ts_parser__breakdown_lookahead(self, &lookahead, ERROR_STATE, &self->reusable_node);
+  }
+  ts_parser__recover(self, version, lookahead);
+
+  LOG_STACK();
+}
+
+static bool ts_parser__advance(
+  TSParser *self,
+  StackVersion version,
+  bool allow_node_reuse
+) {
+  TSStateId state = ts_stack_state(self->stack, version);
+  uint32_t position = ts_stack_position(self->stack, version).bytes;
+  Subtree last_external_token = ts_stack_last_external_token(self->stack, version);
+
+  bool did_reuse = true;
+  Subtree lookahead = NULL_SUBTREE;
+  TableEntry table_entry = {.action_count = 0};
+
+  // If possible, reuse a node from the previous syntax tree.
+  if (allow_node_reuse) {
+    lookahead = ts_parser__reuse_node(
+      self, version, &state, position, last_external_token, &table_entry
+    );
+  }
+
+  // If no node from the previous syntax tree could be reused, then try to
+  // reuse the token previously returned by the lexer.
+  if (!lookahead.ptr) {
+    did_reuse = false;
+    lookahead = ts_parser__get_cached_token(
+      self, state, position, last_external_token, &table_entry
+    );
+  }
+
+  bool needs_lex = !lookahead.ptr;
+  for (;;) {
+    // Otherwise, re-run the lexer.
+    if (needs_lex) {
+      needs_lex = false;
+      lookahead = ts_parser__lex(self, version, state);
+      if (self->has_scanner_error) return false;
+
+      if (lookahead.ptr) {
+        ts_parser__set_cached_token(self, position, last_external_token, lookahead);
+        ts_language_table_entry(self->language, state, ts_subtree_symbol(lookahead), &table_entry);
+      }
+
+      // When parsing a non-terminal extra, a null lookahead indicates the
+      // end of the rule. The reduction is stored in the EOF table entry.
+      // After the reduction, the lexer needs to be run again.
+      else {
+        ts_language_table_entry(self->language, state, ts_builtin_sym_end, &table_entry);
+      }
+    }
+
+    // If a cancellation flag or a timeout was provided, then check every
+    // time a fixed number of parse actions has been processed.
+    if (++self->operation_count == OP_COUNT_PER_PARSER_TIMEOUT_CHECK) {
+      self->operation_count = 0;
+    }
+    if (
+      self->operation_count == 0 &&
+      ((self->cancellation_flag && atomic_load(self->cancellation_flag)) ||
+       (!clock_is_null(self->end_clock) && clock_is_gt(clock_now(), self->end_clock)))
+    ) {
+      if (lookahead.ptr) {
+        ts_subtree_release(&self->tree_pool, lookahead);
+      }
+      return false;
+    }
+
+    // Process each parse action for the current lookahead token in
+    // the current state. If there are multiple actions, then this is
+    // an ambiguous state. REDUCE actions always create a new stack
+    // version, whereas SHIFT actions update the existing stack version
+    // and terminate this loop.
+    StackVersion last_reduction_version = STACK_VERSION_NONE;
+    for (uint32_t i = 0; i < table_entry.action_count; i++) {
+      TSParseAction action = table_entry.actions[i];
+
+      switch (action.type) {
+        case TSParseActionTypeShift: {
+          if (action.shift.repetition) break;
+          TSStateId next_state;
+          if (action.shift.extra) {
+            next_state = state;
+            LOG("shift_extra");
+          } else {
+            next_state = action.shift.state;
+            LOG("shift state:%u", next_state);
+          }
+
+          if (ts_subtree_child_count(lookahead) > 0) {
+            ts_parser__breakdown_lookahead(self, &lookahead, state, &self->reusable_node);
+            next_state = ts_language_next_state(self->language, state, ts_subtree_symbol(lookahead));
+          }
+
+          ts_parser__shift(self, version, next_state, lookahead, action.shift.extra);
+          if (did_reuse) reusable_node_advance(&self->reusable_node);
+          return true;
+        }
+
+        case TSParseActionTypeReduce: {
+          bool is_fragile = table_entry.action_count > 1;
+          bool end_of_non_terminal_extra = lookahead.ptr == NULL;
+          LOG("reduce sym:%s, child_count:%u", SYM_NAME(action.reduce.symbol), action.reduce.child_count);
+          StackVersion reduction_version = ts_parser__reduce(
+            self, version, action.reduce.symbol, action.reduce.child_count,
+            action.reduce.dynamic_precedence, action.reduce.production_id,
+            is_fragile, end_of_non_terminal_extra
+          );
+          if (reduction_version != STACK_VERSION_NONE) {
+            last_reduction_version = reduction_version;
+          }
+          break;
+        }
+
+        case TSParseActionTypeAccept: {
+          LOG("accept");
+          ts_parser__accept(self, version, lookahead);
+          return true;
+        }
+
+        case TSParseActionTypeRecover: {
+          if (ts_subtree_child_count(lookahead) > 0) {
+            ts_parser__breakdown_lookahead(self, &lookahead, ERROR_STATE, &self->reusable_node);
+          }
+
+          ts_parser__recover(self, version, lookahead);
+          if (did_reuse) reusable_node_advance(&self->reusable_node);
+          return true;
+        }
+      }
+    }
+
+    // If a reduction was performed, then replace the current stack version
+    // with one of the stack versions created by a reduction, and continue
+    // processing this version of the stack with the same lookahead symbol.
+    if (last_reduction_version != STACK_VERSION_NONE) {
+      ts_stack_renumber_version(self->stack, last_reduction_version, version);
+      LOG_STACK();
+      state = ts_stack_state(self->stack, version);
+
+      // At the end of a non-terminal extra rule, the lexer will return a
+      // null subtree, because the parser needs to perform a fixed reduction
+      // regardless of the lookahead node. After performing that reduction,
+      // (and completing the non-terminal extra rule) run the lexer again based
+      // on the current parse state.
+      if (!lookahead.ptr) {
+        needs_lex = true;
+      } else {
+        ts_language_table_entry(
+          self->language,
+          state,
+          ts_subtree_leaf_symbol(lookahead),
+          &table_entry
+        );
+      }
+
+      continue;
+    }
+
+    // A non-terminal extra rule was reduced and merged into an existing
+    // stack version. This version can be discarded.
+    if (!lookahead.ptr) {
+      ts_stack_halt(self->stack, version);
+      return true;
+    }
+
+    // If there were no parse actions for the current lookahead token, then
+    // it is not valid in this state. If the current lookahead token is a
+    // keyword, then switch to treating it as the normal word token if that
+    // token is valid in this state.
+    if (
+      ts_subtree_is_keyword(lookahead) &&
+      ts_subtree_symbol(lookahead) != self->language->keyword_capture_token
+    ) {
+      ts_language_table_entry(self->language, state, self->language->keyword_capture_token, &table_entry);
+      if (table_entry.action_count > 0) {
+        LOG(
+          "switch from_keyword:%s, to_word_token:%s",
+          TREE_NAME(lookahead),
+          SYM_NAME(self->language->keyword_capture_token)
+        );
+
+        MutableSubtree mutable_lookahead = ts_subtree_make_mut(&self->tree_pool, lookahead);
+        ts_subtree_set_symbol(&mutable_lookahead, self->language->keyword_capture_token, self->language);
+        lookahead = ts_subtree_from_mut(mutable_lookahead);
+        continue;
+      }
+    }
+
+    // If the current lookahead token is not valid and the parser is
+    // already in the error state, restart the error recovery process.
+    // TODO - can this be unified with the other `RECOVER` case above?
+    if (state == ERROR_STATE) {
+      ts_parser__recover(self, version, lookahead);
+      return true;
+    }
+
+    // If the current lookahead token is not valid and the previous
+    // subtree on the stack was reused from an old tree, it isn't actually
+    // valid to reuse it. Remove it from the stack, and in its place,
+    // push each of its children. Then try again to process the current
+    // lookahead.
+    if (ts_parser__breakdown_top_of_stack(self, version)) {
+      state = ts_stack_state(self->stack, version);
+      ts_subtree_release(&self->tree_pool, lookahead);
+      needs_lex = true;
+      continue;
+    }
+
+    // At this point, the current lookahead token is definitely not valid
+    // for this parse stack version. Mark this version as paused and continue
+    // processing any other stack versions that might exist. If some other
+    // version advances successfully, then this version can simply be removed.
+    // But if all versions end up paused, then error recovery is needed.
+    LOG("detect_error");
+    ts_stack_pause(self->stack, version, lookahead);
+    return true;
+  }
+}
+
+static unsigned ts_parser__condense_stack(TSParser *self) {
+  bool made_changes = false;
+  unsigned min_error_cost = UINT_MAX;
+  for (StackVersion i = 0; i < ts_stack_version_count(self->stack); i++) {
+    // Prune any versions that have been marked for removal.
+    if (ts_stack_is_halted(self->stack, i)) {
+      ts_stack_remove_version(self->stack, i);
+      i--;
+      continue;
+    }
+
+    // Keep track of the minimum error cost of any stack version so
+    // that it can be returned.
+    ErrorStatus status_i = ts_parser__version_status(self, i);
+    if (!status_i.is_in_error && status_i.cost < min_error_cost) {
+      min_error_cost = status_i.cost;
+    }
+
+    // Examine each pair of stack versions, removing any versions that
+    // are clearly worse than another version. Ensure that the versions
+    // are ordered from most promising to least promising.
+    for (StackVersion j = 0; j < i; j++) {
+      ErrorStatus status_j = ts_parser__version_status(self, j);
+
+      switch (ts_parser__compare_versions(self, status_j, status_i)) {
+        case ErrorComparisonTakeLeft:
+          made_changes = true;
+          ts_stack_remove_version(self->stack, i);
+          i--;
+          j = i;
+          break;
+
+        case ErrorComparisonPreferLeft:
+        case ErrorComparisonNone:
+          if (ts_stack_merge(self->stack, j, i)) {
+            made_changes = true;
+            i--;
+            j = i;
+          }
+          break;
+
+        case ErrorComparisonPreferRight:
+          made_changes = true;
+          if (ts_stack_merge(self->stack, j, i)) {
+            i--;
+            j = i;
+          } else {
+            ts_stack_swap_versions(self->stack, i, j);
+          }
+          break;
+
+        case ErrorComparisonTakeRight:
+          made_changes = true;
+          ts_stack_remove_version(self->stack, j);
+          i--;
+          j--;
+          break;
+      }
+    }
+  }
+
+  // Enforce a hard upper bound on the number of stack versions by
+  // discarding the least promising versions.
+  while (ts_stack_version_count(self->stack) > MAX_VERSION_COUNT) {
+    ts_stack_remove_version(self->stack, MAX_VERSION_COUNT);
+    made_changes = true;
+  }
+
+  // If the best-performing stack version is currently paused, or all
+  // versions are paused, then resume the best paused version and begin
+  // the error recovery process. Otherwise, remove the paused versions.
+  if (ts_stack_version_count(self->stack) > 0) {
+    bool has_unpaused_version = false;
+    for (StackVersion i = 0, n = ts_stack_version_count(self->stack); i < n; i++) {
+      if (ts_stack_is_paused(self->stack, i)) {
+        if (!has_unpaused_version && self->accept_count < MAX_VERSION_COUNT) {
+          LOG("resume version:%u", i);
+          min_error_cost = ts_stack_error_cost(self->stack, i);
+          Subtree lookahead = ts_stack_resume(self->stack, i);
+          ts_parser__handle_error(self, i, lookahead);
+          has_unpaused_version = true;
+        } else {
+          ts_stack_remove_version(self->stack, i);
+          i--;
+          n--;
+        }
+      } else {
+        has_unpaused_version = true;
+      }
+    }
+  }
+
+  if (made_changes) {
+    LOG("condense");
+    LOG_STACK();
+  }
+
+  return min_error_cost;
+}
+
+static bool ts_parser_has_outstanding_parse(TSParser *self) {
+  return (
+    self->external_scanner_payload ||
+    ts_stack_state(self->stack, 0) != 1 ||
+    ts_stack_node_count_since_error(self->stack, 0) != 0
+  );
+}
+
+// Parser - Public
+
+TSParser *ts_parser_new(void) {
+  TSParser *self = ts_calloc(1, sizeof(TSParser));
+  ts_lexer_init(&self->lexer);
+  array_init(&self->reduce_actions);
+  array_reserve(&self->reduce_actions, 4);
+  self->tree_pool = ts_subtree_pool_new(32);
+  self->stack = ts_stack_new(&self->tree_pool);
+  self->finished_tree = NULL_SUBTREE;
+  self->reusable_node = reusable_node_new();
+  self->dot_graph_file = NULL;
+  self->cancellation_flag = NULL;
+  self->timeout_duration = 0;
+  self->language = NULL;
+  self->has_scanner_error = false;
+  self->external_scanner_payload = NULL;
+  self->end_clock = clock_null();
+  self->operation_count = 0;
+  self->old_tree = NULL_SUBTREE;
+  self->included_range_differences = (TSRangeArray) array_new();
+  self->included_range_difference_index = 0;
+  ts_parser__set_cached_token(self, 0, NULL_SUBTREE, NULL_SUBTREE);
+  return self;
+}
+
+void ts_parser_delete(TSParser *self) {
+  if (!self) return;
+
+  ts_parser_set_language(self, NULL);
+  ts_stack_delete(self->stack);
+  if (self->reduce_actions.contents) {
+    array_delete(&self->reduce_actions);
+  }
+  if (self->included_range_differences.contents) {
+    array_delete(&self->included_range_differences);
+  }
+  if (self->old_tree.ptr) {
+    ts_subtree_release(&self->tree_pool, self->old_tree);
+    self->old_tree = NULL_SUBTREE;
+  }
+  ts_wasm_store_delete(self->wasm_store);
+  ts_lexer_delete(&self->lexer);
+  ts_parser__set_cached_token(self, 0, NULL_SUBTREE, NULL_SUBTREE);
+  ts_subtree_pool_delete(&self->tree_pool);
+  reusable_node_delete(&self->reusable_node);
+  array_delete(&self->trailing_extras);
+  array_delete(&self->trailing_extras2);
+  array_delete(&self->scratch_trees);
+  ts_free(self);
+}
+
+const TSLanguage *ts_parser_language(const TSParser *self) {
+  return self->language;
+}
+
+bool ts_parser_set_language(TSParser *self, const TSLanguage *language) {
+  ts_parser_reset(self);
+  ts_language_delete(self->language);
+  self->language = NULL;
+
+  if (language) {
+    if (
+      language->version > TREE_SITTER_LANGUAGE_VERSION ||
+      language->version < TREE_SITTER_MIN_COMPATIBLE_LANGUAGE_VERSION
+    ) return false;
+
+    if (ts_language_is_wasm(language)) {
+      if (
+        !self->wasm_store ||
+        !ts_wasm_store_start(self->wasm_store, &self->lexer.data, language)
+      ) return false;
+    }
+  }
+
+  self->language = ts_language_copy(language);
+  return true;
+}
+
+TSLogger ts_parser_logger(const TSParser *self) {
+  return self->lexer.logger;
+}
+
+void ts_parser_set_logger(TSParser *self, TSLogger logger) {
+  self->lexer.logger = logger;
+}
+
+void ts_parser_print_dot_graphs(TSParser *self, int fd) {
+  if (self->dot_graph_file) {
+    fclose(self->dot_graph_file);
+  }
+
+  if (fd >= 0) {
+    #ifdef _WIN32
+    self->dot_graph_file = _fdopen(fd, "a");
+    #else
+    self->dot_graph_file = fdopen(fd, "a");
+    #endif
+  } else {
+    self->dot_graph_file = NULL;
+  }
+}
+
+const size_t *ts_parser_cancellation_flag(const TSParser *self) {
+  return (const size_t *)self->cancellation_flag;
+}
+
+void ts_parser_set_cancellation_flag(TSParser *self, const size_t *flag) {
+  self->cancellation_flag = (const volatile size_t *)flag;
+}
+
+uint64_t ts_parser_timeout_micros(const TSParser *self) {
+  return duration_to_micros(self->timeout_duration);
+}
+
+void ts_parser_set_timeout_micros(TSParser *self, uint64_t timeout_micros) {
+  self->timeout_duration = duration_from_micros(timeout_micros);
+}
+
+bool ts_parser_set_included_ranges(
+  TSParser *self,
+  const TSRange *ranges,
+  uint32_t count
+) {
+  return ts_lexer_set_included_ranges(&self->lexer, ranges, count);
+}
+
+const TSRange *ts_parser_included_ranges(const TSParser *self, uint32_t *count) {
+  return ts_lexer_included_ranges(&self->lexer, count);
+}
+
+void ts_parser_reset(TSParser *self) {
+  ts_parser__external_scanner_destroy(self);
+  if (self->wasm_store) {
+    ts_wasm_store_reset(self->wasm_store);
+  }
+
+  if (self->old_tree.ptr) {
+    ts_subtree_release(&self->tree_pool, self->old_tree);
+    self->old_tree = NULL_SUBTREE;
+  }
+
+  reusable_node_clear(&self->reusable_node);
+  ts_lexer_reset(&self->lexer, length_zero());
+  ts_stack_clear(self->stack);
+  ts_parser__set_cached_token(self, 0, NULL_SUBTREE, NULL_SUBTREE);
+  if (self->finished_tree.ptr) {
+    ts_subtree_release(&self->tree_pool, self->finished_tree);
+    self->finished_tree = NULL_SUBTREE;
+  }
+  self->accept_count = 0;
+  self->has_scanner_error = false;
+}
+
+TSTree *ts_parser_parse(
+  TSParser *self,
+  const TSTree *old_tree,
+  TSInput input
+) {
+  TSTree *result = NULL;
+  if (!self->language || !input.read) return NULL;
+
+  if (ts_language_is_wasm(self->language)) {
+    if (!self->wasm_store) return NULL;
+    ts_wasm_store_start(self->wasm_store, &self->lexer.data, self->language);
+  }
+
+  ts_lexer_set_input(&self->lexer, input);
+  array_clear(&self->included_range_differences);
+  self->included_range_difference_index = 0;
+
+  if (ts_parser_has_outstanding_parse(self)) {
+    LOG("resume_parsing");
+  } else {
+    ts_parser__external_scanner_create(self);
+    if (self->has_scanner_error) goto exit;
+
+    if (old_tree) {
+      ts_subtree_retain(old_tree->root);
+      self->old_tree = old_tree->root;
+      ts_range_array_get_changed_ranges(
+        old_tree->included_ranges, old_tree->included_range_count,
+        self->lexer.included_ranges, self->lexer.included_range_count,
+        &self->included_range_differences
+      );
+      reusable_node_reset(&self->reusable_node, old_tree->root);
+      LOG("parse_after_edit");
+      LOG_TREE(self->old_tree);
+      for (unsigned i = 0; i < self->included_range_differences.size; i++) {
+        TSRange *range = &self->included_range_differences.contents[i];
+        LOG("different_included_range %u - %u", range->start_byte, range->end_byte);
+      }
+    } else {
+      reusable_node_clear(&self->reusable_node);
+      LOG("new_parse");
+    }
+  }
+
+  self->operation_count = 0;
+  if (self->timeout_duration) {
+    self->end_clock = clock_after(clock_now(), self->timeout_duration);
+  } else {
+    self->end_clock = clock_null();
+  }
+
+  uint32_t position = 0, last_position = 0, version_count = 0;
+  do {
+    for (
+      StackVersion version = 0;
+      version_count = ts_stack_version_count(self->stack),
+      version < version_count;
+      version++
+    ) {
+      bool allow_node_reuse = version_count == 1;
+      while (ts_stack_is_active(self->stack, version)) {
+        LOG(
+          "process version:%u, version_count:%u, state:%d, row:%u, col:%u",
+          version,
+          ts_stack_version_count(self->stack),
+          ts_stack_state(self->stack, version),
+          ts_stack_position(self->stack, version).extent.row,
+          ts_stack_position(self->stack, version).extent.column
+        );
+
+        if (!ts_parser__advance(self, version, allow_node_reuse)) {
+          if (self->has_scanner_error) goto exit;
+          return NULL;
+        }
+
+        LOG_STACK();
+
+        position = ts_stack_position(self->stack, version).bytes;
+        if (position > last_position || (version > 0 && position == last_position)) {
+          last_position = position;
+          break;
+        }
+      }
+    }
+
+    // After advancing each version of the stack, re-sort the versions by their cost,
+    // removing any versions that are no longer worth pursuing.
+    unsigned min_error_cost = ts_parser__condense_stack(self);
+
+    // If there's already a finished parse tree that's better than any in-progress version,
+    // then terminate parsing. Clear the parse stack to remove any extra references to subtrees
+    // within the finished tree, ensuring that these subtrees can be safely mutated in-place
+    // for rebalancing.
+    if (self->finished_tree.ptr && ts_subtree_error_cost(self->finished_tree) < min_error_cost) {
+      ts_stack_clear(self->stack);
+      break;
+    }
+
+    while (self->included_range_difference_index < self->included_range_differences.size) {
+      TSRange *range = &self->included_range_differences.contents[self->included_range_difference_index];
+      if (range->end_byte <= position) {
+        self->included_range_difference_index++;
+      } else {
+        break;
+      }
+    }
+  } while (version_count != 0);
+
+  ts_assert(self->finished_tree.ptr);
+  ts_subtree_balance(self->finished_tree, &self->tree_pool, self->language);
+  LOG("done");
+  LOG_TREE(self->finished_tree);
+
+  result = ts_tree_new(
+    self->finished_tree,
+    self->language,
+    self->lexer.included_ranges,
+    self->lexer.included_range_count
+  );
+  self->finished_tree = NULL_SUBTREE;
+
+exit:
+  ts_parser_reset(self);
+  return result;
+}
+
+TSTree *ts_parser_parse_string(
+  TSParser *self,
+  const TSTree *old_tree,
+  const char *string,
+  uint32_t length
+) {
+  return ts_parser_parse_string_encoding(self, old_tree, string, length, TSInputEncodingUTF8);
+}
+
+TSTree *ts_parser_parse_string_encoding(
+  TSParser *self,
+  const TSTree *old_tree,
+  const char *string,
+  uint32_t length,
+  TSInputEncoding encoding
+) {
+  TSStringInput input = {string, length};
+  return ts_parser_parse(self, old_tree, (TSInput) {
+    &input,
+    ts_string_input_read,
+    encoding,
+  });
+}
+
+void ts_parser_set_wasm_store(TSParser *self, TSWasmStore *store) {
+  if (self->language && ts_language_is_wasm(self->language)) {
+    // Copy the assigned language into the new store.
+    const TSLanguage *copy = ts_language_copy(self->language);
+    ts_parser_set_language(self, copy);
+    ts_language_delete(copy);
+  }
+
+  ts_wasm_store_delete(self->wasm_store);
+  self->wasm_store = store;
+}
+
+TSWasmStore *ts_parser_take_wasm_store(TSParser *self) {
+  if (self->language && ts_language_is_wasm(self->language)) {
+    ts_parser_set_language(self, NULL);
+  }
+
+  TSWasmStore *result = self->wasm_store;
+  self->wasm_store = NULL;
+  return result;
+}
+
+#undef LOG
diff --git a/vendor/tree-sitter/lib/src/parser.h b/vendor/tree-sitter/lib/src/parser.h
new file mode 100644
--- /dev/null
+++ b/vendor/tree-sitter/lib/src/parser.h
@@ -0,0 +1,266 @@
+#ifndef TREE_SITTER_PARSER_H_
+#define TREE_SITTER_PARSER_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+#define ts_builtin_sym_error ((TSSymbol)-1)
+#define ts_builtin_sym_end 0
+#define TREE_SITTER_SERIALIZATION_BUFFER_SIZE 1024
+
+#ifndef TREE_SITTER_API_H_
+typedef uint16_t TSStateId;
+typedef uint16_t TSSymbol;
+typedef uint16_t TSFieldId;
+typedef struct TSLanguage TSLanguage;
+#endif
+
+typedef struct {
+  TSFieldId field_id;
+  uint8_t child_index;
+  bool inherited;
+} TSFieldMapEntry;
+
+typedef struct {
+  uint16_t index;
+  uint16_t length;
+} TSFieldMapSlice;
+
+typedef struct {
+  bool visible;
+  bool named;
+  bool supertype;
+} TSSymbolMetadata;
+
+typedef struct TSLexer TSLexer;
+
+struct TSLexer {
+  int32_t lookahead;
+  TSSymbol result_symbol;
+  void (*advance)(TSLexer *, bool);
+  void (*mark_end)(TSLexer *);
+  uint32_t (*get_column)(TSLexer *);
+  bool (*is_at_included_range_start)(const TSLexer *);
+  bool (*eof)(const TSLexer *);
+  void (*log)(const TSLexer *, const char *, ...);
+};
+
+typedef enum {
+  TSParseActionTypeShift,
+  TSParseActionTypeReduce,
+  TSParseActionTypeAccept,
+  TSParseActionTypeRecover,
+} TSParseActionType;
+
+typedef union {
+  struct {
+    uint8_t type;
+    TSStateId state;
+    bool extra;
+    bool repetition;
+  } shift;
+  struct {
+    uint8_t type;
+    uint8_t child_count;
+    TSSymbol symbol;
+    int16_t dynamic_precedence;
+    uint16_t production_id;
+  } reduce;
+  uint8_t type;
+} TSParseAction;
+
+typedef struct {
+  uint16_t lex_state;
+  uint16_t external_lex_state;
+} TSLexMode;
+
+typedef union {
+  TSParseAction action;
+  struct {
+    uint8_t count;
+    bool reusable;
+  } entry;
+} TSParseActionEntry;
+
+typedef struct {
+  int32_t start;
+  int32_t end;
+} TSCharacterRange;
+
+struct TSLanguage {
+  uint32_t version;
+  uint32_t symbol_count;
+  uint32_t alias_count;
+  uint32_t token_count;
+  uint32_t external_token_count;
+  uint32_t state_count;
+  uint32_t large_state_count;
+  uint32_t production_id_count;
+  uint32_t field_count;
+  uint16_t max_alias_sequence_length;
+  const uint16_t *parse_table;
+  const uint16_t *small_parse_table;
+  const uint32_t *small_parse_table_map;
+  const TSParseActionEntry *parse_actions;
+  const char * const *symbol_names;
+  const char * const *field_names;
+  const TSFieldMapSlice *field_map_slices;
+  const TSFieldMapEntry *field_map_entries;
+  const TSSymbolMetadata *symbol_metadata;
+  const TSSymbol *public_symbol_map;
+  const uint16_t *alias_map;
+  const TSSymbol *alias_sequences;
+  const TSLexMode *lex_modes;
+  bool (*lex_fn)(TSLexer *, TSStateId);
+  bool (*keyword_lex_fn)(TSLexer *, TSStateId);
+  TSSymbol keyword_capture_token;
+  struct {
+    const bool *states;
+    const TSSymbol *symbol_map;
+    void *(*create)(void);
+    void (*destroy)(void *);
+    bool (*scan)(void *, TSLexer *, const bool *symbol_whitelist);
+    unsigned (*serialize)(void *, char *);
+    void (*deserialize)(void *, const char *, unsigned);
+  } external_scanner;
+  const TSStateId *primary_state_ids;
+};
+
+static inline bool set_contains(TSCharacterRange *ranges, uint32_t len, int32_t lookahead) {
+  uint32_t index = 0;
+  uint32_t size = len - index;
+  while (size > 1) {
+    uint32_t half_size = size / 2;
+    uint32_t mid_index = index + half_size;
+    TSCharacterRange *range = &ranges[mid_index];
+    if (lookahead >= range->start && lookahead <= range->end) {
+      return true;
+    } else if (lookahead > range->end) {
+      index = mid_index;
+    }
+    size -= half_size;
+  }
+  TSCharacterRange *range = &ranges[index];
+  return (lookahead >= range->start && lookahead <= range->end);
+}
+
+/*
+ *  Lexer Macros
+ */
+
+#ifdef _MSC_VER
+#define UNUSED __pragma(warning(suppress : 4101))
+#else
+#define UNUSED __attribute__((unused))
+#endif
+
+#define START_LEXER()           \
+  bool result = false;          \
+  bool skip = false;            \
+  UNUSED                        \
+  bool eof = false;             \
+  int32_t lookahead;            \
+  goto start;                   \
+  next_state:                   \
+  lexer->advance(lexer, skip);  \
+  start:                        \
+  skip = false;                 \
+  lookahead = lexer->lookahead;
+
+#define ADVANCE(state_value) \
+  {                          \
+    state = state_value;     \
+    goto next_state;         \
+  }
+
+#define ADVANCE_MAP(...)                                              \
+  {                                                                   \
+    static const uint16_t map[] = { __VA_ARGS__ };                    \
+    for (uint32_t i = 0; i < sizeof(map) / sizeof(map[0]); i += 2) {  \
+      if (map[i] == lookahead) {                                      \
+        state = map[i + 1];                                           \
+        goto next_state;                                              \
+      }                                                               \
+    }                                                                 \
+  }
+
+#define SKIP(state_value) \
+  {                       \
+    skip = true;          \
+    state = state_value;  \
+    goto next_state;      \
+  }
+
+#define ACCEPT_TOKEN(symbol_value)     \
+  result = true;                       \
+  lexer->result_symbol = symbol_value; \
+  lexer->mark_end(lexer);
+
+#define END_STATE() return result;
+
+/*
+ *  Parse Table Macros
+ */
+
+#define SMALL_STATE(id) ((id) - LARGE_STATE_COUNT)
+
+#define STATE(id) id
+
+#define ACTIONS(id) id
+
+#define SHIFT(state_value)            \
+  {{                                  \
+    .shift = {                        \
+      .type = TSParseActionTypeShift, \
+      .state = (state_value)          \
+    }                                 \
+  }}
+
+#define SHIFT_REPEAT(state_value)     \
+  {{                                  \
+    .shift = {                        \
+      .type = TSParseActionTypeShift, \
+      .state = (state_value),         \
+      .repetition = true              \
+    }                                 \
+  }}
+
+#define SHIFT_EXTRA()                 \
+  {{                                  \
+    .shift = {                        \
+      .type = TSParseActionTypeShift, \
+      .extra = true                   \
+    }                                 \
+  }}
+
+#define REDUCE(symbol_name, children, precedence, prod_id) \
+  {{                                                       \
+    .reduce = {                                            \
+      .type = TSParseActionTypeReduce,                     \
+      .symbol = symbol_name,                               \
+      .child_count = children,                             \
+      .dynamic_precedence = precedence,                    \
+      .production_id = prod_id                             \
+    },                                                     \
+  }}
+
+#define RECOVER()                    \
+  {{                                 \
+    .type = TSParseActionTypeRecover \
+  }}
+
+#define ACCEPT_INPUT()              \
+  {{                                \
+    .type = TSParseActionTypeAccept \
+  }}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  // TREE_SITTER_PARSER_H_
diff --git a/vendor/tree-sitter/lib/src/point.h b/vendor/tree-sitter/lib/src/point.h
new file mode 100644
--- /dev/null
+++ b/vendor/tree-sitter/lib/src/point.h
@@ -0,0 +1,62 @@
+#ifndef TREE_SITTER_POINT_H_
+#define TREE_SITTER_POINT_H_
+
+#include "tree_sitter/api.h"
+
+#define POINT_ZERO ((TSPoint) {0, 0})
+#define POINT_MAX ((TSPoint) {UINT32_MAX, UINT32_MAX})
+
+static inline TSPoint point__new(unsigned row, unsigned column) {
+  TSPoint result = {row, column};
+  return result;
+}
+
+static inline TSPoint point_add(TSPoint a, TSPoint b) {
+  if (b.row > 0)
+    return point__new(a.row + b.row, b.column);
+  else
+    return point__new(a.row, a.column + b.column);
+}
+
+static inline TSPoint point_sub(TSPoint a, TSPoint b) {
+  if (a.row > b.row)
+    return point__new(a.row - b.row, a.column);
+  else
+    return point__new(0, a.column - b.column);
+}
+
+static inline bool point_lte(TSPoint a, TSPoint b) {
+  return (a.row < b.row) || (a.row == b.row && a.column <= b.column);
+}
+
+static inline bool point_lt(TSPoint a, TSPoint b) {
+  return (a.row < b.row) || (a.row == b.row && a.column < b.column);
+}
+
+static inline bool point_gt(TSPoint a, TSPoint b) {
+  return (a.row > b.row) || (a.row == b.row && a.column > b.column);
+}
+
+static inline bool point_gte(TSPoint a, TSPoint b) {
+  return (a.row > b.row) || (a.row == b.row && a.column >= b.column);
+}
+
+static inline bool point_eq(TSPoint a, TSPoint b) {
+  return a.row == b.row && a.column == b.column;
+}
+
+static inline TSPoint point_min(TSPoint a, TSPoint b) {
+  if (a.row < b.row || (a.row == b.row && a.column < b.column))
+    return a;
+  else
+    return b;
+}
+
+static inline TSPoint point_max(TSPoint a, TSPoint b) {
+  if (a.row > b.row || (a.row == b.row && a.column > b.column))
+    return a;
+  else
+    return b;
+}
+
+#endif
diff --git a/vendor/tree-sitter/lib/src/query.c b/vendor/tree-sitter/lib/src/query.c
new file mode 100644
--- /dev/null
+++ b/vendor/tree-sitter/lib/src/query.c
@@ -0,0 +1,4187 @@
+#include "tree_sitter/api.h"
+#include "./alloc.h"
+#include "./array.h"
+#include "./clock.h"
+#include "./language.h"
+#include "./point.h"
+#include "./tree_cursor.h"
+#include "./unicode.h"
+#include <wctype.h>
+
+// #define DEBUG_ANALYZE_QUERY
+// #define DEBUG_EXECUTE_QUERY
+
+#define MAX_STEP_CAPTURE_COUNT 3
+#define MAX_NEGATED_FIELD_COUNT 8
+#define MAX_STATE_PREDECESSOR_COUNT 256
+#define MAX_ANALYSIS_STATE_DEPTH 8
+#define MAX_ANALYSIS_ITERATION_COUNT 256
+
+/*
+ * Stream - A sequence of unicode characters derived from a UTF8 string.
+ * This struct is used in parsing queries from S-expressions.
+ */
+typedef struct {
+  const char *input;
+  const char *start;
+  const char *end;
+  int32_t next;
+  uint8_t next_size;
+} Stream;
+
+/*
+ * QueryStep - A step in the process of matching a query. Each node within
+ * a query S-expression corresponds to one of these steps. An entire pattern
+ * is represented as a sequence of these steps. The basic properties of a
+ * node are represented by these fields:
+ * - `symbol` - The grammar symbol to match. A zero value represents the
+ *    wildcard symbol, '_'.
+ * - `field` - The field name to match. A zero value means that a field name
+ *    was not specified.
+ * - `capture_ids` - An array of integers representing the names of captures
+ *    associated with this node in the pattern, terminated by a `NONE` value.
+ * - `depth` - The depth where this node occurs in the pattern. The root node
+ *    of the pattern has depth zero.
+ * - `negated_field_list_id` - An id representing a set of fields that must
+ *    not be present on a node matching this step.
+ *
+ * Steps have some additional fields in order to handle the `.` (or "anchor") operator,
+ * which forbids additional child nodes:
+ * - `is_immediate` - Indicates that the node matching this step cannot be preceded
+ *   by other sibling nodes that weren't specified in the pattern.
+ * - `is_last_child` - Indicates that the node matching this step cannot have any
+ *   subsequent named siblings.
+ *
+ * For simple patterns, steps are matched in sequential order. But in order to
+ * handle alternative/repeated/optional sub-patterns, query steps are not always
+ * structured as a linear sequence; they sometimes need to split and merge. This
+ * is done using the following fields:
+ *  - `alternative_index` - The index of a different query step that serves as
+ *    an alternative to this step. A `NONE` value represents no alternative.
+ *    When a query state reaches a step with an alternative index, the state
+ *    is duplicated, with one copy remaining at the original step, and one copy
+ *    moving to the alternative step. The alternative may have its own alternative
+ *    step, so this splitting is an iterative process.
+ * - `is_dead_end` - Indicates that this state cannot be passed directly, and
+ *    exists only in order to redirect to an alternative index, with no splitting.
+ * - `is_pass_through` - Indicates that state has no matching logic of its own,
+ *    and exists only to split a state. One copy of the state advances immediately
+ *    to the next step, and one moves to the alternative step.
+ * - `alternative_is_immediate` - Indicates that this step's alternative step
+ *    should be treated as if `is_immediate` is true.
+ *
+ * Steps also store some derived state that summarizes how they relate to other
+ * steps within the same pattern. This is used to optimize the matching process:
+ *  - `contains_captures` - Indicates that this step or one of its child steps
+ *     has a non-empty `capture_ids` list.
+ *  - `parent_pattern_guaranteed` - Indicates that if this step is reached, then
+ *     it and all of its subsequent sibling steps within the same parent pattern
+ *     are guaranteed to match.
+ *  - `root_pattern_guaranteed` - Similar to `parent_pattern_guaranteed`, but
+ *     for the entire top-level pattern. When iterating through a query's
+ *     captures using `ts_query_cursor_next_capture`, this field is used to
+ *     detect that a capture can safely be returned from a match that has not
+ *     even completed  yet.
+ */
+typedef struct {
+  TSSymbol symbol;
+  TSSymbol supertype_symbol;
+  TSFieldId field;
+  uint16_t capture_ids[MAX_STEP_CAPTURE_COUNT];
+  uint16_t depth;
+  uint16_t alternative_index;
+  uint16_t negated_field_list_id;
+  bool is_named: 1;
+  bool is_immediate: 1;
+  bool is_last_child: 1;
+  bool is_pass_through: 1;
+  bool is_dead_end: 1;
+  bool alternative_is_immediate: 1;
+  bool contains_captures: 1;
+  bool root_pattern_guaranteed: 1;
+  bool parent_pattern_guaranteed: 1;
+} QueryStep;
+
+/*
+ * Slice - A slice of an external array. Within a query, capture names,
+ * literal string values, and predicate step information are stored in three
+ * contiguous arrays. Individual captures, string values, and predicates are
+ * represented as slices of these three arrays.
+ */
+typedef struct {
+  uint32_t offset;
+  uint32_t length;
+} Slice;
+
+/*
+ * SymbolTable - a two-way mapping of strings to ids.
+ */
+typedef struct {
+  Array(char) characters;
+  Array(Slice) slices;
+} SymbolTable;
+
+/**
+ * CaptureQuantififers - a data structure holding the quantifiers of pattern captures.
+ */
+typedef Array(uint8_t) CaptureQuantifiers;
+
+/*
+ * PatternEntry - Information about the starting point for matching a particular
+ * pattern. These entries are stored in a 'pattern map' - a sorted array that
+ * makes it possible to efficiently lookup patterns based on the symbol for their
+ * first step. The entry consists of the following fields:
+ * - `pattern_index` - the index of the pattern within the query
+ * - `step_index` - the index of the pattern's first step in the shared `steps` array
+ * - `is_rooted` - whether or not the pattern has a single root node. This property
+ *   affects decisions about whether or not to start the pattern for nodes outside
+ *   of a QueryCursor's range restriction.
+ */
+typedef struct {
+  uint16_t step_index;
+  uint16_t pattern_index;
+  bool is_rooted;
+} PatternEntry;
+
+typedef struct {
+  Slice steps;
+  Slice predicate_steps;
+  uint32_t start_byte;
+  uint32_t end_byte;
+  bool is_non_local;
+} QueryPattern;
+
+typedef struct {
+  uint32_t byte_offset;
+  uint16_t step_index;
+} StepOffset;
+
+/*
+ * QueryState - The state of an in-progress match of a particular pattern
+ * in a query. While executing, a `TSQueryCursor` must keep track of a number
+ * of possible in-progress matches. Each of those possible matches is
+ * represented as one of these states. Fields:
+ * - `id` - A numeric id that is exposed to the public API. This allows the
+ *    caller to remove a given match, preventing any more of its captures
+ *    from being returned.
+ * - `start_depth` - The depth in the tree where the first step of the state's
+ *    pattern was matched.
+ * - `pattern_index` - The pattern that the state is matching.
+ * - `consumed_capture_count` - The number of captures from this match that
+ *    have already been returned.
+ * - `capture_list_id` - A numeric id that can be used to retrieve the state's
+ *    list of captures from the `CaptureListPool`.
+ * - `seeking_immediate_match` - A flag that indicates that the state's next
+ *    step must be matched by the very next sibling. This is used when
+ *    processing repetitions.
+ * - `has_in_progress_alternatives` - A flag that indicates that there is are
+ *    other states that have the same captures as this state, but are at
+ *    different steps in their pattern. This means that in order to obey the
+ *    'longest-match' rule, this state should not be returned as a match until
+ *    it is clear that there can be no other alternative match with more captures.
+ */
+typedef struct {
+  uint32_t id;
+  uint32_t capture_list_id;
+  uint16_t start_depth;
+  uint16_t step_index;
+  uint16_t pattern_index;
+  uint16_t consumed_capture_count: 12;
+  bool seeking_immediate_match: 1;
+  bool has_in_progress_alternatives: 1;
+  bool dead: 1;
+  bool needs_parent: 1;
+} QueryState;
+
+typedef Array(TSQueryCapture) CaptureList;
+
+/*
+ * CaptureListPool - A collection of *lists* of captures. Each query state needs
+ * to maintain its own list of captures. To avoid repeated allocations, this struct
+ * maintains a fixed set of capture lists, and keeps track of which ones are
+ * currently in use by a query state.
+ */
+typedef struct {
+  Array(CaptureList) list;
+  CaptureList empty_list;
+  // The maximum number of capture lists that we are allowed to allocate. We
+  // never allow `list` to allocate more entries than this, dropping pending
+  // matches if needed to stay under the limit.
+  uint32_t max_capture_list_count;
+  // The number of capture lists allocated in `list` that are not currently in
+  // use. We reuse those existing-but-unused capture lists before trying to
+  // allocate any new ones. We use an invalid value (UINT32_MAX) for a capture
+  // list's length to indicate that it's not in use.
+  uint32_t free_capture_list_count;
+} CaptureListPool;
+
+/*
+ * AnalysisState - The state needed for walking the parse table when analyzing
+ * a query pattern, to determine at which steps the pattern might fail to match.
+ */
+typedef struct {
+  TSStateId parse_state;
+  TSSymbol parent_symbol;
+  uint16_t child_index;
+  TSFieldId field_id: 15;
+  bool done: 1;
+} AnalysisStateEntry;
+
+typedef struct {
+  AnalysisStateEntry stack[MAX_ANALYSIS_STATE_DEPTH];
+  uint16_t depth;
+  uint16_t step_index;
+  TSSymbol root_symbol;
+} AnalysisState;
+
+typedef Array(AnalysisState *) AnalysisStateSet;
+
+typedef struct {
+  AnalysisStateSet states;
+  AnalysisStateSet next_states;
+  AnalysisStateSet deeper_states;
+  AnalysisStateSet state_pool;
+  Array(uint16_t) final_step_indices;
+  Array(TSSymbol) finished_parent_symbols;
+  bool did_abort;
+} QueryAnalysis;
+
+/*
+ * AnalysisSubgraph - A subset of the states in the parse table that are used
+ * in constructing nodes with a certain symbol. Each state is accompanied by
+ * some information about the possible node that could be produced in
+ * downstream states.
+ */
+typedef struct {
+  TSStateId state;
+  uint16_t production_id;
+  uint8_t child_index: 7;
+  bool done: 1;
+} AnalysisSubgraphNode;
+
+typedef struct {
+  TSSymbol symbol;
+  Array(TSStateId) start_states;
+  Array(AnalysisSubgraphNode) nodes;
+} AnalysisSubgraph;
+
+typedef Array(AnalysisSubgraph) AnalysisSubgraphArray;
+
+/*
+ * StatePredecessorMap - A map that stores the predecessors of each parse state.
+ * This is used during query analysis to determine which parse states can lead
+ * to which reduce actions.
+ */
+typedef struct {
+  TSStateId *contents;
+} StatePredecessorMap;
+
+/*
+ * TSQuery - A tree query, compiled from a string of S-expressions. The query
+ * itself is immutable. The mutable state used in the process of executing the
+ * query is stored in a `TSQueryCursor`.
+ */
+struct TSQuery {
+  SymbolTable captures;
+  SymbolTable predicate_values;
+  Array(CaptureQuantifiers) capture_quantifiers;
+  Array(QueryStep) steps;
+  Array(PatternEntry) pattern_map;
+  Array(TSQueryPredicateStep) predicate_steps;
+  Array(QueryPattern) patterns;
+  Array(StepOffset) step_offsets;
+  Array(TSFieldId) negated_fields;
+  Array(char) string_buffer;
+  Array(TSSymbol) repeat_symbols_with_rootless_patterns;
+  const TSLanguage *language;
+  uint16_t wildcard_root_pattern_count;
+};
+
+/*
+ * TSQueryCursor - A stateful struct used to execute a query on a tree.
+ */
+struct TSQueryCursor {
+  const TSQuery *query;
+  TSTreeCursor cursor;
+  Array(QueryState) states;
+  Array(QueryState) finished_states;
+  CaptureListPool capture_list_pool;
+  uint32_t depth;
+  uint32_t max_start_depth;
+  uint32_t start_byte;
+  uint32_t end_byte;
+  TSPoint start_point;
+  TSPoint end_point;
+  uint32_t next_state_id;
+  TSClock end_clock;
+  TSDuration timeout_duration;
+  unsigned operation_count;
+  bool on_visible_node;
+  bool ascending;
+  bool halted;
+  bool did_exceed_match_limit;
+};
+
+static const TSQueryError PARENT_DONE = -1;
+static const uint16_t PATTERN_DONE_MARKER = UINT16_MAX;
+static const uint16_t NONE = UINT16_MAX;
+static const TSSymbol WILDCARD_SYMBOL = 0;
+static const unsigned OP_COUNT_PER_QUERY_TIMEOUT_CHECK = 100;
+
+/**********
+ * Stream
+ **********/
+
+// Advance to the next unicode code point in the stream.
+static bool stream_advance(Stream *self) {
+  self->input += self->next_size;
+  if (self->input < self->end) {
+    uint32_t size = ts_decode_utf8(
+      (const uint8_t *)self->input,
+      (uint32_t)(self->end - self->input),
+      &self->next
+    );
+    if (size > 0) {
+      self->next_size = size;
+      return true;
+    }
+  } else {
+    self->next_size = 0;
+    self->next = '\0';
+  }
+  return false;
+}
+
+// Reset the stream to the given input position, represented as a pointer
+// into the input string.
+static void stream_reset(Stream *self, const char *input) {
+  self->input = input;
+  self->next_size = 0;
+  stream_advance(self);
+}
+
+static Stream stream_new(const char *string, uint32_t length) {
+  Stream self = {
+    .next = 0,
+    .input = string,
+    .start = string,
+    .end = string + length,
+  };
+  stream_advance(&self);
+  return self;
+}
+
+static void stream_skip_whitespace(Stream *self) {
+  for (;;) {
+    if (iswspace(self->next)) {
+      stream_advance(self);
+    } else if (self->next == ';') {
+      // skip over comments
+      stream_advance(self);
+      while (self->next && self->next != '\n') {
+        if (!stream_advance(self)) break;
+      }
+    } else {
+      break;
+    }
+  }
+}
+
+static bool stream_is_ident_start(Stream *self) {
+  return iswalnum(self->next) || self->next == '_' || self->next == '-';
+}
+
+static void stream_scan_identifier(Stream *stream) {
+  do {
+    stream_advance(stream);
+  } while (
+    iswalnum(stream->next) ||
+    stream->next == '_' ||
+    stream->next == '-' ||
+    stream->next == '.' ||
+    stream->next == '?' ||
+    stream->next == '!'
+  );
+}
+
+static uint32_t stream_offset(Stream *self) {
+  return (uint32_t)(self->input - self->start);
+}
+
+/******************
+ * CaptureListPool
+ ******************/
+
+static CaptureListPool capture_list_pool_new(void) {
+  return (CaptureListPool) {
+    .list = array_new(),
+    .empty_list = array_new(),
+    .max_capture_list_count = UINT32_MAX,
+    .free_capture_list_count = 0,
+  };
+}
+
+static void capture_list_pool_reset(CaptureListPool *self) {
+  for (uint16_t i = 0; i < (uint16_t)self->list.size; i++) {
+    // This invalid size means that the list is not in use.
+    self->list.contents[i].size = UINT32_MAX;
+  }
+  self->free_capture_list_count = self->list.size;
+}
+
+static void capture_list_pool_delete(CaptureListPool *self) {
+  for (uint16_t i = 0; i < (uint16_t)self->list.size; i++) {
+    array_delete(&self->list.contents[i]);
+  }
+  array_delete(&self->list);
+}
+
+static const CaptureList *capture_list_pool_get(const CaptureListPool *self, uint16_t id) {
+  if (id >= self->list.size) return &self->empty_list;
+  return &self->list.contents[id];
+}
+
+static CaptureList *capture_list_pool_get_mut(CaptureListPool *self, uint16_t id) {
+  ts_assert(id < self->list.size);
+  return &self->list.contents[id];
+}
+
+static bool capture_list_pool_is_empty(const CaptureListPool *self) {
+  // The capture list pool is empty if all allocated lists are in use, and we
+  // have reached the maximum allowed number of allocated lists.
+  return self->free_capture_list_count == 0 && self->list.size >= self->max_capture_list_count;
+}
+
+static uint16_t capture_list_pool_acquire(CaptureListPool *self) {
+  // First see if any already allocated capture list is currently unused.
+  if (self->free_capture_list_count > 0) {
+    for (uint16_t i = 0; i < (uint16_t)self->list.size; i++) {
+      if (self->list.contents[i].size == UINT32_MAX) {
+        array_clear(&self->list.contents[i]);
+        self->free_capture_list_count--;
+        return i;
+      }
+    }
+  }
+
+  // Otherwise allocate and initialize a new capture list, as long as that
+  // doesn't put us over the requested maximum.
+  uint32_t i = self->list.size;
+  if (i >= self->max_capture_list_count) {
+    return NONE;
+  }
+  CaptureList list;
+  array_init(&list);
+  array_push(&self->list, list);
+  return i;
+}
+
+static void capture_list_pool_release(CaptureListPool *self, uint16_t id) {
+  if (id >= self->list.size) return;
+  self->list.contents[id].size = UINT32_MAX;
+  self->free_capture_list_count++;
+}
+
+/**************
+ * Quantifiers
+ **************/
+
+static TSQuantifier quantifier_mul(
+  TSQuantifier left,
+  TSQuantifier right
+) {
+  switch (left)
+  {
+    case TSQuantifierZero:
+      return TSQuantifierZero;
+    case TSQuantifierZeroOrOne:
+      switch (right) {
+        case TSQuantifierZero:
+          return TSQuantifierZero;
+        case TSQuantifierZeroOrOne:
+        case TSQuantifierOne:
+          return TSQuantifierZeroOrOne;
+        case TSQuantifierZeroOrMore:
+        case TSQuantifierOneOrMore:
+          return TSQuantifierZeroOrMore;
+      };
+      break;
+    case TSQuantifierZeroOrMore:
+      switch (right) {
+        case TSQuantifierZero:
+          return TSQuantifierZero;
+        case TSQuantifierZeroOrOne:
+        case TSQuantifierZeroOrMore:
+        case TSQuantifierOne:
+        case TSQuantifierOneOrMore:
+          return TSQuantifierZeroOrMore;
+      };
+      break;
+    case TSQuantifierOne:
+      return right;
+    case TSQuantifierOneOrMore:
+      switch (right) {
+        case TSQuantifierZero:
+          return TSQuantifierZero;
+        case TSQuantifierZeroOrOne:
+        case TSQuantifierZeroOrMore:
+          return TSQuantifierZeroOrMore;
+        case TSQuantifierOne:
+        case TSQuantifierOneOrMore:
+          return TSQuantifierOneOrMore;
+      };
+      break;
+  }
+  return TSQuantifierZero; // to make compiler happy, but all cases should be covered above!
+}
+
+static TSQuantifier quantifier_join(
+  TSQuantifier left,
+  TSQuantifier right
+) {
+  switch (left)
+  {
+    case TSQuantifierZero:
+      switch (right) {
+        case TSQuantifierZero:
+          return TSQuantifierZero;
+        case TSQuantifierZeroOrOne:
+        case TSQuantifierOne:
+          return TSQuantifierZeroOrOne;
+        case TSQuantifierZeroOrMore:
+        case TSQuantifierOneOrMore:
+          return TSQuantifierZeroOrMore;
+      };
+      break;
+    case TSQuantifierZeroOrOne:
+      switch (right) {
+        case TSQuantifierZero:
+        case TSQuantifierZeroOrOne:
+        case TSQuantifierOne:
+          return TSQuantifierZeroOrOne;
+          break;
+        case TSQuantifierZeroOrMore:
+        case TSQuantifierOneOrMore:
+          return TSQuantifierZeroOrMore;
+          break;
+      };
+      break;
+    case TSQuantifierZeroOrMore:
+      return TSQuantifierZeroOrMore;
+    case TSQuantifierOne:
+      switch (right) {
+        case TSQuantifierZero:
+        case TSQuantifierZeroOrOne:
+          return TSQuantifierZeroOrOne;
+        case TSQuantifierZeroOrMore:
+          return TSQuantifierZeroOrMore;
+        case TSQuantifierOne:
+          return TSQuantifierOne;
+        case TSQuantifierOneOrMore:
+          return TSQuantifierOneOrMore;
+      };
+      break;
+    case TSQuantifierOneOrMore:
+      switch (right) {
+        case TSQuantifierZero:
+        case TSQuantifierZeroOrOne:
+        case TSQuantifierZeroOrMore:
+          return TSQuantifierZeroOrMore;
+        case TSQuantifierOne:
+        case TSQuantifierOneOrMore:
+          return TSQuantifierOneOrMore;
+      };
+      break;
+  }
+  return TSQuantifierZero; // to make compiler happy, but all cases should be covered above!
+}
+
+static TSQuantifier quantifier_add(
+  TSQuantifier left,
+  TSQuantifier right
+) {
+  switch (left)
+  {
+    case TSQuantifierZero:
+      return right;
+    case TSQuantifierZeroOrOne:
+      switch (right) {
+        case TSQuantifierZero:
+          return TSQuantifierZeroOrOne;
+        case TSQuantifierZeroOrOne:
+        case TSQuantifierZeroOrMore:
+          return TSQuantifierZeroOrMore;
+        case TSQuantifierOne:
+        case TSQuantifierOneOrMore:
+          return TSQuantifierOneOrMore;
+      };
+      break;
+    case TSQuantifierZeroOrMore:
+      switch (right) {
+        case TSQuantifierZero:
+          return TSQuantifierZeroOrMore;
+        case TSQuantifierZeroOrOne:
+        case TSQuantifierZeroOrMore:
+          return TSQuantifierZeroOrMore;
+        case TSQuantifierOne:
+        case TSQuantifierOneOrMore:
+          return TSQuantifierOneOrMore;
+      };
+      break;
+    case TSQuantifierOne:
+      switch (right) {
+        case TSQuantifierZero:
+          return TSQuantifierOne;
+        case TSQuantifierZeroOrOne:
+        case TSQuantifierZeroOrMore:
+        case TSQuantifierOne:
+        case TSQuantifierOneOrMore:
+          return TSQuantifierOneOrMore;
+      };
+      break;
+    case TSQuantifierOneOrMore:
+      return TSQuantifierOneOrMore;
+  }
+  return TSQuantifierZero; // to make compiler happy, but all cases should be covered above!
+}
+
+// Create new capture quantifiers structure
+static CaptureQuantifiers capture_quantifiers_new(void) {
+  return (CaptureQuantifiers) array_new();
+}
+
+// Delete capture quantifiers structure
+static void capture_quantifiers_delete(
+  CaptureQuantifiers *self
+) {
+  array_delete(self);
+}
+
+// Clear capture quantifiers structure
+static void capture_quantifiers_clear(
+  CaptureQuantifiers *self
+) {
+  array_clear(self);
+}
+
+// Replace capture quantifiers with the given quantifiers
+static void capture_quantifiers_replace(
+  CaptureQuantifiers *self,
+  CaptureQuantifiers *quantifiers
+) {
+  array_clear(self);
+  array_push_all(self, quantifiers);
+}
+
+// Return capture quantifier for the given capture id
+static TSQuantifier capture_quantifier_for_id(
+  const CaptureQuantifiers *self,
+  uint16_t id
+) {
+  return (self->size <= id) ? TSQuantifierZero : (TSQuantifier) *array_get(self, id);
+}
+
+// Add the given quantifier to the current value for id
+static void capture_quantifiers_add_for_id(
+  CaptureQuantifiers *self,
+  uint16_t id,
+  TSQuantifier quantifier
+) {
+  if (self->size <= id) {
+    array_grow_by(self, id + 1 - self->size);
+  }
+  uint8_t *own_quantifier = array_get(self, id);
+  *own_quantifier = (uint8_t) quantifier_add((TSQuantifier) *own_quantifier, quantifier);
+}
+
+// Point-wise add the given quantifiers to the current values
+static void capture_quantifiers_add_all(
+  CaptureQuantifiers *self,
+  CaptureQuantifiers *quantifiers
+) {
+  if (self->size < quantifiers->size) {
+    array_grow_by(self, quantifiers->size - self->size);
+  }
+  for (uint16_t id = 0; id < (uint16_t)quantifiers->size; id++) {
+    uint8_t *quantifier = array_get(quantifiers, id);
+    uint8_t *own_quantifier = array_get(self, id);
+    *own_quantifier = (uint8_t) quantifier_add((TSQuantifier) *own_quantifier, (TSQuantifier) *quantifier);
+  }
+}
+
+// Join the given quantifier with the current values
+static void capture_quantifiers_mul(
+  CaptureQuantifiers *self,
+  TSQuantifier quantifier
+) {
+  for (uint16_t id = 0; id < (uint16_t)self->size; id++) {
+    uint8_t *own_quantifier = array_get(self, id);
+    *own_quantifier = (uint8_t) quantifier_mul((TSQuantifier) *own_quantifier, quantifier);
+  }
+}
+
+// Point-wise join the quantifiers from a list of alternatives with the current values
+static void capture_quantifiers_join_all(
+  CaptureQuantifiers *self,
+  CaptureQuantifiers *quantifiers
+) {
+  if (self->size < quantifiers->size) {
+    array_grow_by(self, quantifiers->size - self->size);
+  }
+  for (uint32_t id = 0; id < quantifiers->size; id++) {
+    uint8_t *quantifier = array_get(quantifiers, id);
+    uint8_t *own_quantifier = array_get(self, id);
+    *own_quantifier = (uint8_t) quantifier_join((TSQuantifier) *own_quantifier, (TSQuantifier) *quantifier);
+  }
+  for (uint32_t id = quantifiers->size; id < self->size; id++) {
+    uint8_t *own_quantifier = array_get(self, id);
+    *own_quantifier = (uint8_t) quantifier_join((TSQuantifier) *own_quantifier, TSQuantifierZero);
+  }
+}
+
+/**************
+ * SymbolTable
+ **************/
+
+static SymbolTable symbol_table_new(void) {
+  return (SymbolTable) {
+    .characters = array_new(),
+    .slices = array_new(),
+  };
+}
+
+static void symbol_table_delete(SymbolTable *self) {
+  array_delete(&self->characters);
+  array_delete(&self->slices);
+}
+
+static int symbol_table_id_for_name(
+  const SymbolTable *self,
+  const char *name,
+  uint32_t length
+) {
+  for (unsigned i = 0; i < self->slices.size; i++) {
+    Slice slice = self->slices.contents[i];
+    if (
+      slice.length == length &&
+      !strncmp(&self->characters.contents[slice.offset], name, length)
+    ) return i;
+  }
+  return -1;
+}
+
+static const char *symbol_table_name_for_id(
+  const SymbolTable *self,
+  uint16_t id,
+  uint32_t *length
+) {
+  Slice slice = self->slices.contents[id];
+  *length = slice.length;
+  return &self->characters.contents[slice.offset];
+}
+
+static uint16_t symbol_table_insert_name(
+  SymbolTable *self,
+  const char *name,
+  uint32_t length
+) {
+  int id = symbol_table_id_for_name(self, name, length);
+  if (id >= 0) return (uint16_t)id;
+  Slice slice = {
+    .offset = self->characters.size,
+    .length = length,
+  };
+  array_grow_by(&self->characters, length + 1);
+  memcpy(&self->characters.contents[slice.offset], name, length);
+  self->characters.contents[self->characters.size - 1] = 0;
+  array_push(&self->slices, slice);
+  return self->slices.size - 1;
+}
+
+/************
+ * QueryStep
+ ************/
+
+static QueryStep query_step__new(
+  TSSymbol symbol,
+  uint16_t depth,
+  bool is_immediate
+) {
+  QueryStep step = {
+    .symbol = symbol,
+    .depth = depth,
+    .field = 0,
+    .alternative_index = NONE,
+    .negated_field_list_id = 0,
+    .contains_captures = false,
+    .is_last_child = false,
+    .is_named = false,
+    .is_pass_through = false,
+    .is_dead_end = false,
+    .root_pattern_guaranteed = false,
+    .is_immediate = is_immediate,
+    .alternative_is_immediate = false,
+  };
+  for (unsigned i = 0; i < MAX_STEP_CAPTURE_COUNT; i++) {
+    step.capture_ids[i] = NONE;
+  }
+  return step;
+}
+
+static void query_step__add_capture(QueryStep *self, uint16_t capture_id) {
+  for (unsigned i = 0; i < MAX_STEP_CAPTURE_COUNT; i++) {
+    if (self->capture_ids[i] == NONE) {
+      self->capture_ids[i] = capture_id;
+      break;
+    }
+  }
+}
+
+static void query_step__remove_capture(QueryStep *self, uint16_t capture_id) {
+  for (unsigned i = 0; i < MAX_STEP_CAPTURE_COUNT; i++) {
+    if (self->capture_ids[i] == capture_id) {
+      self->capture_ids[i] = NONE;
+      while (i + 1 < MAX_STEP_CAPTURE_COUNT) {
+        if (self->capture_ids[i + 1] == NONE) break;
+        self->capture_ids[i] = self->capture_ids[i + 1];
+        self->capture_ids[i + 1] = NONE;
+        i++;
+      }
+      break;
+    }
+  }
+}
+
+/**********************
+ * StatePredecessorMap
+ **********************/
+
+static inline StatePredecessorMap state_predecessor_map_new(
+  const TSLanguage *language
+) {
+  return (StatePredecessorMap) {
+    .contents = ts_calloc(
+      (size_t)language->state_count * (MAX_STATE_PREDECESSOR_COUNT + 1),
+      sizeof(TSStateId)
+    ),
+  };
+}
+
+static inline void state_predecessor_map_delete(StatePredecessorMap *self) {
+  ts_free(self->contents);
+}
+
+static inline void state_predecessor_map_add(
+  StatePredecessorMap *self,
+  TSStateId state,
+  TSStateId predecessor
+) {
+  size_t index = (size_t)state * (MAX_STATE_PREDECESSOR_COUNT + 1);
+  TSStateId *count = &self->contents[index];
+  if (
+    *count == 0 ||
+    (*count < MAX_STATE_PREDECESSOR_COUNT && self->contents[index + *count] != predecessor)
+  ) {
+    (*count)++;
+    self->contents[index + *count] = predecessor;
+  }
+}
+
+static inline const TSStateId *state_predecessor_map_get(
+  const StatePredecessorMap *self,
+  TSStateId state,
+  unsigned *count
+) {
+  size_t index = (size_t)state * (MAX_STATE_PREDECESSOR_COUNT + 1);
+  *count = self->contents[index];
+  return &self->contents[index + 1];
+}
+
+/****************
+ * AnalysisState
+ ****************/
+
+static unsigned analysis_state__recursion_depth(const AnalysisState *self) {
+  unsigned result = 0;
+  for (unsigned i = 0; i < self->depth; i++) {
+    TSSymbol symbol = self->stack[i].parent_symbol;
+    for (unsigned j = 0; j < i; j++) {
+      if (self->stack[j].parent_symbol == symbol) {
+        result++;
+        break;
+      }
+    }
+  }
+  return result;
+}
+
+static inline int analysis_state__compare_position(
+  AnalysisState *const *self,
+  AnalysisState *const *other
+) {
+  for (unsigned i = 0; i < (*self)->depth; i++) {
+    if (i >= (*other)->depth) return -1;
+    if ((*self)->stack[i].child_index < (*other)->stack[i].child_index) return -1;
+    if ((*self)->stack[i].child_index > (*other)->stack[i].child_index) return 1;
+  }
+  if ((*self)->depth < (*other)->depth) return 1;
+  if ((*self)->step_index < (*other)->step_index) return -1;
+  if ((*self)->step_index > (*other)->step_index) return 1;
+  return 0;
+}
+
+static inline int analysis_state__compare(
+  AnalysisState *const *self,
+  AnalysisState *const *other
+) {
+  int result = analysis_state__compare_position(self, other);
+  if (result != 0) return result;
+  for (unsigned i = 0; i < (*self)->depth; i++) {
+    if ((*self)->stack[i].parent_symbol < (*other)->stack[i].parent_symbol) return -1;
+    if ((*self)->stack[i].parent_symbol > (*other)->stack[i].parent_symbol) return 1;
+    if ((*self)->stack[i].parse_state < (*other)->stack[i].parse_state) return -1;
+    if ((*self)->stack[i].parse_state > (*other)->stack[i].parse_state) return 1;
+    if ((*self)->stack[i].field_id < (*other)->stack[i].field_id) return -1;
+    if ((*self)->stack[i].field_id > (*other)->stack[i].field_id) return 1;
+  }
+  return 0;
+}
+
+static inline AnalysisStateEntry *analysis_state__top(AnalysisState *self) {
+  if (self->depth == 0) {
+    return &self->stack[0];
+  }
+  return &self->stack[self->depth - 1];
+}
+
+static inline bool analysis_state__has_supertype(AnalysisState *self, TSSymbol symbol) {
+  for (unsigned i = 0; i < self->depth; i++) {
+    if (self->stack[i].parent_symbol == symbol) return true;
+  }
+  return false;
+}
+
+/******************
+ * AnalysisStateSet
+ ******************/
+
+// Obtains an `AnalysisState` instance, either by consuming one from this set's object pool, or by
+// cloning one from scratch.
+static inline AnalysisState *analysis_state_pool__clone_or_reuse(
+  AnalysisStateSet *self,
+  AnalysisState *borrowed_item
+) {
+  AnalysisState *new_item;
+  if (self->size) {
+    new_item = array_pop(self);
+  } else {
+    new_item = ts_malloc(sizeof(AnalysisState));
+  }
+  *new_item = *borrowed_item;
+  return new_item;
+}
+
+// Inserts a clone of the passed-in item at the appropriate position to maintain ordering in this
+// set. The set does not contain duplicates, so if the item is already present, it will not be
+// inserted, and no clone will be made.
+//
+// The caller retains ownership of the passed-in memory. However, the clone that is created by this
+// function will be managed by the state set.
+static inline void analysis_state_set__insert_sorted(
+  AnalysisStateSet *self,
+  AnalysisStateSet *pool,
+  AnalysisState *borrowed_item
+) {
+  unsigned index, exists;
+  array_search_sorted_with(self, analysis_state__compare, &borrowed_item, &index, &exists);
+  if (!exists) {
+    AnalysisState *new_item = analysis_state_pool__clone_or_reuse(pool, borrowed_item);
+    array_insert(self, index, new_item);
+  }
+}
+
+// Inserts a clone of the passed-in item at the end position of this list.
+//
+// IMPORTANT: The caller MUST ENSURE that this item is larger (by the comparison function
+// `analysis_state__compare`) than largest item already in this set. If items are inserted in the
+// wrong order, the set will not function properly for future use.
+//
+// The caller retains ownership of the passed-in memory. However, the clone that is created by this
+// function will be managed by the state set.
+static inline void analysis_state_set__push(
+  AnalysisStateSet *self,
+  AnalysisStateSet *pool,
+  AnalysisState *borrowed_item
+) {
+  AnalysisState *new_item = analysis_state_pool__clone_or_reuse(pool, borrowed_item);
+  array_push(self, new_item);
+}
+
+// Removes all items from this set, returning it to an empty state.
+static inline void analysis_state_set__clear(AnalysisStateSet *self, AnalysisStateSet *pool) {
+  array_push_all(pool, self);
+  array_clear(self);
+}
+
+// Releases all memory that is managed with this state set, including any items currently present.
+// After calling this function, the set is no longer suitable for use.
+static inline void analysis_state_set__delete(AnalysisStateSet *self) {
+  for (unsigned i = 0; i < self->size; i++) {
+    ts_free(self->contents[i]);
+  }
+  array_delete(self);
+}
+
+/****************
+ * QueryAnalyzer
+ ****************/
+
+static inline QueryAnalysis query_analysis__new(void) {
+  return (QueryAnalysis) {
+    .states = array_new(),
+    .next_states = array_new(),
+    .deeper_states = array_new(),
+    .state_pool = array_new(),
+    .final_step_indices = array_new(),
+    .finished_parent_symbols = array_new(),
+    .did_abort = false,
+  };
+}
+
+static inline void query_analysis__delete(QueryAnalysis *self) {
+  analysis_state_set__delete(&self->states);
+  analysis_state_set__delete(&self->next_states);
+  analysis_state_set__delete(&self->deeper_states);
+  analysis_state_set__delete(&self->state_pool);
+  array_delete(&self->final_step_indices);
+  array_delete(&self->finished_parent_symbols);
+}
+
+/***********************
+ * AnalysisSubgraphNode
+ ***********************/
+
+static inline int analysis_subgraph_node__compare(const AnalysisSubgraphNode *self, const AnalysisSubgraphNode *other) {
+  if (self->state < other->state) return -1;
+  if (self->state > other->state) return 1;
+  if (self->child_index < other->child_index) return -1;
+  if (self->child_index > other->child_index) return 1;
+  if (self->done < other->done) return -1;
+  if (self->done > other->done) return 1;
+  if (self->production_id < other->production_id) return -1;
+  if (self->production_id > other->production_id) return 1;
+  return 0;
+}
+
+/*********
+ * Query
+ *********/
+
+// The `pattern_map` contains a mapping from TSSymbol values to indices in the
+// `steps` array. For a given syntax node, the `pattern_map` makes it possible
+// to quickly find the starting steps of all of the patterns whose root matches
+// that node. Each entry has two fields: a `pattern_index`, which identifies one
+// of the patterns in the query, and a `step_index`, which indicates the start
+// offset of that pattern's steps within the `steps` array.
+//
+// The entries are sorted by the patterns' root symbols, and lookups use a
+// binary search. This ensures that the cost of this initial lookup step
+// scales logarithmically with the number of patterns in the query.
+//
+// This returns `true` if the symbol is present and `false` otherwise.
+// If the symbol is not present `*result` is set to the index where the
+// symbol should be inserted.
+static inline bool ts_query__pattern_map_search(
+  const TSQuery *self,
+  TSSymbol needle,
+  uint32_t *result
+) {
+  uint32_t base_index = self->wildcard_root_pattern_count;
+  uint32_t size = self->pattern_map.size - base_index;
+  if (size == 0) {
+    *result = base_index;
+    return false;
+  }
+  while (size > 1) {
+    uint32_t half_size = size / 2;
+    uint32_t mid_index = base_index + half_size;
+    TSSymbol mid_symbol = self->steps.contents[
+      self->pattern_map.contents[mid_index].step_index
+    ].symbol;
+    if (needle > mid_symbol) base_index = mid_index;
+    size -= half_size;
+  }
+
+  TSSymbol symbol = self->steps.contents[
+    self->pattern_map.contents[base_index].step_index
+  ].symbol;
+
+  if (needle > symbol) {
+    base_index++;
+    if (base_index < self->pattern_map.size) {
+      symbol = self->steps.contents[
+        self->pattern_map.contents[base_index].step_index
+      ].symbol;
+    }
+  }
+
+  *result = base_index;
+  return needle == symbol;
+}
+
+// Insert a new pattern's start index into the pattern map, maintaining
+// the pattern map's ordering invariant.
+static inline void ts_query__pattern_map_insert(
+  TSQuery *self,
+  TSSymbol symbol,
+  PatternEntry new_entry
+) {
+  uint32_t index;
+  ts_query__pattern_map_search(self, symbol, &index);
+
+  // Ensure that the entries are sorted not only by symbol, but also
+  // by pattern_index. This way, states for earlier patterns will be
+  // initiated first, which allows the ordering of the states array
+  // to be maintained more efficiently.
+  while (index < self->pattern_map.size) {
+    PatternEntry *entry = &self->pattern_map.contents[index];
+    if (
+      self->steps.contents[entry->step_index].symbol == symbol &&
+      entry->pattern_index < new_entry.pattern_index
+    ) {
+      index++;
+    } else {
+      break;
+    }
+  }
+
+  array_insert(&self->pattern_map, index, new_entry);
+}
+
+// Walk the subgraph for this non-terminal, tracking all of the possible
+// sequences of progress within the pattern.
+static void ts_query__perform_analysis(
+  TSQuery *self,
+  const AnalysisSubgraphArray *subgraphs,
+  QueryAnalysis *analysis
+) {
+  unsigned recursion_depth_limit = 0;
+  unsigned prev_final_step_count = 0;
+  array_clear(&analysis->final_step_indices);
+  array_clear(&analysis->finished_parent_symbols);
+
+  for (unsigned iteration = 0;; iteration++) {
+    if (iteration == MAX_ANALYSIS_ITERATION_COUNT) {
+      analysis->did_abort = true;
+      break;
+    }
+
+    #ifdef DEBUG_ANALYZE_QUERY
+      printf("Iteration: %u. Final step indices:", iteration);
+      for (unsigned j = 0; j < analysis->final_step_indices.size; j++) {
+        printf(" %4u", analysis->final_step_indices.contents[j]);
+      }
+      printf("\n");
+      for (unsigned j = 0; j < analysis->states.size; j++) {
+        AnalysisState *state = analysis->states.contents[j];
+        printf("  %3u: step: %u, stack: [", j, state->step_index);
+        for (unsigned k = 0; k < state->depth; k++) {
+          printf(
+            " {%s, child: %u, state: %4u",
+            self->language->symbol_names[state->stack[k].parent_symbol],
+            state->stack[k].child_index,
+            state->stack[k].parse_state
+          );
+          if (state->stack[k].field_id) printf(", field: %s", self->language->field_names[state->stack[k].field_id]);
+          if (state->stack[k].done) printf(", DONE");
+          printf("}");
+        }
+        printf(" ]\n");
+      }
+    #endif
+
+    // If no further progress can be made within the current recursion depth limit, then
+    // bump the depth limit by one, and continue to process the states the exceeded the
+    // limit. But only allow this if progress has been made since the last time the depth
+    // limit was increased.
+    if (analysis->states.size == 0) {
+      if (
+        analysis->deeper_states.size > 0 &&
+        analysis->final_step_indices.size > prev_final_step_count
+      ) {
+        #ifdef DEBUG_ANALYZE_QUERY
+          printf("Increase recursion depth limit to %u\n", recursion_depth_limit + 1);
+        #endif
+
+        prev_final_step_count = analysis->final_step_indices.size;
+        recursion_depth_limit++;
+        AnalysisStateSet _states = analysis->states;
+        analysis->states = analysis->deeper_states;
+        analysis->deeper_states = _states;
+        continue;
+      }
+
+      break;
+    }
+
+    analysis_state_set__clear(&analysis->next_states, &analysis->state_pool);
+    for (unsigned j = 0; j < analysis->states.size; j++) {
+      AnalysisState * const state = analysis->states.contents[j];
+
+      // For efficiency, it's important to avoid processing the same analysis state more
+      // than once. To achieve this, keep the states in order of ascending position within
+      // their hypothetical syntax trees. In each iteration of this loop, start by advancing
+      // the states that have made the least progress. Avoid advancing states that have already
+      // made more progress.
+      if (analysis->next_states.size > 0) {
+        int comparison = analysis_state__compare_position(
+          &state,
+          array_back(&analysis->next_states)
+        );
+        if (comparison == 0) {
+          analysis_state_set__insert_sorted(&analysis->next_states, &analysis->state_pool, state);
+          continue;
+        } else if (comparison > 0) {
+          #ifdef DEBUG_ANALYZE_QUERY
+            printf("Terminate iteration at state %u\n", j);
+          #endif
+          while (j < analysis->states.size) {
+            analysis_state_set__push(
+              &analysis->next_states,
+              &analysis->state_pool,
+              analysis->states.contents[j]
+            );
+            j++;
+          }
+          break;
+        }
+      }
+
+      const TSStateId parse_state = analysis_state__top(state)->parse_state;
+      const TSSymbol parent_symbol = analysis_state__top(state)->parent_symbol;
+      const TSFieldId parent_field_id = analysis_state__top(state)->field_id;
+      const unsigned child_index = analysis_state__top(state)->child_index;
+      const QueryStep * const step = &self->steps.contents[state->step_index];
+
+      unsigned subgraph_index, exists;
+      array_search_sorted_by(subgraphs, .symbol, parent_symbol, &subgraph_index, &exists);
+      if (!exists) continue;
+      const AnalysisSubgraph *subgraph = &subgraphs->contents[subgraph_index];
+
+      // Follow every possible path in the parse table, but only visit states that
+      // are part of the subgraph for the current symbol.
+      LookaheadIterator lookahead_iterator = ts_language_lookaheads(self->language, parse_state);
+      while (ts_lookahead_iterator__next(&lookahead_iterator)) {
+        TSSymbol sym = lookahead_iterator.symbol;
+
+        AnalysisSubgraphNode successor = {
+          .state = parse_state,
+          .child_index = child_index,
+        };
+        if (lookahead_iterator.action_count) {
+          const TSParseAction *action = &lookahead_iterator.actions[lookahead_iterator.action_count - 1];
+          if (action->type == TSParseActionTypeShift) {
+            if (!action->shift.extra) {
+              successor.state = action->shift.state;
+              successor.child_index++;
+            }
+          } else {
+            continue;
+          }
+        } else if (lookahead_iterator.next_state != 0) {
+          successor.state = lookahead_iterator.next_state;
+          successor.child_index++;
+        } else {
+          continue;
+        }
+
+        unsigned node_index;
+        array_search_sorted_with(
+          &subgraph->nodes,
+          analysis_subgraph_node__compare, &successor,
+          &node_index, &exists
+        );
+        while (node_index < subgraph->nodes.size) {
+          AnalysisSubgraphNode *node = &subgraph->nodes.contents[node_index++];
+          if (node->state != successor.state || node->child_index != successor.child_index) break;
+
+          // Use the subgraph to determine what alias and field will eventually be applied
+          // to this child node.
+          TSSymbol alias = ts_language_alias_at(self->language, node->production_id, child_index);
+          TSSymbol visible_symbol = alias
+            ? alias
+            : self->language->symbol_metadata[sym].visible
+              ? self->language->public_symbol_map[sym]
+              : 0;
+          TSFieldId field_id = parent_field_id;
+          if (!field_id) {
+            const TSFieldMapEntry *field_map, *field_map_end;
+            ts_language_field_map(self->language, node->production_id, &field_map, &field_map_end);
+            for (; field_map != field_map_end; field_map++) {
+              if (!field_map->inherited && field_map->child_index == child_index) {
+                field_id = field_map->field_id;
+                break;
+              }
+            }
+          }
+
+          // Create a new state that has advanced past this hypothetical subtree.
+          AnalysisState next_state = *state;
+          AnalysisStateEntry *next_state_top = analysis_state__top(&next_state);
+          next_state_top->child_index = successor.child_index;
+          next_state_top->parse_state = successor.state;
+          if (node->done) next_state_top->done = true;
+
+          // Determine if this hypothetical child node would match the current step
+          // of the query pattern.
+          bool does_match = false;
+          if (visible_symbol) {
+            does_match = true;
+            if (step->symbol == WILDCARD_SYMBOL) {
+              if (
+                step->is_named &&
+                !self->language->symbol_metadata[visible_symbol].named
+              ) does_match = false;
+            } else if (step->symbol != visible_symbol) {
+              does_match = false;
+            }
+            if (step->field && step->field != field_id) {
+              does_match = false;
+            }
+            if (
+              step->supertype_symbol &&
+              !analysis_state__has_supertype(state, step->supertype_symbol)
+            ) does_match = false;
+          }
+
+          // If this child is hidden, then descend into it and walk through its children.
+          // If the top entry of the stack is at the end of its rule, then that entry can
+          // be replaced. Otherwise, push a new entry onto the stack.
+          else if (sym >= self->language->token_count) {
+            if (!next_state_top->done) {
+              if (next_state.depth + 1 >= MAX_ANALYSIS_STATE_DEPTH) {
+                #ifdef DEBUG_ANALYZE_QUERY
+                  printf("Exceeded depth limit for state %u\n", j);
+                #endif
+
+                analysis->did_abort = true;
+                continue;
+              }
+
+              next_state.depth++;
+              next_state_top = analysis_state__top(&next_state);
+            }
+
+            *next_state_top = (AnalysisStateEntry) {
+              .parse_state = parse_state,
+              .parent_symbol = sym,
+              .child_index = 0,
+              .field_id = field_id,
+              .done = false,
+            };
+
+            if (analysis_state__recursion_depth(&next_state) > recursion_depth_limit) {
+              analysis_state_set__insert_sorted(
+                &analysis->deeper_states,
+                &analysis->state_pool,
+                &next_state
+              );
+              continue;
+            }
+          }
+
+          // Pop from the stack when this state reached the end of its current syntax node.
+          while (next_state.depth > 0 && next_state_top->done) {
+            next_state.depth--;
+            next_state_top = analysis_state__top(&next_state);
+          }
+
+          // If this hypothetical child did match the current step of the query pattern,
+          // then advance to the next step at the current depth. This involves skipping
+          // over any descendant steps of the current child.
+          const QueryStep *next_step = step;
+          if (does_match) {
+            for (;;) {
+              next_state.step_index++;
+              next_step = &self->steps.contents[next_state.step_index];
+              if (
+                next_step->depth == PATTERN_DONE_MARKER ||
+                next_step->depth <= step->depth
+              ) break;
+            }
+          } else if (successor.state == parse_state) {
+            continue;
+          }
+
+          for (;;) {
+            // Skip pass-through states. Although these states have alternatives, they are only
+            // used to implement repetitions, and query analysis does not need to process
+            // repetitions in order to determine whether steps are possible and definite.
+            if (next_step->is_pass_through) {
+              next_state.step_index++;
+              next_step++;
+              continue;
+            }
+
+            // If the pattern is finished or hypothetical parent node is complete, then
+            // record that matching can terminate at this step of the pattern. Otherwise,
+            // add this state to the list of states to process on the next iteration.
+            if (!next_step->is_dead_end) {
+              bool did_finish_pattern = self->steps.contents[next_state.step_index].depth != step->depth;
+              if (did_finish_pattern) {
+                array_insert_sorted_by(&analysis->finished_parent_symbols, , state->root_symbol);
+              } else if (next_state.depth == 0) {
+                array_insert_sorted_by(&analysis->final_step_indices, , next_state.step_index);
+              } else {
+                analysis_state_set__insert_sorted(&analysis->next_states, &analysis->state_pool, &next_state);
+              }
+            }
+
+            // If the state has advanced to a step with an alternative step, then add another state
+            // at that alternative step. This process is simpler than the process of actually matching a
+            // pattern during query execution, because for the purposes of query analysis, there is no
+            // need to process repetitions.
+            if (
+              does_match &&
+              next_step->alternative_index != NONE &&
+              next_step->alternative_index > next_state.step_index
+            ) {
+              next_state.step_index = next_step->alternative_index;
+              next_step = &self->steps.contents[next_state.step_index];
+            } else {
+              break;
+            }
+          }
+        }
+      }
+    }
+
+    AnalysisStateSet _states = analysis->states;
+    analysis->states = analysis->next_states;
+    analysis->next_states = _states;
+  }
+}
+
+static bool ts_query__analyze_patterns(TSQuery *self, unsigned *error_offset) {
+  Array(uint16_t) non_rooted_pattern_start_steps = array_new();
+  for (unsigned i = 0; i < self->pattern_map.size; i++) {
+    PatternEntry *pattern = &self->pattern_map.contents[i];
+    if (!pattern->is_rooted) {
+      QueryStep *step = &self->steps.contents[pattern->step_index];
+      if (step->symbol != WILDCARD_SYMBOL) {
+        array_push(&non_rooted_pattern_start_steps, i);
+      }
+    }
+  }
+
+  // Walk forward through all of the steps in the query, computing some
+  // basic information about each step. Mark all of the steps that contain
+  // captures, and record the indices of all of the steps that have child steps.
+  Array(uint32_t) parent_step_indices = array_new();
+  for (unsigned i = 0; i < self->steps.size; i++) {
+    QueryStep *step = &self->steps.contents[i];
+    if (step->depth == PATTERN_DONE_MARKER) {
+      step->parent_pattern_guaranteed = true;
+      step->root_pattern_guaranteed = true;
+      continue;
+    }
+
+    bool has_children = false;
+    bool is_wildcard = step->symbol == WILDCARD_SYMBOL;
+    step->contains_captures = step->capture_ids[0] != NONE;
+    for (unsigned j = i + 1; j < self->steps.size; j++) {
+      QueryStep *next_step = &self->steps.contents[j];
+      if (
+        next_step->depth == PATTERN_DONE_MARKER ||
+        next_step->depth <= step->depth
+      ) break;
+      if (next_step->capture_ids[0] != NONE) {
+        step->contains_captures = true;
+      }
+      if (!is_wildcard) {
+        next_step->root_pattern_guaranteed = true;
+        next_step->parent_pattern_guaranteed = true;
+      }
+      has_children = true;
+    }
+
+    if (has_children && !is_wildcard) {
+      array_push(&parent_step_indices, i);
+    }
+  }
+
+  // For every parent symbol in the query, initialize an 'analysis subgraph'.
+  // This subgraph lists all of the states in the parse table that are directly
+  // involved in building subtrees for this symbol.
+  //
+  // In addition to the parent symbols in the query, construct subgraphs for all
+  // of the hidden symbols in the grammar, because these might occur within
+  // one of the parent nodes, such that their children appear to belong to the
+  // parent.
+  AnalysisSubgraphArray subgraphs = array_new();
+  for (unsigned i = 0; i < parent_step_indices.size; i++) {
+    uint32_t parent_step_index = parent_step_indices.contents[i];
+    TSSymbol parent_symbol = self->steps.contents[parent_step_index].symbol;
+    AnalysisSubgraph subgraph = { .symbol = parent_symbol };
+    array_insert_sorted_by(&subgraphs, .symbol, subgraph);
+  }
+  for (TSSymbol sym = (uint16_t)self->language->token_count; sym < (uint16_t)self->language->symbol_count; sym++) {
+    if (!ts_language_symbol_metadata(self->language, sym).visible) {
+      AnalysisSubgraph subgraph = { .symbol = sym };
+      array_insert_sorted_by(&subgraphs, .symbol, subgraph);
+    }
+  }
+
+  // Scan the parse table to find the data needed to populate these subgraphs.
+  // Collect three things during this scan:
+  //   1) All of the parse states where one of these symbols can start.
+  //   2) All of the parse states where one of these symbols can end, along
+  //      with information about the node that would be created.
+  //   3) A list of predecessor states for each state.
+  StatePredecessorMap predecessor_map = state_predecessor_map_new(self->language);
+  for (TSStateId state = 1; state < (uint16_t)self->language->state_count; state++) {
+    unsigned subgraph_index, exists;
+    LookaheadIterator lookahead_iterator = ts_language_lookaheads(self->language, state);
+    while (ts_lookahead_iterator__next(&lookahead_iterator)) {
+      if (lookahead_iterator.action_count) {
+        for (unsigned i = 0; i < lookahead_iterator.action_count; i++) {
+          const TSParseAction *action = &lookahead_iterator.actions[i];
+          if (action->type == TSParseActionTypeReduce) {
+            const TSSymbol *aliases, *aliases_end;
+            ts_language_aliases_for_symbol(
+              self->language,
+              action->reduce.symbol,
+              &aliases,
+              &aliases_end
+            );
+            for (const TSSymbol *symbol = aliases; symbol < aliases_end; symbol++) {
+              array_search_sorted_by(
+                &subgraphs,
+                .symbol,
+                *symbol,
+                &subgraph_index,
+                &exists
+              );
+              if (exists) {
+                AnalysisSubgraph *subgraph = &subgraphs.contents[subgraph_index];
+                if (subgraph->nodes.size == 0 || array_back(&subgraph->nodes)->state != state) {
+                  array_push(&subgraph->nodes, ((AnalysisSubgraphNode) {
+                    .state = state,
+                    .production_id = action->reduce.production_id,
+                    .child_index = action->reduce.child_count,
+                    .done = true,
+                  }));
+                }
+              }
+            }
+          } else if (action->type == TSParseActionTypeShift && !action->shift.extra) {
+            TSStateId next_state = action->shift.state;
+            state_predecessor_map_add(&predecessor_map, next_state, state);
+          }
+        }
+      } else if (lookahead_iterator.next_state != 0) {
+        if (lookahead_iterator.next_state != state) {
+          state_predecessor_map_add(&predecessor_map, lookahead_iterator.next_state, state);
+        }
+        if (ts_language_state_is_primary(self->language, state)) {
+          const TSSymbol *aliases, *aliases_end;
+          ts_language_aliases_for_symbol(
+            self->language,
+            lookahead_iterator.symbol,
+            &aliases,
+            &aliases_end
+          );
+          for (const TSSymbol *symbol = aliases; symbol < aliases_end; symbol++) {
+            array_search_sorted_by(
+              &subgraphs,
+              .symbol,
+              *symbol,
+              &subgraph_index,
+              &exists
+            );
+            if (exists) {
+              AnalysisSubgraph *subgraph = &subgraphs.contents[subgraph_index];
+              if (
+                subgraph->start_states.size == 0 ||
+                *array_back(&subgraph->start_states) != state
+              )
+              array_push(&subgraph->start_states, state);
+            }
+          }
+        }
+      }
+    }
+  }
+
+  // For each subgraph, compute the preceding states by walking backward
+  // from the end states using the predecessor map.
+  Array(AnalysisSubgraphNode) next_nodes = array_new();
+  for (unsigned i = 0; i < subgraphs.size; i++) {
+    AnalysisSubgraph *subgraph = &subgraphs.contents[i];
+    if (subgraph->nodes.size == 0) {
+      array_delete(&subgraph->start_states);
+      array_erase(&subgraphs, i);
+      i--;
+      continue;
+    }
+    array_assign(&next_nodes, &subgraph->nodes);
+    while (next_nodes.size > 0) {
+      AnalysisSubgraphNode node = array_pop(&next_nodes);
+      if (node.child_index > 1) {
+        unsigned predecessor_count;
+        const TSStateId *predecessors = state_predecessor_map_get(
+          &predecessor_map,
+          node.state,
+          &predecessor_count
+        );
+        for (unsigned j = 0; j < predecessor_count; j++) {
+          AnalysisSubgraphNode predecessor_node = {
+            .state = predecessors[j],
+            .child_index = node.child_index - 1,
+            .production_id = node.production_id,
+            .done = false,
+          };
+          unsigned index, exists;
+          array_search_sorted_with(
+            &subgraph->nodes, analysis_subgraph_node__compare, &predecessor_node,
+            &index, &exists
+          );
+          if (!exists) {
+            array_insert(&subgraph->nodes, index, predecessor_node);
+            array_push(&next_nodes, predecessor_node);
+          }
+        }
+      }
+    }
+  }
+
+  #ifdef DEBUG_ANALYZE_QUERY
+    printf("\nSubgraphs:\n");
+    for (unsigned i = 0; i < subgraphs.size; i++) {
+      AnalysisSubgraph *subgraph = &subgraphs.contents[i];
+      printf("  %u, %s:\n", subgraph->symbol, ts_language_symbol_name(self->language, subgraph->symbol));
+      for (unsigned j = 0; j < subgraph->start_states.size; j++) {
+        printf(
+          "    {state: %u}\n",
+          subgraph->start_states.contents[j]
+        );
+      }
+      for (unsigned j = 0; j < subgraph->nodes.size; j++) {
+        AnalysisSubgraphNode *node = &subgraph->nodes.contents[j];
+        printf(
+          "    {state: %u, child_index: %u, production_id: %u, done: %d}\n",
+          node->state, node->child_index, node->production_id, node->done
+        );
+      }
+      printf("\n");
+    }
+  #endif
+
+  // For each non-terminal pattern, determine if the pattern can successfully match,
+  // and identify all of the possible children within the pattern where matching could fail.
+  bool all_patterns_are_valid = true;
+  QueryAnalysis analysis = query_analysis__new();
+  for (unsigned i = 0; i < parent_step_indices.size; i++) {
+    uint16_t parent_step_index = parent_step_indices.contents[i];
+    uint16_t parent_depth = self->steps.contents[parent_step_index].depth;
+    TSSymbol parent_symbol = self->steps.contents[parent_step_index].symbol;
+    if (parent_symbol == ts_builtin_sym_error) continue;
+
+    // Find the subgraph that corresponds to this pattern's root symbol. If the pattern's
+    // root symbol is a terminal, then return an error.
+    unsigned subgraph_index, exists;
+    array_search_sorted_by(&subgraphs, .symbol, parent_symbol, &subgraph_index, &exists);
+    if (!exists) {
+      unsigned first_child_step_index = parent_step_index + 1;
+      uint32_t j, child_exists;
+      array_search_sorted_by(&self->step_offsets, .step_index, first_child_step_index, &j, &child_exists);
+      ts_assert(child_exists);
+      *error_offset = self->step_offsets.contents[j].byte_offset;
+      all_patterns_are_valid = false;
+      break;
+    }
+
+    // Initialize an analysis state at every parse state in the table where
+    // this parent symbol can occur.
+    AnalysisSubgraph *subgraph = &subgraphs.contents[subgraph_index];
+    analysis_state_set__clear(&analysis.states, &analysis.state_pool);
+    analysis_state_set__clear(&analysis.deeper_states, &analysis.state_pool);
+    for (unsigned j = 0; j < subgraph->start_states.size; j++) {
+      TSStateId parse_state = subgraph->start_states.contents[j];
+      analysis_state_set__push(&analysis.states, &analysis.state_pool, &((AnalysisState) {
+        .step_index = parent_step_index + 1,
+        .stack = {
+          [0] = {
+            .parse_state = parse_state,
+            .parent_symbol = parent_symbol,
+            .child_index = 0,
+            .field_id = 0,
+            .done = false,
+          },
+        },
+        .depth = 1,
+        .root_symbol = parent_symbol,
+      }));
+    }
+
+    #ifdef DEBUG_ANALYZE_QUERY
+      printf(
+        "\nWalk states for %s:\n",
+        ts_language_symbol_name(self->language, analysis.states.contents[0]->stack[0].parent_symbol)
+      );
+    #endif
+
+    analysis.did_abort = false;
+    ts_query__perform_analysis(self, &subgraphs, &analysis);
+
+    // If this pattern could not be fully analyzed, then every step should
+    // be considered fallible.
+    if (analysis.did_abort) {
+      for (unsigned j = parent_step_index + 1; j < self->steps.size; j++) {
+        QueryStep *step = &self->steps.contents[j];
+        if (
+          step->depth <= parent_depth ||
+          step->depth == PATTERN_DONE_MARKER
+        ) break;
+        if (!step->is_dead_end) {
+          step->parent_pattern_guaranteed = false;
+          step->root_pattern_guaranteed = false;
+        }
+      }
+      continue;
+    }
+
+    // If this pattern cannot match, store the pattern index so that it can be
+    // returned to the caller.
+    if (analysis.finished_parent_symbols.size == 0) {
+      ts_assert(analysis.final_step_indices.size > 0);
+      uint16_t impossible_step_index = *array_back(&analysis.final_step_indices);
+      uint32_t j, impossible_exists;
+      array_search_sorted_by(&self->step_offsets, .step_index, impossible_step_index, &j, &impossible_exists);
+      if (j >= self->step_offsets.size) j = self->step_offsets.size - 1;
+      *error_offset = self->step_offsets.contents[j].byte_offset;
+      all_patterns_are_valid = false;
+      break;
+    }
+
+    // Mark as fallible any step where a match terminated.
+    // Later, this property will be propagated to all of the step's predecessors.
+    for (unsigned j = 0; j < analysis.final_step_indices.size; j++) {
+      uint32_t final_step_index = analysis.final_step_indices.contents[j];
+      QueryStep *step = &self->steps.contents[final_step_index];
+      if (
+        step->depth != PATTERN_DONE_MARKER &&
+        step->depth > parent_depth &&
+        !step->is_dead_end
+      ) {
+        step->parent_pattern_guaranteed = false;
+        step->root_pattern_guaranteed = false;
+      }
+    }
+  }
+
+  // Mark as indefinite any step with captures that are used in predicates.
+  Array(uint16_t) predicate_capture_ids = array_new();
+  for (unsigned i = 0; i < self->patterns.size; i++) {
+    QueryPattern *pattern = &self->patterns.contents[i];
+
+    // Gather all of the captures that are used in predicates for this pattern.
+    array_clear(&predicate_capture_ids);
+    for (
+      unsigned start = pattern->predicate_steps.offset,
+      end = start + pattern->predicate_steps.length,
+      j = start; j < end; j++
+    ) {
+      TSQueryPredicateStep *step = &self->predicate_steps.contents[j];
+      if (step->type == TSQueryPredicateStepTypeCapture) {
+        uint16_t value_id = step->value_id;
+        array_insert_sorted_by(&predicate_capture_ids, , value_id);
+      }
+    }
+
+    // Find all of the steps that have these captures.
+    for (
+      unsigned start = pattern->steps.offset,
+      end = start + pattern->steps.length,
+      j = start; j < end; j++
+    ) {
+      QueryStep *step = &self->steps.contents[j];
+      for (unsigned k = 0; k < MAX_STEP_CAPTURE_COUNT; k++) {
+        uint16_t capture_id = step->capture_ids[k];
+        if (capture_id == NONE) break;
+        unsigned index, exists;
+        array_search_sorted_by(&predicate_capture_ids, , capture_id, &index, &exists);
+        if (exists) {
+          step->root_pattern_guaranteed = false;
+          break;
+        }
+      }
+    }
+  }
+
+  // Propagate fallibility. If a pattern is fallible at a given step, then it is
+  // fallible at all of its preceding steps.
+  bool done = self->steps.size == 0;
+  while (!done) {
+    done = true;
+    for (unsigned i = self->steps.size - 1; i > 0; i--) {
+      QueryStep *step = &self->steps.contents[i];
+      if (step->depth == PATTERN_DONE_MARKER) continue;
+
+      // Determine if this step is definite or has definite alternatives.
+      bool parent_pattern_guaranteed = false;
+      for (;;) {
+        if (step->root_pattern_guaranteed) {
+          parent_pattern_guaranteed = true;
+          break;
+        }
+        if (step->alternative_index == NONE || step->alternative_index < i) {
+          break;
+        }
+        step = &self->steps.contents[step->alternative_index];
+      }
+
+      // If not, mark its predecessor as indefinite.
+      if (!parent_pattern_guaranteed) {
+        QueryStep *prev_step = &self->steps.contents[i - 1];
+        if (
+          !prev_step->is_dead_end &&
+          prev_step->depth != PATTERN_DONE_MARKER &&
+          prev_step->root_pattern_guaranteed
+        ) {
+          prev_step->root_pattern_guaranteed = false;
+          done = false;
+        }
+      }
+    }
+  }
+
+  #ifdef DEBUG_ANALYZE_QUERY
+    printf("Steps:\n");
+    for (unsigned i = 0; i < self->steps.size; i++) {
+      QueryStep *step = &self->steps.contents[i];
+      if (step->depth == PATTERN_DONE_MARKER) {
+        printf("  %u: DONE\n", i);
+      } else {
+        printf(
+          "  %u: {symbol: %s, field: %s, depth: %u, parent_pattern_guaranteed: %d, root_pattern_guaranteed: %d}\n",
+          i,
+          (step->symbol == WILDCARD_SYMBOL)
+            ? "ANY"
+            : ts_language_symbol_name(self->language, step->symbol),
+          (step->field ? ts_language_field_name_for_id(self->language, step->field) : "-"),
+          step->depth,
+          step->parent_pattern_guaranteed,
+          step->root_pattern_guaranteed
+        );
+      }
+    }
+  #endif
+
+  // Determine which repetition symbols in this language have the possibility
+  // of matching non-rooted patterns in this query. These repetition symbols
+  // prevent certain optimizations with range restrictions.
+  analysis.did_abort = false;
+  for (uint32_t i = 0; i < non_rooted_pattern_start_steps.size; i++) {
+    uint16_t pattern_entry_index = non_rooted_pattern_start_steps.contents[i];
+    PatternEntry *pattern_entry = &self->pattern_map.contents[pattern_entry_index];
+
+    analysis_state_set__clear(&analysis.states, &analysis.state_pool);
+    analysis_state_set__clear(&analysis.deeper_states, &analysis.state_pool);
+    for (unsigned j = 0; j < subgraphs.size; j++) {
+      AnalysisSubgraph *subgraph = &subgraphs.contents[j];
+      TSSymbolMetadata metadata = ts_language_symbol_metadata(self->language, subgraph->symbol);
+      if (metadata.visible || metadata.named) continue;
+
+      for (uint32_t k = 0; k < subgraph->start_states.size; k++) {
+        TSStateId parse_state = subgraph->start_states.contents[k];
+        analysis_state_set__push(&analysis.states, &analysis.state_pool, &((AnalysisState) {
+          .step_index = pattern_entry->step_index,
+          .stack = {
+            [0] = {
+              .parse_state = parse_state,
+              .parent_symbol = subgraph->symbol,
+              .child_index = 0,
+              .field_id = 0,
+              .done = false,
+            },
+          },
+          .root_symbol = subgraph->symbol,
+          .depth = 1,
+        }));
+      }
+    }
+
+    #ifdef DEBUG_ANALYZE_QUERY
+      printf("\nWalk states for rootless pattern step %u:\n", pattern_entry->step_index);
+    #endif
+
+    ts_query__perform_analysis(
+      self,
+      &subgraphs,
+      &analysis
+    );
+
+    if (analysis.finished_parent_symbols.size > 0) {
+      self->patterns.contents[pattern_entry->pattern_index].is_non_local = true;
+    }
+
+    for (unsigned k = 0; k < analysis.finished_parent_symbols.size; k++) {
+      TSSymbol symbol = analysis.finished_parent_symbols.contents[k];
+      array_insert_sorted_by(&self->repeat_symbols_with_rootless_patterns, , symbol);
+    }
+  }
+
+  #ifdef DEBUG_ANALYZE_QUERY
+    if (self->repeat_symbols_with_rootless_patterns.size > 0) {
+      printf("\nRepetition symbols with rootless patterns:\n");
+      printf("aborted analysis: %d\n", analysis.did_abort);
+      for (unsigned i = 0; i < self->repeat_symbols_with_rootless_patterns.size; i++) {
+        TSSymbol symbol = self->repeat_symbols_with_rootless_patterns.contents[i];
+        printf("  %u, %s\n", symbol, ts_language_symbol_name(self->language, symbol));
+      }
+      printf("\n");
+    }
+  #endif
+
+  // Cleanup
+  for (unsigned i = 0; i < subgraphs.size; i++) {
+    array_delete(&subgraphs.contents[i].start_states);
+    array_delete(&subgraphs.contents[i].nodes);
+  }
+  array_delete(&subgraphs);
+  query_analysis__delete(&analysis);
+  array_delete(&next_nodes);
+  array_delete(&non_rooted_pattern_start_steps);
+  array_delete(&parent_step_indices);
+  array_delete(&predicate_capture_ids);
+  state_predecessor_map_delete(&predecessor_map);
+
+  return all_patterns_are_valid;
+}
+
+static void ts_query__add_negated_fields(
+  TSQuery *self,
+  uint16_t step_index,
+  TSFieldId *field_ids,
+  uint16_t field_count
+) {
+  QueryStep *step = &self->steps.contents[step_index];
+
+  // The negated field array stores a list of field lists, separated by zeros.
+  // Try to find the start index of an existing list that matches this new list.
+  bool failed_match = false;
+  unsigned match_count = 0;
+  unsigned start_i = 0;
+  for (unsigned i = 0; i < self->negated_fields.size; i++) {
+    TSFieldId existing_field_id = self->negated_fields.contents[i];
+
+    // At each zero value, terminate the match attempt. If we've exactly
+    // matched the new field list, then reuse this index. Otherwise,
+    // start over the matching process.
+    if (existing_field_id == 0) {
+      if (match_count == field_count) {
+        step->negated_field_list_id = start_i;
+        return;
+      } else {
+        start_i = i + 1;
+        match_count = 0;
+        failed_match = false;
+      }
+    }
+
+    // If the existing list matches our new list so far, then advance
+    // to the next element of the new list.
+    else if (
+      match_count < field_count &&
+      existing_field_id == field_ids[match_count] &&
+      !failed_match
+    ) {
+      match_count++;
+    }
+
+    // Otherwise, this existing list has failed to match.
+    else {
+      match_count = 0;
+      failed_match = true;
+    }
+  }
+
+  step->negated_field_list_id = self->negated_fields.size;
+  array_extend(&self->negated_fields, field_count, field_ids);
+  array_push(&self->negated_fields, 0);
+}
+
+static TSQueryError ts_query__parse_string_literal(
+  TSQuery *self,
+  Stream *stream
+) {
+  const char *string_start = stream->input;
+  if (stream->next != '"') return TSQueryErrorSyntax;
+  stream_advance(stream);
+  const char *prev_position = stream->input;
+
+  bool is_escaped = false;
+  array_clear(&self->string_buffer);
+  for (;;) {
+    if (is_escaped) {
+      is_escaped = false;
+      switch (stream->next) {
+        case 'n':
+          array_push(&self->string_buffer, '\n');
+          break;
+        case 'r':
+          array_push(&self->string_buffer, '\r');
+          break;
+        case 't':
+          array_push(&self->string_buffer, '\t');
+          break;
+        case '0':
+          array_push(&self->string_buffer, '\0');
+          break;
+        default:
+          array_extend(&self->string_buffer, stream->next_size, stream->input);
+          break;
+      }
+      prev_position = stream->input + stream->next_size;
+    } else {
+      if (stream->next == '\\') {
+        array_extend(&self->string_buffer, (uint32_t)(stream->input - prev_position), prev_position);
+        prev_position = stream->input + 1;
+        is_escaped = true;
+      } else if (stream->next == '"') {
+        array_extend(&self->string_buffer, (uint32_t)(stream->input - prev_position), prev_position);
+        stream_advance(stream);
+        return TSQueryErrorNone;
+      } else if (stream->next == '\n') {
+        stream_reset(stream, string_start);
+        return TSQueryErrorSyntax;
+      }
+    }
+    if (!stream_advance(stream)) {
+      stream_reset(stream, string_start);
+      return TSQueryErrorSyntax;
+    }
+  }
+}
+
+// Parse a single predicate associated with a pattern, adding it to the
+// query's internal `predicate_steps` array. Predicates are arbitrary
+// S-expressions associated with a pattern which are meant to be handled at
+// a higher level of abstraction, such as the Rust/JavaScript bindings. They
+// can contain '@'-prefixed capture names, double-quoted strings, and bare
+// symbols, which also represent strings.
+static TSQueryError ts_query__parse_predicate(
+  TSQuery *self,
+  Stream *stream
+) {
+  if (!stream_is_ident_start(stream)) return TSQueryErrorSyntax;
+  const char *predicate_name = stream->input;
+  stream_scan_identifier(stream);
+  uint32_t length = (uint32_t)(stream->input - predicate_name);
+  uint16_t id = symbol_table_insert_name(
+    &self->predicate_values,
+    predicate_name,
+    length
+  );
+  array_push(&self->predicate_steps, ((TSQueryPredicateStep) {
+    .type = TSQueryPredicateStepTypeString,
+    .value_id = id,
+  }));
+  stream_skip_whitespace(stream);
+
+  for (;;) {
+    if (stream->next == ')') {
+      stream_advance(stream);
+      stream_skip_whitespace(stream);
+      array_push(&self->predicate_steps, ((TSQueryPredicateStep) {
+        .type = TSQueryPredicateStepTypeDone,
+        .value_id = 0,
+      }));
+      break;
+    }
+
+    // Parse an '@'-prefixed capture name
+    else if (stream->next == '@') {
+      stream_advance(stream);
+
+      // Parse the capture name
+      if (!stream_is_ident_start(stream)) return TSQueryErrorSyntax;
+      const char *capture_name = stream->input;
+      stream_scan_identifier(stream);
+      uint32_t capture_length = (uint32_t)(stream->input - capture_name);
+
+      // Add the capture id to the first step of the pattern
+      int capture_id = symbol_table_id_for_name(
+        &self->captures,
+        capture_name,
+        capture_length
+      );
+      if (capture_id == -1) {
+        stream_reset(stream, capture_name);
+        return TSQueryErrorCapture;
+      }
+
+      array_push(&self->predicate_steps, ((TSQueryPredicateStep) {
+        .type = TSQueryPredicateStepTypeCapture,
+        .value_id = capture_id,
+      }));
+    }
+
+    // Parse a string literal
+    else if (stream->next == '"') {
+      TSQueryError e = ts_query__parse_string_literal(self, stream);
+      if (e) return e;
+      uint16_t query_id = symbol_table_insert_name(
+        &self->predicate_values,
+        self->string_buffer.contents,
+        self->string_buffer.size
+      );
+      array_push(&self->predicate_steps, ((TSQueryPredicateStep) {
+        .type = TSQueryPredicateStepTypeString,
+        .value_id = query_id,
+      }));
+    }
+
+    // Parse a bare symbol
+    else if (stream_is_ident_start(stream)) {
+      const char *symbol_start = stream->input;
+      stream_scan_identifier(stream);
+      uint32_t symbol_length = (uint32_t)(stream->input - symbol_start);
+      uint16_t query_id = symbol_table_insert_name(
+        &self->predicate_values,
+        symbol_start,
+        symbol_length
+      );
+      array_push(&self->predicate_steps, ((TSQueryPredicateStep) {
+        .type = TSQueryPredicateStepTypeString,
+        .value_id = query_id,
+      }));
+    }
+
+    else {
+      return TSQueryErrorSyntax;
+    }
+
+    stream_skip_whitespace(stream);
+  }
+
+  return 0;
+}
+
+// Read one S-expression pattern from the stream, and incorporate it into
+// the query's internal state machine representation. For nested patterns,
+// this function calls itself recursively.
+//
+// The caller is responsible for passing in a dedicated CaptureQuantifiers.
+// These should not be shared between different calls to ts_query__parse_pattern!
+static TSQueryError ts_query__parse_pattern(
+  TSQuery *self,
+  Stream *stream,
+  uint32_t depth,
+  bool is_immediate,
+  CaptureQuantifiers *capture_quantifiers
+) {
+  if (stream->next == 0) return TSQueryErrorSyntax;
+  if (stream->next == ')' || stream->next == ']') return PARENT_DONE;
+
+  const uint32_t starting_step_index = self->steps.size;
+
+  // Store the byte offset of each step in the query.
+  if (
+    self->step_offsets.size == 0 ||
+    array_back(&self->step_offsets)->step_index != starting_step_index
+  ) {
+    array_push(&self->step_offsets, ((StepOffset) {
+      .step_index = starting_step_index,
+      .byte_offset = stream_offset(stream),
+    }));
+  }
+
+  // An open bracket is the start of an alternation.
+  if (stream->next == '[') {
+    stream_advance(stream);
+    stream_skip_whitespace(stream);
+
+    // Parse each branch, and add a placeholder step in between the branches.
+    Array(uint32_t) branch_step_indices = array_new();
+    CaptureQuantifiers branch_capture_quantifiers = capture_quantifiers_new();
+    for (;;) {
+      uint32_t start_index = self->steps.size;
+      TSQueryError e = ts_query__parse_pattern(
+        self,
+        stream,
+        depth,
+        is_immediate,
+        &branch_capture_quantifiers
+      );
+
+      if (e == PARENT_DONE) {
+        if (stream->next == ']' && branch_step_indices.size > 0) {
+          stream_advance(stream);
+          break;
+        }
+        e = TSQueryErrorSyntax;
+      }
+      if (e) {
+        capture_quantifiers_delete(&branch_capture_quantifiers);
+        array_delete(&branch_step_indices);
+        return e;
+      }
+
+      if (start_index == starting_step_index) {
+        capture_quantifiers_replace(capture_quantifiers, &branch_capture_quantifiers);
+      } else {
+        capture_quantifiers_join_all(capture_quantifiers, &branch_capture_quantifiers);
+      }
+
+      array_push(&branch_step_indices, start_index);
+      array_push(&self->steps, query_step__new(0, depth, false));
+      capture_quantifiers_clear(&branch_capture_quantifiers);
+    }
+    (void)array_pop(&self->steps);
+
+    // For all of the branches except for the last one, add the subsequent branch as an
+    // alternative, and link the end of the branch to the current end of the steps.
+    for (unsigned i = 0; i < branch_step_indices.size - 1; i++) {
+      uint32_t step_index = branch_step_indices.contents[i];
+      uint32_t next_step_index = branch_step_indices.contents[i + 1];
+      QueryStep *start_step = &self->steps.contents[step_index];
+      QueryStep *end_step = &self->steps.contents[next_step_index - 1];
+      start_step->alternative_index = next_step_index;
+      end_step->alternative_index = self->steps.size;
+      end_step->is_dead_end = true;
+    }
+
+    capture_quantifiers_delete(&branch_capture_quantifiers);
+    array_delete(&branch_step_indices);
+  }
+
+  // An open parenthesis can be the start of three possible constructs:
+  // * A grouped sequence
+  // * A predicate
+  // * A named node
+  else if (stream->next == '(') {
+    stream_advance(stream);
+    stream_skip_whitespace(stream);
+
+    // If this parenthesis is followed by a node, then it represents a grouped sequence.
+    if (stream->next == '(' || stream->next == '"' || stream->next == '[') {
+      bool child_is_immediate = is_immediate;
+      CaptureQuantifiers child_capture_quantifiers = capture_quantifiers_new();
+      for (;;) {
+        if (stream->next == '.') {
+          child_is_immediate = true;
+          stream_advance(stream);
+          stream_skip_whitespace(stream);
+        }
+        TSQueryError e = ts_query__parse_pattern(
+          self,
+          stream,
+          depth,
+          child_is_immediate,
+          &child_capture_quantifiers
+        );
+        if (e == PARENT_DONE) {
+          if (stream->next == ')') {
+            stream_advance(stream);
+            break;
+          }
+          e = TSQueryErrorSyntax;
+        }
+        if (e) {
+          capture_quantifiers_delete(&child_capture_quantifiers);
+          return e;
+        }
+
+        capture_quantifiers_add_all(capture_quantifiers, &child_capture_quantifiers);
+        capture_quantifiers_clear(&child_capture_quantifiers);
+        child_is_immediate = false;
+      }
+
+      capture_quantifiers_delete(&child_capture_quantifiers);
+    }
+
+    // A dot/pound character indicates the start of a predicate.
+    else if (stream->next == '.' || stream->next == '#') {
+      stream_advance(stream);
+      return ts_query__parse_predicate(self, stream);
+    }
+
+    // Otherwise, this parenthesis is the start of a named node.
+    else {
+      TSSymbol symbol;
+
+      // Parse a normal node name
+      if (stream_is_ident_start(stream)) {
+        const char *node_name = stream->input;
+        stream_scan_identifier(stream);
+        uint32_t length = (uint32_t)(stream->input - node_name);
+
+        // Parse the wildcard symbol
+        if (length == 1 && node_name[0] == '_') {
+          symbol = WILDCARD_SYMBOL;
+        }
+
+        else {
+          symbol = ts_language_symbol_for_name(
+            self->language,
+            node_name,
+            length,
+            true
+          );
+          if (!symbol) {
+            stream_reset(stream, node_name);
+            return TSQueryErrorNodeType;
+          }
+        }
+      } else {
+        return TSQueryErrorSyntax;
+      }
+
+      // Add a step for the node.
+      array_push(&self->steps, query_step__new(symbol, depth, is_immediate));
+      QueryStep *step = array_back(&self->steps);
+      if (ts_language_symbol_metadata(self->language, symbol).supertype) {
+        step->supertype_symbol = step->symbol;
+        step->symbol = WILDCARD_SYMBOL;
+      }
+      if (symbol == WILDCARD_SYMBOL) {
+        step->is_named = true;
+      }
+
+      stream_skip_whitespace(stream);
+
+      if (stream->next == '/') {
+        stream_advance(stream);
+        if (!stream_is_ident_start(stream)) {
+          return TSQueryErrorSyntax;
+        }
+
+        const char *node_name = stream->input;
+        stream_scan_identifier(stream);
+        uint32_t length = (uint32_t)(stream->input - node_name);
+
+        step->symbol = ts_language_symbol_for_name(
+          self->language,
+          node_name,
+          length,
+          true
+        );
+        if (!step->symbol) {
+          stream_reset(stream, node_name);
+          return TSQueryErrorNodeType;
+        }
+
+        stream_skip_whitespace(stream);
+      }
+
+      // Parse the child patterns
+      bool child_is_immediate = false;
+      uint16_t last_child_step_index = 0;
+      uint16_t negated_field_count = 0;
+      TSFieldId negated_field_ids[MAX_NEGATED_FIELD_COUNT];
+      CaptureQuantifiers child_capture_quantifiers = capture_quantifiers_new();
+      for (;;) {
+        // Parse a negated field assertion
+        if (stream->next == '!') {
+          stream_advance(stream);
+          stream_skip_whitespace(stream);
+          if (!stream_is_ident_start(stream)) {
+            capture_quantifiers_delete(&child_capture_quantifiers);
+            return TSQueryErrorSyntax;
+          }
+          const char *field_name = stream->input;
+          stream_scan_identifier(stream);
+          uint32_t length = (uint32_t)(stream->input - field_name);
+          stream_skip_whitespace(stream);
+
+          TSFieldId field_id = ts_language_field_id_for_name(
+            self->language,
+            field_name,
+            length
+          );
+          if (!field_id) {
+            stream->input = field_name;
+            capture_quantifiers_delete(&child_capture_quantifiers);
+            return TSQueryErrorField;
+          }
+
+          // Keep the field ids sorted.
+          if (negated_field_count < MAX_NEGATED_FIELD_COUNT) {
+            negated_field_ids[negated_field_count] = field_id;
+            negated_field_count++;
+          }
+
+          continue;
+        }
+
+        // Parse a sibling anchor
+        if (stream->next == '.') {
+          child_is_immediate = true;
+          stream_advance(stream);
+          stream_skip_whitespace(stream);
+        }
+
+        uint16_t step_index = self->steps.size;
+        TSQueryError e = ts_query__parse_pattern(
+          self,
+          stream,
+          depth + 1,
+          child_is_immediate,
+          &child_capture_quantifiers
+        );
+        if (e == PARENT_DONE) {
+          if (stream->next == ')') {
+            if (child_is_immediate) {
+              if (last_child_step_index == 0) {
+                capture_quantifiers_delete(&child_capture_quantifiers);
+                return TSQueryErrorSyntax;
+              }
+              self->steps.contents[last_child_step_index].is_last_child = true;
+            }
+
+            if (negated_field_count) {
+              ts_query__add_negated_fields(
+                self,
+                starting_step_index,
+                negated_field_ids,
+                negated_field_count
+              );
+            }
+
+            stream_advance(stream);
+            break;
+          }
+          e = TSQueryErrorSyntax;
+        }
+        if (e) {
+          capture_quantifiers_delete(&child_capture_quantifiers);
+          return e;
+        }
+
+        capture_quantifiers_add_all(capture_quantifiers, &child_capture_quantifiers);
+
+        last_child_step_index = step_index;
+        child_is_immediate = false;
+        capture_quantifiers_clear(&child_capture_quantifiers);
+      }
+      capture_quantifiers_delete(&child_capture_quantifiers);
+    }
+  }
+
+  // Parse a wildcard pattern
+  else if (stream->next == '_') {
+    stream_advance(stream);
+    stream_skip_whitespace(stream);
+
+    // Add a step that matches any kind of node
+    array_push(&self->steps, query_step__new(WILDCARD_SYMBOL, depth, is_immediate));
+  }
+
+  // Parse a double-quoted anonymous leaf node expression
+  else if (stream->next == '"') {
+    const char *string_start = stream->input;
+    TSQueryError e = ts_query__parse_string_literal(self, stream);
+    if (e) return e;
+
+    // Add a step for the node
+    TSSymbol symbol = ts_language_symbol_for_name(
+      self->language,
+      self->string_buffer.contents,
+      self->string_buffer.size,
+      false
+    );
+    if (!symbol) {
+      stream_reset(stream, string_start + 1);
+      return TSQueryErrorNodeType;
+    }
+    array_push(&self->steps, query_step__new(symbol, depth, is_immediate));
+  }
+
+  // Parse a field-prefixed pattern
+  else if (stream_is_ident_start(stream)) {
+    // Parse the field name
+    const char *field_name = stream->input;
+    stream_scan_identifier(stream);
+    uint32_t length = (uint32_t)(stream->input - field_name);
+    stream_skip_whitespace(stream);
+
+    if (stream->next != ':') {
+      stream_reset(stream, field_name);
+      return TSQueryErrorSyntax;
+    }
+    stream_advance(stream);
+    stream_skip_whitespace(stream);
+
+    // Parse the pattern
+    CaptureQuantifiers field_capture_quantifiers = capture_quantifiers_new();
+    TSQueryError e = ts_query__parse_pattern(
+      self,
+      stream,
+      depth,
+      is_immediate,
+      &field_capture_quantifiers
+    );
+    if (e) {
+      capture_quantifiers_delete(&field_capture_quantifiers);
+      if (e == PARENT_DONE) e = TSQueryErrorSyntax;
+      return e;
+    }
+
+    // Add the field name to the first step of the pattern
+    TSFieldId field_id = ts_language_field_id_for_name(
+      self->language,
+      field_name,
+      length
+    );
+    if (!field_id) {
+      stream->input = field_name;
+      return TSQueryErrorField;
+    }
+
+    uint32_t step_index = starting_step_index;
+    QueryStep *step = &self->steps.contents[step_index];
+    for (;;) {
+      step->field = field_id;
+      if (
+        step->alternative_index != NONE &&
+        step->alternative_index > step_index &&
+        step->alternative_index < self->steps.size
+      ) {
+        step_index = step->alternative_index;
+        step = &self->steps.contents[step_index];
+      } else {
+        break;
+      }
+    }
+
+    capture_quantifiers_add_all(capture_quantifiers, &field_capture_quantifiers);
+    capture_quantifiers_delete(&field_capture_quantifiers);
+  }
+
+  else {
+    return TSQueryErrorSyntax;
+  }
+
+  stream_skip_whitespace(stream);
+
+  // Parse suffixes modifiers for this pattern
+  TSQuantifier quantifier = TSQuantifierOne;
+  for (;;) {
+    // Parse the one-or-more operator.
+    if (stream->next == '+') {
+      quantifier = quantifier_join(TSQuantifierOneOrMore, quantifier);
+
+      stream_advance(stream);
+      stream_skip_whitespace(stream);
+
+      QueryStep repeat_step = query_step__new(WILDCARD_SYMBOL, depth, false);
+      repeat_step.alternative_index = starting_step_index;
+      repeat_step.is_pass_through = true;
+      repeat_step.alternative_is_immediate = true;
+      array_push(&self->steps, repeat_step);
+    }
+
+    // Parse the zero-or-more repetition operator.
+    else if (stream->next == '*') {
+      quantifier = quantifier_join(TSQuantifierZeroOrMore, quantifier);
+
+      stream_advance(stream);
+      stream_skip_whitespace(stream);
+
+      QueryStep repeat_step = query_step__new(WILDCARD_SYMBOL, depth, false);
+      repeat_step.alternative_index = starting_step_index;
+      repeat_step.is_pass_through = true;
+      repeat_step.alternative_is_immediate = true;
+      array_push(&self->steps, repeat_step);
+
+      // Stop when `step->alternative_index` is `NONE` or it points to
+      // `repeat_step` or beyond. Note that having just been pushed,
+      // `repeat_step` occupies slot `self->steps.size - 1`.
+      QueryStep *step = &self->steps.contents[starting_step_index];
+      while (step->alternative_index != NONE && step->alternative_index < self->steps.size - 1) {
+        step = &self->steps.contents[step->alternative_index];
+      }
+      step->alternative_index = self->steps.size;
+    }
+
+    // Parse the optional operator.
+    else if (stream->next == '?') {
+      quantifier = quantifier_join(TSQuantifierZeroOrOne, quantifier);
+
+      stream_advance(stream);
+      stream_skip_whitespace(stream);
+
+      QueryStep *step = &self->steps.contents[starting_step_index];
+      while (step->alternative_index != NONE && step->alternative_index < self->steps.size) {
+        step = &self->steps.contents[step->alternative_index];
+      }
+      step->alternative_index = self->steps.size;
+    }
+
+    // Parse an '@'-prefixed capture pattern
+    else if (stream->next == '@') {
+      stream_advance(stream);
+      if (!stream_is_ident_start(stream)) return TSQueryErrorSyntax;
+      const char *capture_name = stream->input;
+      stream_scan_identifier(stream);
+      uint32_t length = (uint32_t)(stream->input - capture_name);
+      stream_skip_whitespace(stream);
+
+      // Add the capture id to the first step of the pattern
+      uint16_t capture_id = symbol_table_insert_name(
+        &self->captures,
+        capture_name,
+        length
+      );
+
+      // Add the capture quantifier
+      capture_quantifiers_add_for_id(capture_quantifiers, capture_id, TSQuantifierOne);
+
+      uint32_t step_index = starting_step_index;
+      for (;;) {
+        QueryStep *step = &self->steps.contents[step_index];
+        query_step__add_capture(step, capture_id);
+        if (
+          step->alternative_index != NONE &&
+          step->alternative_index > step_index &&
+          step->alternative_index < self->steps.size
+        ) {
+          step_index = step->alternative_index;
+        } else {
+          break;
+        }
+      }
+    }
+
+    // No more suffix modifiers
+    else {
+      break;
+    }
+  }
+
+  capture_quantifiers_mul(capture_quantifiers, quantifier);
+
+  return 0;
+}
+
+TSQuery *ts_query_new(
+  const TSLanguage *language,
+  const char *source,
+  uint32_t source_len,
+  uint32_t *error_offset,
+  TSQueryError *error_type
+) {
+  if (
+    !language ||
+    language->version > TREE_SITTER_LANGUAGE_VERSION ||
+    language->version < TREE_SITTER_MIN_COMPATIBLE_LANGUAGE_VERSION
+  ) {
+    *error_type = TSQueryErrorLanguage;
+    return NULL;
+  }
+
+  TSQuery *self = ts_malloc(sizeof(TSQuery));
+  *self = (TSQuery) {
+    .steps = array_new(),
+    .pattern_map = array_new(),
+    .captures = symbol_table_new(),
+    .capture_quantifiers = array_new(),
+    .predicate_values = symbol_table_new(),
+    .predicate_steps = array_new(),
+    .patterns = array_new(),
+    .step_offsets = array_new(),
+    .string_buffer = array_new(),
+    .negated_fields = array_new(),
+    .repeat_symbols_with_rootless_patterns = array_new(),
+    .wildcard_root_pattern_count = 0,
+    .language = ts_language_copy(language),
+  };
+
+  array_push(&self->negated_fields, 0);
+
+  // Parse all of the S-expressions in the given string.
+  Stream stream = stream_new(source, source_len);
+  stream_skip_whitespace(&stream);
+  while (stream.input < stream.end) {
+    uint32_t pattern_index = self->patterns.size;
+    uint32_t start_step_index = self->steps.size;
+    uint32_t start_predicate_step_index = self->predicate_steps.size;
+    array_push(&self->patterns, ((QueryPattern) {
+      .steps = (Slice) {.offset = start_step_index},
+      .predicate_steps = (Slice) {.offset = start_predicate_step_index},
+      .start_byte = stream_offset(&stream),
+      .is_non_local = false,
+    }));
+    CaptureQuantifiers capture_quantifiers = capture_quantifiers_new();
+    *error_type = ts_query__parse_pattern(self, &stream, 0, false, &capture_quantifiers);
+    array_push(&self->steps, query_step__new(0, PATTERN_DONE_MARKER, false));
+
+    QueryPattern *pattern = array_back(&self->patterns);
+    pattern->steps.length = self->steps.size - start_step_index;
+    pattern->predicate_steps.length = self->predicate_steps.size - start_predicate_step_index;
+    pattern->end_byte = stream_offset(&stream);
+
+    // If any pattern could not be parsed, then report the error information
+    // and terminate.
+    if (*error_type) {
+      if (*error_type == PARENT_DONE) *error_type = TSQueryErrorSyntax;
+      *error_offset = stream_offset(&stream);
+      capture_quantifiers_delete(&capture_quantifiers);
+      ts_query_delete(self);
+      return NULL;
+    }
+
+    // Maintain a list of capture quantifiers for each pattern
+    array_push(&self->capture_quantifiers, capture_quantifiers);
+
+    // Maintain a map that can look up patterns for a given root symbol.
+    uint16_t wildcard_root_alternative_index = NONE;
+    for (;;) {
+      QueryStep *step = &self->steps.contents[start_step_index];
+
+      // If a pattern has a wildcard at its root, but it has a non-wildcard child,
+      // then optimize the matching process by skipping matching the wildcard.
+      // Later, during the matching process, the query cursor will check that
+      // there is a parent node, and capture it if necessary.
+      if (step->symbol == WILDCARD_SYMBOL && step->depth == 0 && !step->field) {
+        QueryStep *second_step = &self->steps.contents[start_step_index + 1];
+        if (second_step->symbol != WILDCARD_SYMBOL && second_step->depth == 1 && !second_step->is_immediate) {
+          wildcard_root_alternative_index = step->alternative_index;
+          start_step_index += 1;
+          step = second_step;
+        }
+      }
+
+      // Determine whether the pattern has a single root node. This affects
+      // decisions about whether or not to start matching the pattern when
+      // a query cursor has a range restriction or when immediately within an
+      // error node.
+      uint32_t start_depth = step->depth;
+      bool is_rooted = start_depth == 0;
+      for (uint32_t step_index = start_step_index + 1; step_index < self->steps.size; step_index++) {
+        QueryStep *child_step = &self->steps.contents[step_index];
+        if (child_step->is_dead_end) break;
+        if (child_step->depth == start_depth) {
+          is_rooted = false;
+          break;
+        }
+      }
+
+      ts_query__pattern_map_insert(self, step->symbol, (PatternEntry) {
+        .step_index = start_step_index,
+        .pattern_index = pattern_index,
+        .is_rooted = is_rooted
+      });
+      if (step->symbol == WILDCARD_SYMBOL) {
+        self->wildcard_root_pattern_count++;
+      }
+
+      // If there are alternatives or options at the root of the pattern,
+      // then add multiple entries to the pattern map.
+      if (step->alternative_index != NONE) {
+        start_step_index = step->alternative_index;
+      } else if (wildcard_root_alternative_index != NONE) {
+        start_step_index = wildcard_root_alternative_index;
+        wildcard_root_alternative_index = NONE;
+      } else {
+        break;
+      }
+    }
+  }
+
+  if (!ts_query__analyze_patterns(self, error_offset)) {
+    *error_type = TSQueryErrorStructure;
+    ts_query_delete(self);
+    return NULL;
+  }
+
+  array_delete(&self->string_buffer);
+  return self;
+}
+
+void ts_query_delete(TSQuery *self) {
+  if (self) {
+    array_delete(&self->steps);
+    array_delete(&self->pattern_map);
+    array_delete(&self->predicate_steps);
+    array_delete(&self->patterns);
+    array_delete(&self->step_offsets);
+    array_delete(&self->string_buffer);
+    array_delete(&self->negated_fields);
+    array_delete(&self->repeat_symbols_with_rootless_patterns);
+    ts_language_delete(self->language);
+    symbol_table_delete(&self->captures);
+    symbol_table_delete(&self->predicate_values);
+    for (uint32_t index = 0; index < self->capture_quantifiers.size; index++) {
+      CaptureQuantifiers *capture_quantifiers = array_get(&self->capture_quantifiers, index);
+      capture_quantifiers_delete(capture_quantifiers);
+    }
+    array_delete(&self->capture_quantifiers);
+    ts_free(self);
+  }
+}
+
+uint32_t ts_query_pattern_count(const TSQuery *self) {
+  return self->patterns.size;
+}
+
+uint32_t ts_query_capture_count(const TSQuery *self) {
+  return self->captures.slices.size;
+}
+
+uint32_t ts_query_string_count(const TSQuery *self) {
+  return self->predicate_values.slices.size;
+}
+
+const char *ts_query_capture_name_for_id(
+  const TSQuery *self,
+  uint32_t index,
+  uint32_t *length
+) {
+  return symbol_table_name_for_id(&self->captures, index, length);
+}
+
+TSQuantifier ts_query_capture_quantifier_for_id(
+  const TSQuery *self,
+  uint32_t pattern_index,
+  uint32_t capture_index
+) {
+  CaptureQuantifiers *capture_quantifiers = array_get(&self->capture_quantifiers, pattern_index);
+  return capture_quantifier_for_id(capture_quantifiers, capture_index);
+}
+
+const char *ts_query_string_value_for_id(
+  const TSQuery *self,
+  uint32_t index,
+  uint32_t *length
+) {
+  return symbol_table_name_for_id(&self->predicate_values, index, length);
+}
+
+const TSQueryPredicateStep *ts_query_predicates_for_pattern(
+  const TSQuery *self,
+  uint32_t pattern_index,
+  uint32_t *step_count
+) {
+  Slice slice = self->patterns.contents[pattern_index].predicate_steps;
+  *step_count = slice.length;
+  if (self->predicate_steps.contents == NULL) {
+    return NULL;
+  }
+  return &self->predicate_steps.contents[slice.offset];
+}
+
+uint32_t ts_query_start_byte_for_pattern(
+  const TSQuery *self,
+  uint32_t pattern_index
+) {
+  return self->patterns.contents[pattern_index].start_byte;
+}
+
+uint32_t ts_query_end_byte_for_pattern(
+  const TSQuery *self,
+  uint32_t pattern_index
+) {
+  return self->patterns.contents[pattern_index].end_byte;
+}
+
+bool ts_query_is_pattern_rooted(
+  const TSQuery *self,
+  uint32_t pattern_index
+) {
+  for (unsigned i = 0; i < self->pattern_map.size; i++) {
+    PatternEntry *entry = &self->pattern_map.contents[i];
+    if (entry->pattern_index == pattern_index) {
+      if (!entry->is_rooted) return false;
+    }
+  }
+  return true;
+}
+
+bool ts_query_is_pattern_non_local(
+  const TSQuery *self,
+  uint32_t pattern_index
+) {
+  if (pattern_index < self->patterns.size) {
+    return self->patterns.contents[pattern_index].is_non_local;
+  } else {
+    return false;
+  }
+}
+
+bool ts_query_is_pattern_guaranteed_at_step(
+  const TSQuery *self,
+  uint32_t byte_offset
+) {
+  uint32_t step_index = UINT32_MAX;
+  for (unsigned i = 0; i < self->step_offsets.size; i++) {
+    StepOffset *step_offset = &self->step_offsets.contents[i];
+    if (step_offset->byte_offset > byte_offset) break;
+    step_index = step_offset->step_index;
+  }
+  if (step_index < self->steps.size) {
+    return self->steps.contents[step_index].root_pattern_guaranteed;
+  } else {
+    return false;
+  }
+}
+
+bool ts_query__step_is_fallible(
+  const TSQuery *self,
+  uint16_t step_index
+) {
+  ts_assert((uint32_t)step_index + 1 < self->steps.size);
+  QueryStep *step = &self->steps.contents[step_index];
+  QueryStep *next_step = &self->steps.contents[step_index + 1];
+  return (
+    next_step->depth != PATTERN_DONE_MARKER &&
+    next_step->depth > step->depth &&
+    !next_step->parent_pattern_guaranteed
+  );
+}
+
+void ts_query_disable_capture(
+  TSQuery *self,
+  const char *name,
+  uint32_t length
+) {
+  // Remove capture information for any pattern step that previously
+  // captured with the given name.
+  int id = symbol_table_id_for_name(&self->captures, name, length);
+  if (id != -1) {
+    for (unsigned i = 0; i < self->steps.size; i++) {
+      QueryStep *step = &self->steps.contents[i];
+      query_step__remove_capture(step, id);
+    }
+  }
+}
+
+void ts_query_disable_pattern(
+  TSQuery *self,
+  uint32_t pattern_index
+) {
+  // Remove the given pattern from the pattern map. Its steps will still
+  // be in the `steps` array, but they will never be read.
+  for (unsigned i = 0; i < self->pattern_map.size; i++) {
+    PatternEntry *pattern = &self->pattern_map.contents[i];
+    if (pattern->pattern_index == pattern_index) {
+      array_erase(&self->pattern_map, i);
+      i--;
+    }
+  }
+}
+
+/***************
+ * QueryCursor
+ ***************/
+
+TSQueryCursor *ts_query_cursor_new(void) {
+  TSQueryCursor *self = ts_malloc(sizeof(TSQueryCursor));
+  *self = (TSQueryCursor) {
+    .did_exceed_match_limit = false,
+    .ascending = false,
+    .halted = false,
+    .states = array_new(),
+    .finished_states = array_new(),
+    .capture_list_pool = capture_list_pool_new(),
+    .start_byte = 0,
+    .end_byte = UINT32_MAX,
+    .start_point = {0, 0},
+    .end_point = POINT_MAX,
+    .max_start_depth = UINT32_MAX,
+    .timeout_duration = 0,
+    .end_clock = clock_null(),
+    .operation_count = 0,
+  };
+  array_reserve(&self->states, 8);
+  array_reserve(&self->finished_states, 8);
+  return self;
+}
+
+void ts_query_cursor_delete(TSQueryCursor *self) {
+  array_delete(&self->states);
+  array_delete(&self->finished_states);
+  ts_tree_cursor_delete(&self->cursor);
+  capture_list_pool_delete(&self->capture_list_pool);
+  ts_free(self);
+}
+
+bool ts_query_cursor_did_exceed_match_limit(const TSQueryCursor *self) {
+  return self->did_exceed_match_limit;
+}
+
+uint32_t ts_query_cursor_match_limit(const TSQueryCursor *self) {
+  return self->capture_list_pool.max_capture_list_count;
+}
+
+void ts_query_cursor_set_match_limit(TSQueryCursor *self, uint32_t limit) {
+  self->capture_list_pool.max_capture_list_count = limit;
+}
+
+uint64_t ts_query_cursor_timeout_micros(const TSQueryCursor *self) {
+  return duration_to_micros(self->timeout_duration);
+}
+
+void ts_query_cursor_set_timeout_micros(TSQueryCursor *self, uint64_t timeout_micros) {
+  self->timeout_duration = duration_from_micros(timeout_micros);
+}
+
+#ifdef DEBUG_EXECUTE_QUERY
+#define LOG(...) fprintf(stderr, __VA_ARGS__)
+#else
+#define LOG(...)
+#endif
+
+void ts_query_cursor_exec(
+  TSQueryCursor *self,
+  const TSQuery *query,
+  TSNode node
+) {
+  if (query) {
+    LOG("query steps:\n");
+    for (unsigned i = 0; i < query->steps.size; i++) {
+      QueryStep *step = &query->steps.contents[i];
+      LOG("  %u: {", i);
+      if (step->depth == PATTERN_DONE_MARKER) {
+        LOG("DONE");
+      } else if (step->is_dead_end) {
+        LOG("dead_end");
+      } else if (step->is_pass_through) {
+        LOG("pass_through");
+      } else if (step->symbol != WILDCARD_SYMBOL) {
+        LOG("symbol: %s", query->language->symbol_names[step->symbol]);
+      } else {
+        LOG("symbol: *");
+      }
+      if (step->field) {
+        LOG(", field: %s", query->language->field_names[step->field]);
+      }
+      if (step->alternative_index != NONE) {
+        LOG(", alternative: %u", step->alternative_index);
+      }
+      LOG("},\n");
+    }
+  }
+
+  array_clear(&self->states);
+  array_clear(&self->finished_states);
+  ts_tree_cursor_reset(&self->cursor, node);
+  capture_list_pool_reset(&self->capture_list_pool);
+  self->on_visible_node = true;
+  self->next_state_id = 0;
+  self->depth = 0;
+  self->ascending = false;
+  self->halted = false;
+  self->query = query;
+  self->did_exceed_match_limit = false;
+  self->operation_count = 0;
+  if (self->timeout_duration) {
+    self->end_clock = clock_after(clock_now(), self->timeout_duration);
+  } else {
+    self->end_clock = clock_null();
+  }
+}
+
+void ts_query_cursor_set_byte_range(
+  TSQueryCursor *self,
+  uint32_t start_byte,
+  uint32_t end_byte
+) {
+  if (end_byte == 0) {
+    end_byte = UINT32_MAX;
+  }
+  self->start_byte = start_byte;
+  self->end_byte = end_byte;
+}
+
+void ts_query_cursor_set_point_range(
+  TSQueryCursor *self,
+  TSPoint start_point,
+  TSPoint end_point
+) {
+  if (end_point.row == 0 && end_point.column == 0) {
+    end_point = POINT_MAX;
+  }
+  self->start_point = start_point;
+  self->end_point = end_point;
+}
+
+// Search through all of the in-progress states, and find the captured
+// node that occurs earliest in the document.
+static bool ts_query_cursor__first_in_progress_capture(
+  TSQueryCursor *self,
+  uint32_t *state_index,
+  uint32_t *byte_offset,
+  uint32_t *pattern_index,
+  bool *root_pattern_guaranteed
+) {
+  bool result = false;
+  *state_index = UINT32_MAX;
+  *byte_offset = UINT32_MAX;
+  *pattern_index = UINT32_MAX;
+  for (unsigned i = 0; i < self->states.size; i++) {
+    QueryState *state = &self->states.contents[i];
+    if (state->dead) continue;
+
+    const CaptureList *captures = capture_list_pool_get(
+      &self->capture_list_pool,
+      state->capture_list_id
+    );
+    if (state->consumed_capture_count >= captures->size) {
+      continue;
+    }
+
+    TSNode node = captures->contents[state->consumed_capture_count].node;
+    if (
+      ts_node_end_byte(node) <= self->start_byte ||
+      point_lte(ts_node_end_point(node), self->start_point)
+    ) {
+      state->consumed_capture_count++;
+      i--;
+      continue;
+    }
+
+    uint32_t node_start_byte = ts_node_start_byte(node);
+    if (
+      !result ||
+      node_start_byte < *byte_offset ||
+      (node_start_byte == *byte_offset && state->pattern_index < *pattern_index)
+    ) {
+      QueryStep *step = &self->query->steps.contents[state->step_index];
+      if (root_pattern_guaranteed) {
+        *root_pattern_guaranteed = step->root_pattern_guaranteed;
+      } else if (step->root_pattern_guaranteed) {
+        continue;
+      }
+
+      result = true;
+      *state_index = i;
+      *byte_offset = node_start_byte;
+      *pattern_index = state->pattern_index;
+    }
+  }
+  return result;
+}
+
+// Determine which node is first in a depth-first traversal
+int ts_query_cursor__compare_nodes(TSNode left, TSNode right) {
+  if (left.id != right.id) {
+    uint32_t left_start = ts_node_start_byte(left);
+    uint32_t right_start = ts_node_start_byte(right);
+    if (left_start < right_start) return -1;
+    if (left_start > right_start) return 1;
+    uint32_t left_node_count = ts_node_end_byte(left);
+    uint32_t right_node_count = ts_node_end_byte(right);
+    if (left_node_count > right_node_count) return -1;
+    if (left_node_count < right_node_count) return 1;
+  }
+  return 0;
+}
+
+// Determine if either state contains a superset of the other state's captures.
+void ts_query_cursor__compare_captures(
+  TSQueryCursor *self,
+  QueryState *left_state,
+  QueryState *right_state,
+  bool *left_contains_right,
+  bool *right_contains_left
+) {
+  const CaptureList *left_captures = capture_list_pool_get(
+    &self->capture_list_pool,
+    left_state->capture_list_id
+  );
+  const CaptureList *right_captures = capture_list_pool_get(
+    &self->capture_list_pool,
+    right_state->capture_list_id
+  );
+  *left_contains_right = true;
+  *right_contains_left = true;
+  unsigned i = 0, j = 0;
+  for (;;) {
+    if (i < left_captures->size) {
+      if (j < right_captures->size) {
+        TSQueryCapture *left = &left_captures->contents[i];
+        TSQueryCapture *right = &right_captures->contents[j];
+        if (left->node.id == right->node.id && left->index == right->index) {
+          i++;
+          j++;
+        } else {
+          switch (ts_query_cursor__compare_nodes(left->node, right->node)) {
+            case -1:
+              *right_contains_left = false;
+              i++;
+              break;
+            case 1:
+              *left_contains_right = false;
+              j++;
+              break;
+            default:
+              *right_contains_left = false;
+              *left_contains_right = false;
+              i++;
+              j++;
+              break;
+          }
+        }
+      } else {
+        *right_contains_left = false;
+        break;
+      }
+    } else {
+      if (j < right_captures->size) {
+        *left_contains_right = false;
+      }
+      break;
+    }
+  }
+}
+
+static void ts_query_cursor__add_state(
+  TSQueryCursor *self,
+  const PatternEntry *pattern
+) {
+  QueryStep *step = &self->query->steps.contents[pattern->step_index];
+  uint32_t start_depth = self->depth - step->depth;
+
+  // Keep the states array in ascending order of start_depth and pattern_index,
+  // so that it can be processed more efficiently elsewhere. Usually, there is
+  // no work to do here because of two facts:
+  // * States with lower start_depth are naturally added first due to the
+  //   order in which nodes are visited.
+  // * Earlier patterns are naturally added first because of the ordering of the
+  //   pattern_map data structure that's used to initiate matches.
+  //
+  // This loop is only needed in cases where two conditions hold:
+  // * A pattern consists of more than one sibling node, so that its states
+  //   remain in progress after exiting the node that started the match.
+  // * The first node in the pattern matches against multiple nodes at the
+  //   same depth.
+  //
+  // An example of this is the pattern '((comment)* (function))'. If multiple
+  // `comment` nodes appear in a row, then we may initiate a new state for this
+  // pattern while another state for the same pattern is already in progress.
+  // If there are multiple patterns like this in a query, then this loop will
+  // need to execute in order to keep the states ordered by pattern_index.
+  uint32_t index = self->states.size;
+  while (index > 0) {
+    QueryState *prev_state = &self->states.contents[index - 1];
+    if (prev_state->start_depth < start_depth) break;
+    if (prev_state->start_depth == start_depth) {
+      // Avoid inserting an unnecessary duplicate state, which would be
+      // immediately pruned by the longest-match criteria.
+      if (
+        prev_state->pattern_index == pattern->pattern_index &&
+        prev_state->step_index == pattern->step_index
+      ) return;
+      if (prev_state->pattern_index <= pattern->pattern_index) break;
+    }
+    index--;
+  }
+
+  LOG(
+    "  start state. pattern:%u, step:%u\n",
+    pattern->pattern_index,
+    pattern->step_index
+  );
+  array_insert(&self->states, index, ((QueryState) {
+    .id = UINT32_MAX,
+    .capture_list_id = NONE,
+    .step_index = pattern->step_index,
+    .pattern_index = pattern->pattern_index,
+    .start_depth = start_depth,
+    .consumed_capture_count = 0,
+    .seeking_immediate_match = true,
+    .has_in_progress_alternatives = false,
+    .needs_parent = step->depth == 1,
+    .dead = false,
+  }));
+}
+
+// Acquire a capture list for this state. If there are no capture lists left in the
+// pool, this will steal the capture list from another existing state, and mark that
+// other state as 'dead'.
+static CaptureList *ts_query_cursor__prepare_to_capture(
+  TSQueryCursor *self,
+  QueryState *state,
+  unsigned state_index_to_preserve
+) {
+  if (state->capture_list_id == NONE) {
+    state->capture_list_id = capture_list_pool_acquire(&self->capture_list_pool);
+
+    // If there are no capture lists left in the pool, then terminate whichever
+    // state has captured the earliest node in the document, and steal its
+    // capture list.
+    if (state->capture_list_id == NONE) {
+      self->did_exceed_match_limit = true;
+      uint32_t state_index, byte_offset, pattern_index;
+      if (
+        ts_query_cursor__first_in_progress_capture(
+          self,
+          &state_index,
+          &byte_offset,
+          &pattern_index,
+          NULL
+        ) &&
+        state_index != state_index_to_preserve
+      ) {
+        LOG(
+          "  abandon state. index:%u, pattern:%u, offset:%u.\n",
+          state_index, pattern_index, byte_offset
+        );
+        QueryState *other_state = &self->states.contents[state_index];
+        state->capture_list_id = other_state->capture_list_id;
+        other_state->capture_list_id = NONE;
+        other_state->dead = true;
+        CaptureList *list = capture_list_pool_get_mut(
+          &self->capture_list_pool,
+          state->capture_list_id
+        );
+        array_clear(list);
+        return list;
+      } else {
+        LOG("  ran out of capture lists");
+        return NULL;
+      }
+    }
+  }
+  return capture_list_pool_get_mut(&self->capture_list_pool, state->capture_list_id);
+}
+
+static void ts_query_cursor__capture(
+  TSQueryCursor *self,
+  QueryState *state,
+  QueryStep *step,
+  TSNode node
+) {
+  if (state->dead) return;
+  CaptureList *capture_list = ts_query_cursor__prepare_to_capture(self, state, UINT32_MAX);
+  if (!capture_list) {
+    state->dead = true;
+    return;
+  }
+
+  for (unsigned j = 0; j < MAX_STEP_CAPTURE_COUNT; j++) {
+    uint16_t capture_id = step->capture_ids[j];
+    if (step->capture_ids[j] == NONE) break;
+    array_push(capture_list, ((TSQueryCapture) { node, capture_id }));
+    LOG(
+      "  capture node. type:%s, pattern:%u, capture_id:%u, capture_count:%u\n",
+      ts_node_type(node),
+      state->pattern_index,
+      capture_id,
+      capture_list->size
+    );
+  }
+}
+
+// Duplicate the given state and insert the newly-created state immediately after
+// the given state in the `states` array. Ensures that the given state reference is
+// still valid, even if the states array is reallocated.
+static QueryState *ts_query_cursor__copy_state(
+  TSQueryCursor *self,
+  QueryState **state_ref
+) {
+  const QueryState *state = *state_ref;
+  uint32_t state_index = (uint32_t)(state - self->states.contents);
+  QueryState copy = *state;
+  copy.capture_list_id = NONE;
+
+  // If the state has captures, copy its capture list.
+  if (state->capture_list_id != NONE) {
+    CaptureList *new_captures = ts_query_cursor__prepare_to_capture(self, &copy, state_index);
+    if (!new_captures) return NULL;
+    const CaptureList *old_captures = capture_list_pool_get(
+      &self->capture_list_pool,
+      state->capture_list_id
+    );
+    array_push_all(new_captures, old_captures);
+  }
+
+  array_insert(&self->states, state_index + 1, copy);
+  *state_ref = &self->states.contents[state_index];
+  return &self->states.contents[state_index + 1];
+}
+
+static inline bool ts_query_cursor__should_descend(
+  TSQueryCursor *self,
+  bool node_intersects_range
+) {
+
+  if (node_intersects_range && self->depth < self->max_start_depth) {
+    return true;
+  }
+
+  // If there are in-progress matches whose remaining steps occur
+  // deeper in the tree, then descend.
+  for (unsigned i = 0; i < self->states.size; i++) {
+    QueryState *state = &self->states.contents[i];;
+    QueryStep *next_step = &self->query->steps.contents[state->step_index];
+    if (
+      next_step->depth != PATTERN_DONE_MARKER &&
+      state->start_depth + next_step->depth > self->depth
+    ) {
+      return true;
+    }
+  }
+
+  if (self->depth >= self->max_start_depth) {
+    return false;
+  }
+
+  // If the current node is hidden, then a non-rooted pattern might match
+  // one if its roots inside of this node, and match another of its roots
+  // as part of a sibling node, so we may need to descend.
+  if (!self->on_visible_node) {
+    // Descending into a repetition node outside of the range can be
+    // expensive, because these nodes can have many visible children.
+    // Avoid descending into repetition nodes unless we have already
+    // determined that this query can match rootless patterns inside
+    // of this type of repetition node.
+    Subtree subtree = ts_tree_cursor_current_subtree(&self->cursor);
+    if (ts_subtree_is_repetition(subtree)) {
+      bool exists;
+      uint32_t index;
+      array_search_sorted_by(
+        &self->query->repeat_symbols_with_rootless_patterns,,
+        ts_subtree_symbol(subtree),
+        &index,
+        &exists
+      );
+      return exists;
+    }
+
+    return true;
+  }
+
+  return false;
+}
+
+// Walk the tree, processing patterns until at least one pattern finishes,
+// If one or more patterns finish, return `true` and store their states in the
+// `finished_states` array. Multiple patterns can finish on the same node. If
+// there are no more matches, return `false`.
+static inline bool ts_query_cursor__advance(
+  TSQueryCursor *self,
+  bool stop_on_definite_step
+) {
+  bool did_match = false;
+  for (;;) {
+    if (self->halted) {
+      while (self->states.size > 0) {
+        QueryState state = array_pop(&self->states);
+        capture_list_pool_release(
+          &self->capture_list_pool,
+          state.capture_list_id
+        );
+      }
+    }
+
+    if (++self->operation_count == OP_COUNT_PER_QUERY_TIMEOUT_CHECK) {
+      self->operation_count = 0;
+    }
+    if (
+      did_match ||
+      self->halted ||
+      (
+        self->operation_count == 0 &&
+        !clock_is_null(self->end_clock) && clock_is_gt(clock_now(), self->end_clock)
+      )
+    ) {
+      return did_match;
+    }
+
+    // Exit the current node.
+    if (self->ascending) {
+      if (self->on_visible_node) {
+        LOG(
+          "leave node. depth:%u, type:%s\n",
+          self->depth,
+          ts_node_type(ts_tree_cursor_current_node(&self->cursor))
+        );
+
+        // After leaving a node, remove any states that cannot make further progress.
+        uint32_t deleted_count = 0;
+        for (unsigned i = 0, n = self->states.size; i < n; i++) {
+          QueryState *state = &self->states.contents[i];
+          QueryStep *step = &self->query->steps.contents[state->step_index];
+
+          // If a state completed its pattern inside of this node, but was deferred from finishing
+          // in order to search for longer matches, mark it as finished.
+          if (
+            step->depth == PATTERN_DONE_MARKER &&
+            (state->start_depth > self->depth || self->depth == 0)
+          ) {
+            LOG("  finish pattern %u\n", state->pattern_index);
+            array_push(&self->finished_states, *state);
+            did_match = true;
+            deleted_count++;
+          }
+
+          // If a state needed to match something within this node, then remove that state
+          // as it has failed to match.
+          else if (
+            step->depth != PATTERN_DONE_MARKER &&
+            (uint32_t)state->start_depth + (uint32_t)step->depth > self->depth
+          ) {
+            LOG(
+              "  failed to match. pattern:%u, step:%u\n",
+              state->pattern_index,
+              state->step_index
+            );
+            capture_list_pool_release(
+              &self->capture_list_pool,
+              state->capture_list_id
+            );
+            deleted_count++;
+          }
+
+          else if (deleted_count > 0) {
+            self->states.contents[i - deleted_count] = *state;
+          }
+        }
+        self->states.size -= deleted_count;
+      }
+
+      // Leave this node by stepping to its next sibling or to its parent.
+      switch (ts_tree_cursor_goto_next_sibling_internal(&self->cursor)) {
+        case TreeCursorStepVisible:
+          if (!self->on_visible_node) {
+            self->depth++;
+            self->on_visible_node = true;
+          }
+          self->ascending = false;
+          break;
+        case TreeCursorStepHidden:
+          if (self->on_visible_node) {
+            self->depth--;
+            self->on_visible_node = false;
+          }
+          self->ascending = false;
+          break;
+        default:
+          if (ts_tree_cursor_goto_parent(&self->cursor)) {
+            self->depth--;
+          } else {
+            LOG("halt at root\n");
+            self->halted = true;
+          }
+      }
+    }
+
+    // Enter a new node.
+    else {
+      // Get the properties of the current node.
+      TSNode node = ts_tree_cursor_current_node(&self->cursor);
+      TSNode parent_node = ts_tree_cursor_parent_node(&self->cursor);
+
+      uint32_t start_byte = ts_node_start_byte(node);
+      uint32_t end_byte = ts_node_end_byte(node);
+      TSPoint start_point = ts_node_start_point(node);
+      TSPoint end_point = ts_node_end_point(node);
+      bool is_empty = start_byte == end_byte;
+
+      bool parent_precedes_range = !ts_node_is_null(parent_node) && (
+        ts_node_end_byte(parent_node) <= self->start_byte ||
+        point_lte(ts_node_end_point(parent_node), self->start_point)
+      );
+      bool parent_follows_range = !ts_node_is_null(parent_node) && (
+        ts_node_start_byte(parent_node) >= self->end_byte ||
+        point_gte(ts_node_start_point(parent_node), self->end_point)
+      );
+      bool node_precedes_range =
+        parent_precedes_range ||
+        end_byte < self->start_byte ||
+        point_lt(end_point, self->start_point) ||
+        (!is_empty && end_byte == self->start_byte) ||
+        (!is_empty && point_eq(end_point, self->start_point));
+
+      bool node_follows_range = parent_follows_range || (
+        start_byte >= self->end_byte ||
+        point_gte(start_point, self->end_point)
+      );
+      bool parent_intersects_range = !parent_precedes_range && !parent_follows_range;
+      bool node_intersects_range = !node_precedes_range && !node_follows_range;
+
+      if (self->on_visible_node) {
+        TSSymbol symbol = ts_node_symbol(node);
+        bool is_named = ts_node_is_named(node);
+        bool has_later_siblings;
+        bool has_later_named_siblings;
+        bool can_have_later_siblings_with_this_field;
+        TSFieldId field_id = 0;
+        TSSymbol supertypes[8] = {0};
+        unsigned supertype_count = 8;
+        ts_tree_cursor_current_status(
+          &self->cursor,
+          &field_id,
+          &has_later_siblings,
+          &has_later_named_siblings,
+          &can_have_later_siblings_with_this_field,
+          supertypes,
+          &supertype_count
+        );
+        LOG(
+          "enter node. depth:%u, type:%s, field:%s, row:%u state_count:%u, finished_state_count:%u\n",
+          self->depth,
+          ts_node_type(node),
+          ts_language_field_name_for_id(self->query->language, field_id),
+          ts_node_start_point(node).row,
+          self->states.size,
+          self->finished_states.size
+        );
+
+        bool node_is_error = symbol == ts_builtin_sym_error;
+        bool parent_is_error =
+          !ts_node_is_null(parent_node) &&
+          ts_node_symbol(parent_node) == ts_builtin_sym_error;
+
+        // Add new states for any patterns whose root node is a wildcard.
+        if (!node_is_error) {
+          for (unsigned i = 0; i < self->query->wildcard_root_pattern_count; i++) {
+            PatternEntry *pattern = &self->query->pattern_map.contents[i];
+
+            // If this node matches the first step of the pattern, then add a new
+            // state at the start of this pattern.
+            QueryStep *step = &self->query->steps.contents[pattern->step_index];
+            uint32_t start_depth = self->depth - step->depth;
+            if (
+              (pattern->is_rooted ?
+                node_intersects_range :
+                (parent_intersects_range && !parent_is_error)) &&
+              (!step->field || field_id == step->field) &&
+              (!step->supertype_symbol || supertype_count > 0) &&
+              (start_depth <= self->max_start_depth)
+            ) {
+              ts_query_cursor__add_state(self, pattern);
+            }
+          }
+        }
+
+        // Add new states for any patterns whose root node matches this node.
+        unsigned i;
+        if (ts_query__pattern_map_search(self->query, symbol, &i)) {
+          PatternEntry *pattern = &self->query->pattern_map.contents[i];
+
+          QueryStep *step = &self->query->steps.contents[pattern->step_index];
+          uint32_t start_depth = self->depth - step->depth;
+          do {
+            // If this node matches the first step of the pattern, then add a new
+            // state at the start of this pattern.
+            if (
+              (pattern->is_rooted ?
+                node_intersects_range :
+                (parent_intersects_range && !parent_is_error)) &&
+              (!step->field || field_id == step->field) &&
+              (start_depth <= self->max_start_depth)
+            ) {
+              ts_query_cursor__add_state(self, pattern);
+            }
+
+            // Advance to the next pattern whose root node matches this node.
+            i++;
+            if (i == self->query->pattern_map.size) break;
+            pattern = &self->query->pattern_map.contents[i];
+            step = &self->query->steps.contents[pattern->step_index];
+          } while (step->symbol == symbol);
+        }
+
+        // Update all of the in-progress states with current node.
+        for (unsigned j = 0, copy_count = 0; j < self->states.size; j += 1 + copy_count) {
+          QueryState *state = &self->states.contents[j];
+          QueryStep *step = &self->query->steps.contents[state->step_index];
+          state->has_in_progress_alternatives = false;
+          copy_count = 0;
+
+          // Check that the node matches all of the criteria for the next
+          // step of the pattern.
+          if ((uint32_t)state->start_depth + (uint32_t)step->depth != self->depth) continue;
+
+          // Determine if this node matches this step of the pattern, and also
+          // if this node can have later siblings that match this step of the
+          // pattern.
+          bool node_does_match = false;
+          if (step->symbol == WILDCARD_SYMBOL) {
+            node_does_match = !node_is_error && (is_named || !step->is_named);
+          } else {
+            node_does_match = symbol == step->symbol;
+          }
+          bool later_sibling_can_match = has_later_siblings;
+          if ((step->is_immediate && is_named) || state->seeking_immediate_match) {
+            later_sibling_can_match = false;
+          }
+          if (step->is_last_child && has_later_named_siblings) {
+            node_does_match = false;
+          }
+          if (step->supertype_symbol) {
+            bool has_supertype = false;
+            for (unsigned k = 0; k < supertype_count; k++) {
+              if (supertypes[k] == step->supertype_symbol) {
+                has_supertype = true;
+                break;
+              }
+            }
+            if (!has_supertype) node_does_match = false;
+          }
+          if (step->field) {
+            if (step->field == field_id) {
+              if (!can_have_later_siblings_with_this_field) {
+                later_sibling_can_match = false;
+              }
+            } else {
+              node_does_match = false;
+            }
+          }
+
+          if (step->negated_field_list_id) {
+            TSFieldId *negated_field_ids = &self->query->negated_fields.contents[step->negated_field_list_id];
+            for (;;) {
+              TSFieldId negated_field_id = *negated_field_ids;
+              if (negated_field_id) {
+                negated_field_ids++;
+                if (ts_node_child_by_field_id(node, negated_field_id).id) {
+                  node_does_match = false;
+                  break;
+                }
+              } else {
+                break;
+              }
+            }
+          }
+
+          // Remove states immediately if it is ever clear that they cannot match.
+          if (!node_does_match) {
+            if (!later_sibling_can_match) {
+              LOG(
+                "  discard state. pattern:%u, step:%u\n",
+                state->pattern_index,
+                state->step_index
+              );
+              capture_list_pool_release(
+                &self->capture_list_pool,
+                state->capture_list_id
+              );
+              array_erase(&self->states, j);
+              j--;
+            }
+            continue;
+          }
+
+          // Some patterns can match their root node in multiple ways, capturing different
+          // children. If this pattern step could match later children within the same
+          // parent, then this query state cannot simply be updated in place. It must be
+          // split into two states: one that matches this node, and one which skips over
+          // this node, to preserve the possibility of matching later siblings.
+          if (later_sibling_can_match && (
+            step->contains_captures ||
+            ts_query__step_is_fallible(self->query, state->step_index)
+          )) {
+            if (ts_query_cursor__copy_state(self, &state)) {
+              LOG(
+                "  split state for capture. pattern:%u, step:%u\n",
+                state->pattern_index,
+                state->step_index
+              );
+              copy_count++;
+            }
+          }
+
+          // If this pattern started with a wildcard, such that the pattern map
+          // actually points to the *second* step of the pattern, then check
+          // that the node has a parent, and capture the parent node if necessary.
+          if (state->needs_parent) {
+            TSNode parent = ts_tree_cursor_parent_node(&self->cursor);
+            if (ts_node_is_null(parent)) {
+              LOG("  missing parent node\n");
+              state->dead = true;
+            } else {
+              state->needs_parent = false;
+              QueryStep *skipped_wildcard_step = step;
+              do {
+                skipped_wildcard_step--;
+              } while (
+                skipped_wildcard_step->is_dead_end ||
+                skipped_wildcard_step->is_pass_through ||
+                skipped_wildcard_step->depth > 0
+              );
+              if (skipped_wildcard_step->capture_ids[0] != NONE) {
+                LOG("  capture wildcard parent\n");
+                ts_query_cursor__capture(
+                  self,
+                  state,
+                  skipped_wildcard_step,
+                  parent
+                );
+              }
+            }
+          }
+
+          // If the current node is captured in this pattern, add it to the capture list.
+          if (step->capture_ids[0] != NONE) {
+            ts_query_cursor__capture(self, state, step, node);
+          }
+
+          if (state->dead) {
+            array_erase(&self->states, j);
+            j--;
+            continue;
+          }
+
+          // Advance this state to the next step of its pattern.
+          state->step_index++;
+          state->seeking_immediate_match = false;
+          LOG(
+            "  advance state. pattern:%u, step:%u\n",
+            state->pattern_index,
+            state->step_index
+          );
+
+          QueryStep *next_step = &self->query->steps.contents[state->step_index];
+          if (stop_on_definite_step && next_step->root_pattern_guaranteed) did_match = true;
+
+          // If this state's next step has an alternative step, then copy the state in order
+          // to pursue both alternatives. The alternative step itself may have an alternative,
+          // so this is an interactive process.
+          unsigned end_index = j + 1;
+          for (unsigned k = j; k < end_index; k++) {
+            QueryState *child_state = &self->states.contents[k];
+            QueryStep *child_step = &self->query->steps.contents[child_state->step_index];
+            if (child_step->alternative_index != NONE) {
+              // A "dead-end" step exists only to add a non-sequential jump into the step sequence,
+              // via its alternative index. When a state reaches a dead-end step, it jumps straight
+              // to the step's alternative.
+              if (child_step->is_dead_end) {
+                child_state->step_index = child_step->alternative_index;
+                k--;
+                continue;
+              }
+
+              // A "pass-through" step exists only to add a branch into the step sequence,
+              // via its alternative_index. When a state reaches a pass-through step, it splits
+              // in order to process the alternative step, and then it advances to the next step.
+              if (child_step->is_pass_through) {
+                child_state->step_index++;
+                k--;
+              }
+
+              QueryState *copy = ts_query_cursor__copy_state(self, &child_state);
+              if (copy) {
+                LOG(
+                  "  split state for branch. pattern:%u, from_step:%u, to_step:%u, immediate:%d, capture_count: %u\n",
+                  copy->pattern_index,
+                  copy->step_index,
+                  next_step->alternative_index,
+                  next_step->alternative_is_immediate,
+                  capture_list_pool_get(&self->capture_list_pool, copy->capture_list_id)->size
+                );
+                end_index++;
+                copy_count++;
+                copy->step_index = child_step->alternative_index;
+                if (child_step->alternative_is_immediate) {
+                  copy->seeking_immediate_match = true;
+                }
+              }
+            }
+          }
+        }
+
+        for (unsigned j = 0; j < self->states.size; j++) {
+          QueryState *state = &self->states.contents[j];
+          if (state->dead) {
+            array_erase(&self->states, j);
+            j--;
+            continue;
+          }
+
+          // Enforce the longest-match criteria. When a query pattern contains optional or
+          // repeated nodes, this is necessary to avoid multiple redundant states, where
+          // one state has a strict subset of another state's captures.
+          bool did_remove = false;
+          for (unsigned k = j + 1; k < self->states.size; k++) {
+            QueryState *other_state = &self->states.contents[k];
+
+            // Query states are kept in ascending order of start_depth and pattern_index.
+            // Since the longest-match criteria is only used for deduping matches of the same
+            // pattern and root node, we only need to perform pairwise comparisons within a
+            // small slice of the states array.
+            if (
+              other_state->start_depth != state->start_depth ||
+              other_state->pattern_index != state->pattern_index
+            ) break;
+
+            bool left_contains_right, right_contains_left;
+            ts_query_cursor__compare_captures(
+              self,
+              state,
+              other_state,
+              &left_contains_right,
+              &right_contains_left
+            );
+            if (left_contains_right) {
+              if (state->step_index == other_state->step_index) {
+                LOG(
+                  "  drop shorter state. pattern: %u, step_index: %u\n",
+                  state->pattern_index,
+                  state->step_index
+                );
+                capture_list_pool_release(&self->capture_list_pool, other_state->capture_list_id);
+                array_erase(&self->states, k);
+                k--;
+                continue;
+              }
+              other_state->has_in_progress_alternatives = true;
+            }
+            if (right_contains_left) {
+              if (state->step_index == other_state->step_index) {
+                LOG(
+                  "  drop shorter state. pattern: %u, step_index: %u\n",
+                  state->pattern_index,
+                  state->step_index
+                );
+                capture_list_pool_release(&self->capture_list_pool, state->capture_list_id);
+                array_erase(&self->states, j);
+                j--;
+                did_remove = true;
+                break;
+              }
+              state->has_in_progress_alternatives = true;
+            }
+          }
+
+          // If the state is at the end of its pattern, remove it from the list
+          // of in-progress states and add it to the list of finished states.
+          if (!did_remove) {
+            LOG(
+              "  keep state. pattern: %u, start_depth: %u, step_index: %u, capture_count: %u\n",
+              state->pattern_index,
+              state->start_depth,
+              state->step_index,
+              capture_list_pool_get(&self->capture_list_pool, state->capture_list_id)->size
+            );
+            QueryStep *next_step = &self->query->steps.contents[state->step_index];
+            if (next_step->depth == PATTERN_DONE_MARKER) {
+              if (state->has_in_progress_alternatives) {
+                LOG("  defer finishing pattern %u\n", state->pattern_index);
+              } else {
+                LOG("  finish pattern %u\n", state->pattern_index);
+                array_push(&self->finished_states, *state);
+                array_erase(&self->states, (uint32_t)(state - self->states.contents));
+                did_match = true;
+                j--;
+              }
+            }
+          }
+        }
+      }
+
+      if (ts_query_cursor__should_descend(self, node_intersects_range)) {
+        switch (ts_tree_cursor_goto_first_child_internal(&self->cursor)) {
+          case TreeCursorStepVisible:
+            self->depth++;
+            self->on_visible_node = true;
+            continue;
+          case TreeCursorStepHidden:
+            self->on_visible_node = false;
+            continue;
+          default:
+            break;
+        }
+      }
+
+      self->ascending = true;
+    }
+  }
+}
+
+bool ts_query_cursor_next_match(
+  TSQueryCursor *self,
+  TSQueryMatch *match
+) {
+  if (self->finished_states.size == 0) {
+    if (!ts_query_cursor__advance(self, false)) {
+      return false;
+    }
+  }
+
+  QueryState *state = &self->finished_states.contents[0];
+  if (state->id == UINT32_MAX) state->id = self->next_state_id++;
+  match->id = state->id;
+  match->pattern_index = state->pattern_index;
+  const CaptureList *captures = capture_list_pool_get(
+    &self->capture_list_pool,
+    state->capture_list_id
+  );
+  match->captures = captures->contents;
+  match->capture_count = captures->size;
+  capture_list_pool_release(&self->capture_list_pool, state->capture_list_id);
+  array_erase(&self->finished_states, 0);
+  return true;
+}
+
+void ts_query_cursor_remove_match(
+  TSQueryCursor *self,
+  uint32_t match_id
+) {
+  for (unsigned i = 0; i < self->finished_states.size; i++) {
+    const QueryState *state = &self->finished_states.contents[i];
+    if (state->id == match_id) {
+      capture_list_pool_release(
+        &self->capture_list_pool,
+        state->capture_list_id
+      );
+      array_erase(&self->finished_states, i);
+      return;
+    }
+  }
+
+  // Remove unfinished query states as well to prevent future
+  // captures for a match being removed.
+  for (unsigned i = 0; i < self->states.size; i++) {
+    const QueryState *state = &self->states.contents[i];
+    if (state->id == match_id) {
+      capture_list_pool_release(
+        &self->capture_list_pool,
+        state->capture_list_id
+      );
+      array_erase(&self->states, i);
+      return;
+    }
+  }
+}
+
+bool ts_query_cursor_next_capture(
+  TSQueryCursor *self,
+  TSQueryMatch *match,
+  uint32_t *capture_index
+) {
+  // The goal here is to return captures in order, even though they may not
+  // be discovered in order, because patterns can overlap. Search for matches
+  // until there is a finished capture that is before any unfinished capture.
+  for (;;) {
+    // First, find the earliest capture in an unfinished match.
+    uint32_t first_unfinished_capture_byte;
+    uint32_t first_unfinished_pattern_index;
+    uint32_t first_unfinished_state_index;
+    bool first_unfinished_state_is_definite = false;
+    bool found_unfinished_state = ts_query_cursor__first_in_progress_capture(
+      self,
+      &first_unfinished_state_index,
+      &first_unfinished_capture_byte,
+      &first_unfinished_pattern_index,
+      &first_unfinished_state_is_definite
+    );
+
+    // Then find the earliest capture in a finished match. It must occur
+    // before the first capture in an *unfinished* match.
+    QueryState *first_finished_state = NULL;
+    uint32_t first_finished_capture_byte = first_unfinished_capture_byte;
+    uint32_t first_finished_pattern_index = first_unfinished_pattern_index;
+    for (unsigned i = 0; i < self->finished_states.size;) {
+      QueryState *state = &self->finished_states.contents[i];
+      const CaptureList *captures = capture_list_pool_get(
+        &self->capture_list_pool,
+        state->capture_list_id
+      );
+
+      // Remove states whose captures are all consumed.
+      if (state->consumed_capture_count >= captures->size) {
+        capture_list_pool_release(
+          &self->capture_list_pool,
+          state->capture_list_id
+        );
+        array_erase(&self->finished_states, i);
+        continue;
+      }
+
+      TSNode node = captures->contents[state->consumed_capture_count].node;
+
+      bool node_precedes_range = (
+        ts_node_end_byte(node) <= self->start_byte ||
+        point_lte(ts_node_end_point(node), self->start_point)
+      );
+      bool node_follows_range = (
+        ts_node_start_byte(node) >= self->end_byte ||
+        point_gte(ts_node_start_point(node), self->end_point)
+      );
+      bool node_outside_of_range = node_precedes_range || node_follows_range;
+
+      // Skip captures that are outside of the cursor's range.
+      if (node_outside_of_range) {
+        state->consumed_capture_count++;
+        continue;
+      }
+
+      uint32_t node_start_byte = ts_node_start_byte(node);
+      if (
+        node_start_byte < first_finished_capture_byte ||
+        (
+          node_start_byte == first_finished_capture_byte &&
+          state->pattern_index < first_finished_pattern_index
+        )
+      ) {
+        first_finished_state = state;
+        first_finished_capture_byte = node_start_byte;
+        first_finished_pattern_index = state->pattern_index;
+      }
+      i++;
+    }
+
+    // If there is finished capture that is clearly before any unfinished
+    // capture, then return its match, and its capture index. Internally
+    // record the fact that the capture has been 'consumed'.
+    QueryState *state;
+    if (first_finished_state) {
+      state = first_finished_state;
+    } else if (first_unfinished_state_is_definite) {
+      state = &self->states.contents[first_unfinished_state_index];
+    } else {
+      state = NULL;
+    }
+
+    if (state) {
+      if (state->id == UINT32_MAX) state->id = self->next_state_id++;
+      match->id = state->id;
+      match->pattern_index = state->pattern_index;
+      const CaptureList *captures = capture_list_pool_get(
+        &self->capture_list_pool,
+        state->capture_list_id
+      );
+      match->captures = captures->contents;
+      match->capture_count = captures->size;
+      *capture_index = state->consumed_capture_count;
+      state->consumed_capture_count++;
+      return true;
+    }
+
+    if (capture_list_pool_is_empty(&self->capture_list_pool) && found_unfinished_state) {
+      LOG(
+        "  abandon state. index:%u, pattern:%u, offset:%u.\n",
+        first_unfinished_state_index,
+        first_unfinished_pattern_index,
+        first_unfinished_capture_byte
+      );
+      capture_list_pool_release(
+        &self->capture_list_pool,
+        self->states.contents[first_unfinished_state_index].capture_list_id
+      );
+      array_erase(&self->states, first_unfinished_state_index);
+    }
+
+    // If there are no finished matches that are ready to be returned, then
+    // continue finding more matches.
+    if (
+      !ts_query_cursor__advance(self, true) &&
+      self->finished_states.size == 0
+    ) return false;
+  }
+}
+
+void ts_query_cursor_set_max_start_depth(
+  TSQueryCursor *self,
+  uint32_t max_start_depth
+) {
+  self->max_start_depth = max_start_depth;
+}
+
+#undef LOG
diff --git a/vendor/tree-sitter/lib/src/reduce_action.h b/vendor/tree-sitter/lib/src/reduce_action.h
new file mode 100644
--- /dev/null
+++ b/vendor/tree-sitter/lib/src/reduce_action.h
@@ -0,0 +1,34 @@
+#ifndef TREE_SITTER_REDUCE_ACTION_H_
+#define TREE_SITTER_REDUCE_ACTION_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "./array.h"
+#include "tree_sitter/api.h"
+
+typedef struct {
+  uint32_t count;
+  TSSymbol symbol;
+  int dynamic_precedence;
+  unsigned short production_id;
+} ReduceAction;
+
+typedef Array(ReduceAction) ReduceActionSet;
+
+static inline void ts_reduce_action_set_add(ReduceActionSet *self,
+                                            ReduceAction new_action) {
+  for (uint32_t i = 0; i < self->size; i++) {
+    ReduceAction action = self->contents[i];
+    if (action.symbol == new_action.symbol && action.count == new_action.count)
+      return;
+  }
+  array_push(self, new_action);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  // TREE_SITTER_REDUCE_ACTION_H_
diff --git a/vendor/tree-sitter/lib/src/reusable_node.h b/vendor/tree-sitter/lib/src/reusable_node.h
new file mode 100644
--- /dev/null
+++ b/vendor/tree-sitter/lib/src/reusable_node.h
@@ -0,0 +1,95 @@
+#include "./subtree.h"
+
+typedef struct {
+  Subtree tree;
+  uint32_t child_index;
+  uint32_t byte_offset;
+} StackEntry;
+
+typedef struct {
+  Array(StackEntry) stack;
+  Subtree last_external_token;
+} ReusableNode;
+
+static inline ReusableNode reusable_node_new(void) {
+  return (ReusableNode) {array_new(), NULL_SUBTREE};
+}
+
+static inline void reusable_node_clear(ReusableNode *self) {
+  array_clear(&self->stack);
+  self->last_external_token = NULL_SUBTREE;
+}
+
+static inline Subtree reusable_node_tree(ReusableNode *self) {
+  return self->stack.size > 0
+    ? self->stack.contents[self->stack.size - 1].tree
+    : NULL_SUBTREE;
+}
+
+static inline uint32_t reusable_node_byte_offset(ReusableNode *self) {
+  return self->stack.size > 0
+    ? self->stack.contents[self->stack.size - 1].byte_offset
+    : UINT32_MAX;
+}
+
+static inline void reusable_node_delete(ReusableNode *self) {
+  array_delete(&self->stack);
+}
+
+static inline void reusable_node_advance(ReusableNode *self) {
+  StackEntry last_entry = *array_back(&self->stack);
+  uint32_t byte_offset = last_entry.byte_offset + ts_subtree_total_bytes(last_entry.tree);
+  if (ts_subtree_has_external_tokens(last_entry.tree)) {
+    self->last_external_token = ts_subtree_last_external_token(last_entry.tree);
+  }
+
+  Subtree tree;
+  uint32_t next_index;
+  do {
+    StackEntry popped_entry = array_pop(&self->stack);
+    next_index = popped_entry.child_index + 1;
+    if (self->stack.size == 0) return;
+    tree = array_back(&self->stack)->tree;
+  } while (ts_subtree_child_count(tree) <= next_index);
+
+  array_push(&self->stack, ((StackEntry) {
+    .tree = ts_subtree_children(tree)[next_index],
+    .child_index = next_index,
+    .byte_offset = byte_offset,
+  }));
+}
+
+static inline bool reusable_node_descend(ReusableNode *self) {
+  StackEntry last_entry = *array_back(&self->stack);
+  if (ts_subtree_child_count(last_entry.tree) > 0) {
+    array_push(&self->stack, ((StackEntry) {
+      .tree = ts_subtree_children(last_entry.tree)[0],
+      .child_index = 0,
+      .byte_offset = last_entry.byte_offset,
+    }));
+    return true;
+  } else {
+    return false;
+  }
+}
+
+static inline void reusable_node_advance_past_leaf(ReusableNode *self) {
+  while (reusable_node_descend(self)) {}
+  reusable_node_advance(self);
+}
+
+static inline void reusable_node_reset(ReusableNode *self, Subtree tree) {
+  reusable_node_clear(self);
+  array_push(&self->stack, ((StackEntry) {
+    .tree = tree,
+    .child_index = 0,
+    .byte_offset = 0,
+  }));
+
+  // Never reuse the root node, because it has a non-standard internal structure
+  // due to transformations that are applied when it is accepted: adding the EOF
+  // child and any extra children.
+  if (!reusable_node_descend(self)) {
+    reusable_node_clear(self);
+  }
+}
diff --git a/vendor/tree-sitter/lib/src/stack.c b/vendor/tree-sitter/lib/src/stack.c
new file mode 100644
--- /dev/null
+++ b/vendor/tree-sitter/lib/src/stack.c
@@ -0,0 +1,899 @@
+#include "./alloc.h"
+#include "./language.h"
+#include "./subtree.h"
+#include "./array.h"
+#include "./stack.h"
+#include "./length.h"
+#include <assert.h>
+#include <inttypes.h>
+#include <stdio.h>
+
+#define MAX_LINK_COUNT 8
+#define MAX_NODE_POOL_SIZE 50
+#define MAX_ITERATOR_COUNT 64
+
+#if defined _WIN32 && !defined __GNUC__
+#define forceinline __forceinline
+#else
+#define forceinline static inline __attribute__((always_inline))
+#endif
+
+typedef struct StackNode StackNode;
+
+typedef struct {
+  StackNode *node;
+  Subtree subtree;
+  bool is_pending;
+} StackLink;
+
+struct StackNode {
+  TSStateId state;
+  Length position;
+  StackLink links[MAX_LINK_COUNT];
+  short unsigned int link_count;
+  uint32_t ref_count;
+  unsigned error_cost;
+  unsigned node_count;
+  int dynamic_precedence;
+};
+
+typedef struct {
+  StackNode *node;
+  SubtreeArray subtrees;
+  uint32_t subtree_count;
+  bool is_pending;
+} StackIterator;
+
+typedef Array(StackNode *) StackNodeArray;
+
+typedef enum {
+  StackStatusActive,
+  StackStatusPaused,
+  StackStatusHalted,
+} StackStatus;
+
+typedef struct {
+  StackNode *node;
+  StackSummary *summary;
+  unsigned node_count_at_last_error;
+  Subtree last_external_token;
+  Subtree lookahead_when_paused;
+  StackStatus status;
+} StackHead;
+
+struct Stack {
+  Array(StackHead) heads;
+  StackSliceArray slices;
+  Array(StackIterator) iterators;
+  StackNodeArray node_pool;
+  StackNode *base_node;
+  SubtreePool *subtree_pool;
+};
+
+typedef unsigned StackAction;
+enum {
+  StackActionNone,
+  StackActionStop = 1,
+  StackActionPop = 2,
+};
+
+typedef StackAction (*StackCallback)(void *, const StackIterator *);
+
+static void stack_node_retain(StackNode *self) {
+  if (!self)
+    return;
+  ts_assert(self->ref_count > 0);
+  self->ref_count++;
+  ts_assert(self->ref_count != 0);
+}
+
+static void stack_node_release(
+  StackNode *self,
+  StackNodeArray *pool,
+  SubtreePool *subtree_pool
+) {
+recur:
+  ts_assert(self->ref_count != 0);
+  self->ref_count--;
+  if (self->ref_count > 0) return;
+
+  StackNode *first_predecessor = NULL;
+  if (self->link_count > 0) {
+    for (unsigned i = self->link_count - 1; i > 0; i--) {
+      StackLink link = self->links[i];
+      if (link.subtree.ptr) ts_subtree_release(subtree_pool, link.subtree);
+      stack_node_release(link.node, pool, subtree_pool);
+    }
+    StackLink link = self->links[0];
+    if (link.subtree.ptr) ts_subtree_release(subtree_pool, link.subtree);
+    first_predecessor = self->links[0].node;
+  }
+
+  if (pool->size < MAX_NODE_POOL_SIZE) {
+    array_push(pool, self);
+  } else {
+    ts_free(self);
+  }
+
+  if (first_predecessor) {
+    self = first_predecessor;
+    goto recur;
+  }
+}
+
+/// Get the number of nodes in the subtree, for the purpose of measuring
+/// how much progress has been made by a given version of the stack.
+static uint32_t stack__subtree_node_count(Subtree subtree) {
+  uint32_t count = ts_subtree_visible_descendant_count(subtree);
+  if (ts_subtree_visible(subtree)) count++;
+
+  // Count intermediate error nodes even though they are not visible,
+  // because a stack version's node count is used to check whether it
+  // has made any progress since the last time it encountered an error.
+  if (ts_subtree_symbol(subtree) == ts_builtin_sym_error_repeat) count++;
+
+  return count;
+}
+
+static StackNode *stack_node_new(
+  StackNode *previous_node,
+  Subtree subtree,
+  bool is_pending,
+  TSStateId state,
+  StackNodeArray *pool
+) {
+  StackNode *node = pool->size > 0
+    ? array_pop(pool)
+    : ts_malloc(sizeof(StackNode));
+  *node = (StackNode) {
+    .ref_count = 1,
+    .link_count = 0,
+    .state = state
+  };
+
+  if (previous_node) {
+    node->link_count = 1;
+    node->links[0] = (StackLink) {
+      .node = previous_node,
+      .subtree = subtree,
+      .is_pending = is_pending,
+    };
+
+    node->position = previous_node->position;
+    node->error_cost = previous_node->error_cost;
+    node->dynamic_precedence = previous_node->dynamic_precedence;
+    node->node_count = previous_node->node_count;
+
+    if (subtree.ptr) {
+      node->error_cost += ts_subtree_error_cost(subtree);
+      node->position = length_add(node->position, ts_subtree_total_size(subtree));
+      node->node_count += stack__subtree_node_count(subtree);
+      node->dynamic_precedence += ts_subtree_dynamic_precedence(subtree);
+    }
+  } else {
+    node->position = length_zero();
+    node->error_cost = 0;
+  }
+
+  return node;
+}
+
+static bool stack__subtree_is_equivalent(Subtree left, Subtree right) {
+  if (left.ptr == right.ptr) return true;
+  if (!left.ptr || !right.ptr) return false;
+
+  // Symbols must match
+  if (ts_subtree_symbol(left) != ts_subtree_symbol(right)) return false;
+
+  // If both have errors, don't bother keeping both.
+  if (ts_subtree_error_cost(left) > 0 && ts_subtree_error_cost(right) > 0) return true;
+
+  return (
+    ts_subtree_padding(left).bytes == ts_subtree_padding(right).bytes &&
+    ts_subtree_size(left).bytes == ts_subtree_size(right).bytes &&
+    ts_subtree_child_count(left) == ts_subtree_child_count(right) &&
+    ts_subtree_extra(left) == ts_subtree_extra(right) &&
+    ts_subtree_external_scanner_state_eq(left, right)
+  );
+}
+
+static void stack_node_add_link(
+  StackNode *self,
+  StackLink link,
+  SubtreePool *subtree_pool
+) {
+  if (link.node == self) return;
+
+  for (int i = 0; i < self->link_count; i++) {
+    StackLink *existing_link = &self->links[i];
+    if (stack__subtree_is_equivalent(existing_link->subtree, link.subtree)) {
+      // In general, we preserve ambiguities until they are removed from the stack
+      // during a pop operation where multiple paths lead to the same node. But in
+      // the special case where two links directly connect the same pair of nodes,
+      // we can safely remove the ambiguity ahead of time without changing behavior.
+      if (existing_link->node == link.node) {
+        if (
+          ts_subtree_dynamic_precedence(link.subtree) >
+          ts_subtree_dynamic_precedence(existing_link->subtree)
+        ) {
+          ts_subtree_retain(link.subtree);
+          ts_subtree_release(subtree_pool, existing_link->subtree);
+          existing_link->subtree = link.subtree;
+          self->dynamic_precedence =
+            link.node->dynamic_precedence + ts_subtree_dynamic_precedence(link.subtree);
+        }
+        return;
+      }
+
+      // If the previous nodes are mergeable, merge them recursively.
+      if (
+        existing_link->node->state == link.node->state &&
+        existing_link->node->position.bytes == link.node->position.bytes &&
+        existing_link->node->error_cost == link.node->error_cost
+      ) {
+        for (int j = 0; j < link.node->link_count; j++) {
+          stack_node_add_link(existing_link->node, link.node->links[j], subtree_pool);
+        }
+        int32_t dynamic_precedence = link.node->dynamic_precedence;
+        if (link.subtree.ptr) {
+          dynamic_precedence += ts_subtree_dynamic_precedence(link.subtree);
+        }
+        if (dynamic_precedence > self->dynamic_precedence) {
+          self->dynamic_precedence = dynamic_precedence;
+        }
+        return;
+      }
+    }
+  }
+
+  if (self->link_count == MAX_LINK_COUNT) return;
+
+  stack_node_retain(link.node);
+  unsigned node_count = link.node->node_count;
+  int dynamic_precedence = link.node->dynamic_precedence;
+  self->links[self->link_count++] = link;
+
+  if (link.subtree.ptr) {
+    ts_subtree_retain(link.subtree);
+    node_count += stack__subtree_node_count(link.subtree);
+    dynamic_precedence += ts_subtree_dynamic_precedence(link.subtree);
+  }
+
+  if (node_count > self->node_count) self->node_count = node_count;
+  if (dynamic_precedence > self->dynamic_precedence) self->dynamic_precedence = dynamic_precedence;
+}
+
+static void stack_head_delete(
+  StackHead *self,
+  StackNodeArray *pool,
+  SubtreePool *subtree_pool
+) {
+  if (self->node) {
+    if (self->last_external_token.ptr) {
+      ts_subtree_release(subtree_pool, self->last_external_token);
+    }
+    if (self->lookahead_when_paused.ptr) {
+      ts_subtree_release(subtree_pool, self->lookahead_when_paused);
+    }
+    if (self->summary) {
+      array_delete(self->summary);
+      ts_free(self->summary);
+    }
+    stack_node_release(self->node, pool, subtree_pool);
+  }
+}
+
+static StackVersion ts_stack__add_version(
+  Stack *self,
+  StackVersion original_version,
+  StackNode *node
+) {
+  StackHead head = {
+    .node = node,
+    .node_count_at_last_error = self->heads.contents[original_version].node_count_at_last_error,
+    .last_external_token = self->heads.contents[original_version].last_external_token,
+    .status = StackStatusActive,
+    .lookahead_when_paused = NULL_SUBTREE,
+  };
+  array_push(&self->heads, head);
+  stack_node_retain(node);
+  if (head.last_external_token.ptr) ts_subtree_retain(head.last_external_token);
+  return (StackVersion)(self->heads.size - 1);
+}
+
+static void ts_stack__add_slice(
+  Stack *self,
+  StackVersion original_version,
+  StackNode *node,
+  SubtreeArray *subtrees
+) {
+  for (uint32_t i = self->slices.size - 1; i + 1 > 0; i--) {
+    StackVersion version = self->slices.contents[i].version;
+    if (self->heads.contents[version].node == node) {
+      StackSlice slice = {*subtrees, version};
+      array_insert(&self->slices, i + 1, slice);
+      return;
+    }
+  }
+
+  StackVersion version = ts_stack__add_version(self, original_version, node);
+  StackSlice slice = { *subtrees, version };
+  array_push(&self->slices, slice);
+}
+
+static StackSliceArray stack__iter(
+  Stack *self,
+  StackVersion version,
+  StackCallback callback,
+  void *payload,
+  int goal_subtree_count
+) {
+  array_clear(&self->slices);
+  array_clear(&self->iterators);
+
+  StackHead *head = array_get(&self->heads, version);
+  StackIterator new_iterator = {
+    .node = head->node,
+    .subtrees = array_new(),
+    .subtree_count = 0,
+    .is_pending = true,
+  };
+
+  bool include_subtrees = false;
+  if (goal_subtree_count >= 0) {
+    include_subtrees = true;
+    array_reserve(&new_iterator.subtrees, (uint32_t)ts_subtree_alloc_size(goal_subtree_count) / sizeof(Subtree));
+  }
+
+  array_push(&self->iterators, new_iterator);
+
+  while (self->iterators.size > 0) {
+    for (uint32_t i = 0, size = self->iterators.size; i < size; i++) {
+      StackIterator *iterator = &self->iterators.contents[i];
+      StackNode *node = iterator->node;
+
+      StackAction action = callback(payload, iterator);
+      bool should_pop = action & StackActionPop;
+      bool should_stop = action & StackActionStop || node->link_count == 0;
+
+      if (should_pop) {
+        SubtreeArray subtrees = iterator->subtrees;
+        if (!should_stop) {
+          ts_subtree_array_copy(subtrees, &subtrees);
+        }
+        ts_subtree_array_reverse(&subtrees);
+        ts_stack__add_slice(
+          self,
+          version,
+          node,
+          &subtrees
+        );
+      }
+
+      if (should_stop) {
+        if (!should_pop) {
+          ts_subtree_array_delete(self->subtree_pool, &iterator->subtrees);
+        }
+        array_erase(&self->iterators, i);
+        i--, size--;
+        continue;
+      }
+
+      for (uint32_t j = 1; j <= node->link_count; j++) {
+        StackIterator *next_iterator;
+        StackLink link;
+        if (j == node->link_count) {
+          link = node->links[0];
+          next_iterator = &self->iterators.contents[i];
+        } else {
+          if (self->iterators.size >= MAX_ITERATOR_COUNT) continue;
+          link = node->links[j];
+          StackIterator current_iterator = self->iterators.contents[i];
+          array_push(&self->iterators, current_iterator);
+          next_iterator = array_back(&self->iterators);
+          ts_subtree_array_copy(next_iterator->subtrees, &next_iterator->subtrees);
+        }
+
+        next_iterator->node = link.node;
+        if (link.subtree.ptr) {
+          if (include_subtrees) {
+            array_push(&next_iterator->subtrees, link.subtree);
+            ts_subtree_retain(link.subtree);
+          }
+
+          if (!ts_subtree_extra(link.subtree)) {
+            next_iterator->subtree_count++;
+            if (!link.is_pending) {
+              next_iterator->is_pending = false;
+            }
+          }
+        } else {
+          next_iterator->subtree_count++;
+          next_iterator->is_pending = false;
+        }
+      }
+    }
+  }
+
+  return self->slices;
+}
+
+Stack *ts_stack_new(SubtreePool *subtree_pool) {
+  Stack *self = ts_calloc(1, sizeof(Stack));
+
+  array_init(&self->heads);
+  array_init(&self->slices);
+  array_init(&self->iterators);
+  array_init(&self->node_pool);
+  array_reserve(&self->heads, 4);
+  array_reserve(&self->slices, 4);
+  array_reserve(&self->iterators, 4);
+  array_reserve(&self->node_pool, MAX_NODE_POOL_SIZE);
+
+  self->subtree_pool = subtree_pool;
+  self->base_node = stack_node_new(NULL, NULL_SUBTREE, false, 1, &self->node_pool);
+  ts_stack_clear(self);
+
+  return self;
+}
+
+void ts_stack_delete(Stack *self) {
+  if (self->slices.contents)
+    array_delete(&self->slices);
+  if (self->iterators.contents)
+    array_delete(&self->iterators);
+  stack_node_release(self->base_node, &self->node_pool, self->subtree_pool);
+  for (uint32_t i = 0; i < self->heads.size; i++) {
+    stack_head_delete(&self->heads.contents[i], &self->node_pool, self->subtree_pool);
+  }
+  array_clear(&self->heads);
+  if (self->node_pool.contents) {
+    for (uint32_t i = 0; i < self->node_pool.size; i++)
+      ts_free(self->node_pool.contents[i]);
+    array_delete(&self->node_pool);
+  }
+  array_delete(&self->heads);
+  ts_free(self);
+}
+
+uint32_t ts_stack_version_count(const Stack *self) {
+  return self->heads.size;
+}
+
+TSStateId ts_stack_state(const Stack *self, StackVersion version) {
+  return array_get(&self->heads, version)->node->state;
+}
+
+Length ts_stack_position(const Stack *self, StackVersion version) {
+  return array_get(&self->heads, version)->node->position;
+}
+
+Subtree ts_stack_last_external_token(const Stack *self, StackVersion version) {
+  return array_get(&self->heads, version)->last_external_token;
+}
+
+void ts_stack_set_last_external_token(Stack *self, StackVersion version, Subtree token) {
+  StackHead *head = array_get(&self->heads, version);
+  if (token.ptr) ts_subtree_retain(token);
+  if (head->last_external_token.ptr) ts_subtree_release(self->subtree_pool, head->last_external_token);
+  head->last_external_token = token;
+}
+
+unsigned ts_stack_error_cost(const Stack *self, StackVersion version) {
+  StackHead *head = array_get(&self->heads, version);
+  unsigned result = head->node->error_cost;
+  if (
+    head->status == StackStatusPaused ||
+    (head->node->state == ERROR_STATE && !head->node->links[0].subtree.ptr)) {
+    result += ERROR_COST_PER_RECOVERY;
+  }
+  return result;
+}
+
+unsigned ts_stack_node_count_since_error(const Stack *self, StackVersion version) {
+  StackHead *head = array_get(&self->heads, version);
+  if (head->node->node_count < head->node_count_at_last_error) {
+    head->node_count_at_last_error = head->node->node_count;
+  }
+  return head->node->node_count - head->node_count_at_last_error;
+}
+
+void ts_stack_push(
+  Stack *self,
+  StackVersion version,
+  Subtree subtree,
+  bool pending,
+  TSStateId state
+) {
+  StackHead *head = array_get(&self->heads, version);
+  StackNode *new_node = stack_node_new(head->node, subtree, pending, state, &self->node_pool);
+  if (!subtree.ptr) head->node_count_at_last_error = new_node->node_count;
+  head->node = new_node;
+}
+
+forceinline StackAction pop_count_callback(void *payload, const StackIterator *iterator) {
+  unsigned *goal_subtree_count = payload;
+  if (iterator->subtree_count == *goal_subtree_count) {
+    return StackActionPop | StackActionStop;
+  } else {
+    return StackActionNone;
+  }
+}
+
+StackSliceArray ts_stack_pop_count(Stack *self, StackVersion version, uint32_t count) {
+  return stack__iter(self, version, pop_count_callback, &count, (int)count);
+}
+
+forceinline StackAction pop_pending_callback(void *payload, const StackIterator *iterator) {
+  (void)payload;
+  if (iterator->subtree_count >= 1) {
+    if (iterator->is_pending) {
+      return StackActionPop | StackActionStop;
+    } else {
+      return StackActionStop;
+    }
+  } else {
+    return StackActionNone;
+  }
+}
+
+StackSliceArray ts_stack_pop_pending(Stack *self, StackVersion version) {
+  StackSliceArray pop = stack__iter(self, version, pop_pending_callback, NULL, 0);
+  if (pop.size > 0) {
+    ts_stack_renumber_version(self, pop.contents[0].version, version);
+    pop.contents[0].version = version;
+  }
+  return pop;
+}
+
+forceinline StackAction pop_error_callback(void *payload, const StackIterator *iterator) {
+  if (iterator->subtrees.size > 0) {
+    bool *found_error = payload;
+    if (!*found_error && ts_subtree_is_error(iterator->subtrees.contents[0])) {
+      *found_error = true;
+      return StackActionPop | StackActionStop;
+    } else {
+      return StackActionStop;
+    }
+  } else {
+    return StackActionNone;
+  }
+}
+
+SubtreeArray ts_stack_pop_error(Stack *self, StackVersion version) {
+  StackNode *node = array_get(&self->heads, version)->node;
+  for (unsigned i = 0; i < node->link_count; i++) {
+    if (node->links[i].subtree.ptr && ts_subtree_is_error(node->links[i].subtree)) {
+      bool found_error = false;
+      StackSliceArray pop = stack__iter(self, version, pop_error_callback, &found_error, 1);
+      if (pop.size > 0) {
+        ts_assert(pop.size == 1);
+        ts_stack_renumber_version(self, pop.contents[0].version, version);
+        return pop.contents[0].subtrees;
+      }
+      break;
+    }
+  }
+  return (SubtreeArray) {.size = 0};
+}
+
+forceinline StackAction pop_all_callback(void *payload, const StackIterator *iterator) {
+  (void)payload;
+  return iterator->node->link_count == 0 ? StackActionPop : StackActionNone;
+}
+
+StackSliceArray ts_stack_pop_all(Stack *self, StackVersion version) {
+  return stack__iter(self, version, pop_all_callback, NULL, 0);
+}
+
+typedef struct {
+  StackSummary *summary;
+  unsigned max_depth;
+} SummarizeStackSession;
+
+forceinline StackAction summarize_stack_callback(void *payload, const StackIterator *iterator) {
+  SummarizeStackSession *session = payload;
+  TSStateId state = iterator->node->state;
+  unsigned depth = iterator->subtree_count;
+  if (depth > session->max_depth) return StackActionStop;
+  for (unsigned i = session->summary->size - 1; i + 1 > 0; i--) {
+    StackSummaryEntry entry = session->summary->contents[i];
+    if (entry.depth < depth) break;
+    if (entry.depth == depth && entry.state == state) return StackActionNone;
+  }
+  array_push(session->summary, ((StackSummaryEntry) {
+    .position = iterator->node->position,
+    .depth = depth,
+    .state = state,
+  }));
+  return StackActionNone;
+}
+
+void ts_stack_record_summary(Stack *self, StackVersion version, unsigned max_depth) {
+  SummarizeStackSession session = {
+    .summary = ts_malloc(sizeof(StackSummary)),
+    .max_depth = max_depth
+  };
+  array_init(session.summary);
+  stack__iter(self, version, summarize_stack_callback, &session, -1);
+  StackHead *head = &self->heads.contents[version];
+  if (head->summary) {
+    array_delete(head->summary);
+    ts_free(head->summary);
+  }
+  head->summary = session.summary;
+}
+
+StackSummary *ts_stack_get_summary(Stack *self, StackVersion version) {
+  return array_get(&self->heads, version)->summary;
+}
+
+int ts_stack_dynamic_precedence(Stack *self, StackVersion version) {
+  return array_get(&self->heads, version)->node->dynamic_precedence;
+}
+
+bool ts_stack_has_advanced_since_error(const Stack *self, StackVersion version) {
+  const StackHead *head = array_get(&self->heads, version);
+  const StackNode *node = head->node;
+  if (node->error_cost == 0) return true;
+  while (node) {
+    if (node->link_count > 0) {
+      Subtree subtree = node->links[0].subtree;
+      if (subtree.ptr) {
+        if (ts_subtree_total_bytes(subtree) > 0) {
+          return true;
+        } else if (
+          node->node_count > head->node_count_at_last_error &&
+          ts_subtree_error_cost(subtree) == 0
+        ) {
+          node = node->links[0].node;
+          continue;
+        }
+      }
+    }
+    break;
+  }
+  return false;
+}
+
+void ts_stack_remove_version(Stack *self, StackVersion version) {
+  stack_head_delete(array_get(&self->heads, version), &self->node_pool, self->subtree_pool);
+  array_erase(&self->heads, version);
+}
+
+void ts_stack_renumber_version(Stack *self, StackVersion v1, StackVersion v2) {
+  if (v1 == v2) return;
+  ts_assert(v2 < v1);
+  ts_assert((uint32_t)v1 < self->heads.size);
+  StackHead *source_head = &self->heads.contents[v1];
+  StackHead *target_head = &self->heads.contents[v2];
+  if (target_head->summary && !source_head->summary) {
+    source_head->summary = target_head->summary;
+    target_head->summary = NULL;
+  }
+  stack_head_delete(target_head, &self->node_pool, self->subtree_pool);
+  *target_head = *source_head;
+  array_erase(&self->heads, v1);
+}
+
+void ts_stack_swap_versions(Stack *self, StackVersion v1, StackVersion v2) {
+  StackHead temporary_head = self->heads.contents[v1];
+  self->heads.contents[v1] = self->heads.contents[v2];
+  self->heads.contents[v2] = temporary_head;
+}
+
+StackVersion ts_stack_copy_version(Stack *self, StackVersion version) {
+  ts_assert(version < self->heads.size);
+  array_push(&self->heads, self->heads.contents[version]);
+  StackHead *head = array_back(&self->heads);
+  stack_node_retain(head->node);
+  if (head->last_external_token.ptr) ts_subtree_retain(head->last_external_token);
+  head->summary = NULL;
+  return self->heads.size - 1;
+}
+
+bool ts_stack_merge(Stack *self, StackVersion version1, StackVersion version2) {
+  if (!ts_stack_can_merge(self, version1, version2)) return false;
+  StackHead *head1 = &self->heads.contents[version1];
+  StackHead *head2 = &self->heads.contents[version2];
+  for (uint32_t i = 0; i < head2->node->link_count; i++) {
+    stack_node_add_link(head1->node, head2->node->links[i], self->subtree_pool);
+  }
+  if (head1->node->state == ERROR_STATE) {
+    head1->node_count_at_last_error = head1->node->node_count;
+  }
+  ts_stack_remove_version(self, version2);
+  return true;
+}
+
+bool ts_stack_can_merge(Stack *self, StackVersion version1, StackVersion version2) {
+  StackHead *head1 = &self->heads.contents[version1];
+  StackHead *head2 = &self->heads.contents[version2];
+  return
+    head1->status == StackStatusActive &&
+    head2->status == StackStatusActive &&
+    head1->node->state == head2->node->state &&
+    head1->node->position.bytes == head2->node->position.bytes &&
+    head1->node->error_cost == head2->node->error_cost &&
+    ts_subtree_external_scanner_state_eq(head1->last_external_token, head2->last_external_token);
+}
+
+void ts_stack_halt(Stack *self, StackVersion version) {
+  array_get(&self->heads, version)->status = StackStatusHalted;
+}
+
+void ts_stack_pause(Stack *self, StackVersion version, Subtree lookahead) {
+  StackHead *head = array_get(&self->heads, version);
+  head->status = StackStatusPaused;
+  head->lookahead_when_paused = lookahead;
+  head->node_count_at_last_error = head->node->node_count;
+}
+
+bool ts_stack_is_active(const Stack *self, StackVersion version) {
+  return array_get(&self->heads, version)->status == StackStatusActive;
+}
+
+bool ts_stack_is_halted(const Stack *self, StackVersion version) {
+  return array_get(&self->heads, version)->status == StackStatusHalted;
+}
+
+bool ts_stack_is_paused(const Stack *self, StackVersion version) {
+  return array_get(&self->heads, version)->status == StackStatusPaused;
+}
+
+Subtree ts_stack_resume(Stack *self, StackVersion version) {
+  StackHead *head = array_get(&self->heads, version);
+  ts_assert(head->status == StackStatusPaused);
+  Subtree result = head->lookahead_when_paused;
+  head->status = StackStatusActive;
+  head->lookahead_when_paused = NULL_SUBTREE;
+  return result;
+}
+
+void ts_stack_clear(Stack *self) {
+  stack_node_retain(self->base_node);
+  for (uint32_t i = 0; i < self->heads.size; i++) {
+    stack_head_delete(&self->heads.contents[i], &self->node_pool, self->subtree_pool);
+  }
+  array_clear(&self->heads);
+  array_push(&self->heads, ((StackHead) {
+    .node = self->base_node,
+    .status = StackStatusActive,
+    .last_external_token = NULL_SUBTREE,
+    .lookahead_when_paused = NULL_SUBTREE,
+  }));
+}
+
+bool ts_stack_print_dot_graph(Stack *self, const TSLanguage *language, FILE *f) {
+  array_reserve(&self->iterators, 32);
+  if (!f) f = stderr;
+
+  fprintf(f, "digraph stack {\n");
+  fprintf(f, "rankdir=\"RL\";\n");
+  fprintf(f, "edge [arrowhead=none]\n");
+
+  Array(StackNode *) visited_nodes = array_new();
+
+  array_clear(&self->iterators);
+  for (uint32_t i = 0; i < self->heads.size; i++) {
+    StackHead *head = &self->heads.contents[i];
+    if (head->status == StackStatusHalted) continue;
+
+    fprintf(f, "node_head_%u [shape=none, label=\"\"]\n", i);
+    fprintf(f, "node_head_%u -> node_%p [", i, (void *)head->node);
+
+    if (head->status == StackStatusPaused) {
+      fprintf(f, "color=red ");
+    }
+    fprintf(f,
+      "label=%u, fontcolor=blue, weight=10000, labeltooltip=\"node_count: %u\nerror_cost: %u",
+      i,
+      ts_stack_node_count_since_error(self, i),
+      ts_stack_error_cost(self, i)
+    );
+
+    if (head->summary) {
+      fprintf(f, "\nsummary:");
+      for (uint32_t j = 0; j < head->summary->size; j++) fprintf(f, " %u", head->summary->contents[j].state);
+    }
+
+    if (head->last_external_token.ptr) {
+      const ExternalScannerState *state = &head->last_external_token.ptr->external_scanner_state;
+      const char *data = ts_external_scanner_state_data(state);
+      fprintf(f, "\nexternal_scanner_state:");
+      for (uint32_t j = 0; j < state->length; j++) fprintf(f, " %2X", data[j]);
+    }
+
+    fprintf(f, "\"]\n");
+    array_push(&self->iterators, ((StackIterator) {
+      .node = head->node
+    }));
+  }
+
+  bool all_iterators_done = false;
+  while (!all_iterators_done) {
+    all_iterators_done = true;
+
+    for (uint32_t i = 0; i < self->iterators.size; i++) {
+      StackIterator iterator = self->iterators.contents[i];
+      StackNode *node = iterator.node;
+
+      for (uint32_t j = 0; j < visited_nodes.size; j++) {
+        if (visited_nodes.contents[j] == node) {
+          node = NULL;
+          break;
+        }
+      }
+
+      if (!node) continue;
+      all_iterators_done = false;
+
+      fprintf(f, "node_%p [", (void *)node);
+      if (node->state == ERROR_STATE) {
+        fprintf(f, "label=\"?\"");
+      } else if (
+        node->link_count == 1 &&
+        node->links[0].subtree.ptr &&
+        ts_subtree_extra(node->links[0].subtree)
+      ) {
+        fprintf(f, "shape=point margin=0 label=\"\"");
+      } else {
+        fprintf(f, "label=\"%d\"", node->state);
+      }
+
+      fprintf(
+        f,
+        " tooltip=\"position: %u,%u\nnode_count:%u\nerror_cost: %u\ndynamic_precedence: %d\"];\n",
+        node->position.extent.row + 1,
+        node->position.extent.column,
+        node->node_count,
+        node->error_cost,
+        node->dynamic_precedence
+      );
+
+      for (int j = 0; j < node->link_count; j++) {
+        StackLink link = node->links[j];
+        fprintf(f, "node_%p -> node_%p [", (void *)node, (void *)link.node);
+        if (link.is_pending) fprintf(f, "style=dashed ");
+        if (link.subtree.ptr && ts_subtree_extra(link.subtree)) fprintf(f, "fontcolor=gray ");
+
+        if (!link.subtree.ptr) {
+          fprintf(f, "color=red");
+        } else {
+          fprintf(f, "label=\"");
+          bool quoted = ts_subtree_visible(link.subtree) && !ts_subtree_named(link.subtree);
+          if (quoted) fprintf(f, "'");
+          ts_language_write_symbol_as_dot_string(language, f, ts_subtree_symbol(link.subtree));
+          if (quoted) fprintf(f, "'");
+          fprintf(f, "\"");
+          fprintf(
+            f,
+            "labeltooltip=\"error_cost: %u\ndynamic_precedence: %" PRId32 "\"",
+            ts_subtree_error_cost(link.subtree),
+            ts_subtree_dynamic_precedence(link.subtree)
+          );
+        }
+
+        fprintf(f, "];\n");
+
+        StackIterator *next_iterator;
+        if (j == 0) {
+          next_iterator = &self->iterators.contents[i];
+        } else {
+          array_push(&self->iterators, iterator);
+          next_iterator = array_back(&self->iterators);
+        }
+        next_iterator->node = link.node;
+      }
+
+      array_push(&visited_nodes, node);
+    }
+  }
+
+  fprintf(f, "}\n");
+
+  array_delete(&visited_nodes);
+  return true;
+}
+
+#undef forceinline
diff --git a/vendor/tree-sitter/lib/src/stack.h b/vendor/tree-sitter/lib/src/stack.h
new file mode 100644
--- /dev/null
+++ b/vendor/tree-sitter/lib/src/stack.h
@@ -0,0 +1,130 @@
+#ifndef TREE_SITTER_PARSE_STACK_H_
+#define TREE_SITTER_PARSE_STACK_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "./array.h"
+#include "./subtree.h"
+#include <stdio.h>
+
+typedef struct Stack Stack;
+
+typedef unsigned StackVersion;
+#define STACK_VERSION_NONE ((StackVersion)-1)
+
+typedef struct {
+  SubtreeArray subtrees;
+  StackVersion version;
+} StackSlice;
+typedef Array(StackSlice) StackSliceArray;
+
+typedef struct {
+  Length position;
+  unsigned depth;
+  TSStateId state;
+} StackSummaryEntry;
+typedef Array(StackSummaryEntry) StackSummary;
+
+// Create a stack.
+Stack *ts_stack_new(SubtreePool *subtree_pool);
+
+// Release the memory reserved for a given stack.
+void ts_stack_delete(Stack *self);
+
+// Get the stack's current number of versions.
+uint32_t ts_stack_version_count(const Stack *self);
+
+// Get the state at the top of the given version of the stack. If the stack is
+// empty, this returns the initial state, 0.
+TSStateId ts_stack_state(const Stack *self, StackVersion version);
+
+// Get the last external token associated with a given version of the stack.
+Subtree ts_stack_last_external_token(const Stack *self, StackVersion version);
+
+// Set the last external token associated with a given version of the stack.
+void ts_stack_set_last_external_token(Stack *self, StackVersion version, Subtree token);
+
+// Get the position of the given version of the stack within the document.
+Length ts_stack_position(const Stack *, StackVersion);
+
+// Push a tree and state onto the given version of the stack.
+//
+// This transfers ownership of the tree to the Stack. Callers that
+// need to retain ownership of the tree for their own purposes should
+// first retain the tree.
+void ts_stack_push(Stack *self, StackVersion version, Subtree subtree, bool pending, TSStateId state);
+
+// Pop the given number of entries from the given version of the stack. This
+// operation can increase the number of stack versions by revealing multiple
+// versions which had previously been merged. It returns an array that
+// specifies the index of each revealed version and the trees that were
+// removed from that version.
+StackSliceArray ts_stack_pop_count(Stack *self, StackVersion version, uint32_t count);
+
+// Remove an error at the top of the given version of the stack.
+SubtreeArray ts_stack_pop_error(Stack *self, StackVersion version);
+
+// Remove any pending trees from the top of the given version of the stack.
+StackSliceArray ts_stack_pop_pending(Stack *self, StackVersion version);
+
+// Remove all trees from the given version of the stack.
+StackSliceArray ts_stack_pop_all(Stack *self, StackVersion version);
+
+// Get the maximum number of tree nodes reachable from this version of the stack
+// since the last error was detected.
+unsigned ts_stack_node_count_since_error(const Stack *self, StackVersion version);
+
+int ts_stack_dynamic_precedence(Stack *self, StackVersion version);
+
+bool ts_stack_has_advanced_since_error(const Stack *self, StackVersion version);
+
+// Compute a summary of all the parse states near the top of the given
+// version of the stack and store the summary for later retrieval.
+void ts_stack_record_summary(Stack *self, StackVersion version, unsigned max_depth);
+
+// Retrieve a summary of all the parse states near the top of the
+// given version of the stack.
+StackSummary *ts_stack_get_summary(Stack *self, StackVersion version);
+
+// Get the total cost of all errors on the given version of the stack.
+unsigned ts_stack_error_cost(const Stack *self, StackVersion version);
+
+// Merge the given two stack versions if possible, returning true
+// if they were successfully merged and false otherwise.
+bool ts_stack_merge(Stack *self, StackVersion version1, StackVersion version2);
+
+// Determine whether the given two stack versions can be merged.
+bool ts_stack_can_merge(Stack *self, StackVersion version1, StackVersion version2);
+
+Subtree ts_stack_resume(Stack *self, StackVersion version);
+
+void ts_stack_pause(Stack *self, StackVersion version, Subtree lookahead);
+
+void ts_stack_halt(Stack *self, StackVersion version);
+
+bool ts_stack_is_active(const Stack *self, StackVersion version);
+
+bool ts_stack_is_paused(const Stack *self, StackVersion version);
+
+bool ts_stack_is_halted(const Stack *self, StackVersion version);
+
+void ts_stack_renumber_version(Stack *self, StackVersion v1, StackVersion v2);
+
+void ts_stack_swap_versions(Stack *, StackVersion v1, StackVersion v2);
+
+StackVersion ts_stack_copy_version(Stack *self, StackVersion version);
+
+// Remove the given version from the stack.
+void ts_stack_remove_version(Stack *self, StackVersion version);
+
+void ts_stack_clear(Stack *self);
+
+bool ts_stack_print_dot_graph(Stack *self, const TSLanguage *language, FILE *f);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  // TREE_SITTER_PARSE_STACK_H_
diff --git a/vendor/tree-sitter/lib/src/subtree.c b/vendor/tree-sitter/lib/src/subtree.c
new file mode 100644
--- /dev/null
+++ b/vendor/tree-sitter/lib/src/subtree.c
@@ -0,0 +1,1065 @@
+#include <ctype.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <string.h>
+#include <stdio.h>
+#include "./alloc.h"
+#include "./array.h"
+#include "./atomic.h"
+#include "./subtree.h"
+#include "./length.h"
+#include "./language.h"
+#include "./error_costs.h"
+#include "./ts_assert.h"
+#include <stddef.h>
+
+typedef struct {
+  Length start;
+  Length old_end;
+  Length new_end;
+} Edit;
+
+#define TS_MAX_INLINE_TREE_LENGTH UINT8_MAX
+#define TS_MAX_TREE_POOL_SIZE 32
+
+// ExternalScannerState
+
+void ts_external_scanner_state_init(ExternalScannerState *self, const char *data, unsigned length) {
+  self->length = length;
+  if (length > sizeof(self->short_data)) {
+    self->long_data = ts_malloc(length);
+    memcpy(self->long_data, data, length);
+  } else {
+    memcpy(self->short_data, data, length);
+  }
+}
+
+ExternalScannerState ts_external_scanner_state_copy(const ExternalScannerState *self) {
+  ExternalScannerState result = *self;
+  if (self->length > sizeof(self->short_data)) {
+    result.long_data = ts_malloc(self->length);
+    memcpy(result.long_data, self->long_data, self->length);
+  }
+  return result;
+}
+
+void ts_external_scanner_state_delete(ExternalScannerState *self) {
+  if (self->length > sizeof(self->short_data)) {
+    ts_free(self->long_data);
+  }
+}
+
+const char *ts_external_scanner_state_data(const ExternalScannerState *self) {
+  if (self->length > sizeof(self->short_data)) {
+    return self->long_data;
+  } else {
+    return self->short_data;
+  }
+}
+
+bool ts_external_scanner_state_eq(const ExternalScannerState *self, const char *buffer, unsigned length) {
+  return
+    self->length == length &&
+    memcmp(ts_external_scanner_state_data(self), buffer, length) == 0;
+}
+
+// SubtreeArray
+
+void ts_subtree_array_copy(SubtreeArray self, SubtreeArray *dest) {
+  dest->size = self.size;
+  dest->capacity = self.capacity;
+  dest->contents = self.contents;
+  if (self.capacity > 0) {
+    dest->contents = ts_calloc(self.capacity, sizeof(Subtree));
+    memcpy(dest->contents, self.contents, self.size * sizeof(Subtree));
+    for (uint32_t i = 0; i < self.size; i++) {
+      ts_subtree_retain(dest->contents[i]);
+    }
+  }
+}
+
+void ts_subtree_array_clear(SubtreePool *pool, SubtreeArray *self) {
+  for (uint32_t i = 0; i < self->size; i++) {
+    ts_subtree_release(pool, self->contents[i]);
+  }
+  array_clear(self);
+}
+
+void ts_subtree_array_delete(SubtreePool *pool, SubtreeArray *self) {
+  ts_subtree_array_clear(pool, self);
+  array_delete(self);
+}
+
+void ts_subtree_array_remove_trailing_extras(
+  SubtreeArray *self,
+  SubtreeArray *destination
+) {
+  array_clear(destination);
+  while (self->size > 0) {
+    Subtree last = self->contents[self->size - 1];
+    if (ts_subtree_extra(last)) {
+      self->size--;
+      array_push(destination, last);
+    } else {
+      break;
+    }
+  }
+  ts_subtree_array_reverse(destination);
+}
+
+void ts_subtree_array_reverse(SubtreeArray *self) {
+  for (uint32_t i = 0, limit = self->size / 2; i < limit; i++) {
+    size_t reverse_index = self->size - 1 - i;
+    Subtree swap = self->contents[i];
+    self->contents[i] = self->contents[reverse_index];
+    self->contents[reverse_index] = swap;
+  }
+}
+
+// SubtreePool
+
+SubtreePool ts_subtree_pool_new(uint32_t capacity) {
+  SubtreePool self = {array_new(), array_new()};
+  array_reserve(&self.free_trees, capacity);
+  return self;
+}
+
+void ts_subtree_pool_delete(SubtreePool *self) {
+  if (self->free_trees.contents) {
+    for (unsigned i = 0; i < self->free_trees.size; i++) {
+      ts_free(self->free_trees.contents[i].ptr);
+    }
+    array_delete(&self->free_trees);
+  }
+  if (self->tree_stack.contents) array_delete(&self->tree_stack);
+}
+
+static SubtreeHeapData *ts_subtree_pool_allocate(SubtreePool *self) {
+  if (self->free_trees.size > 0) {
+    return array_pop(&self->free_trees).ptr;
+  } else {
+    return ts_malloc(sizeof(SubtreeHeapData));
+  }
+}
+
+static void ts_subtree_pool_free(SubtreePool *self, SubtreeHeapData *tree) {
+  if (self->free_trees.capacity > 0 && self->free_trees.size + 1 <= TS_MAX_TREE_POOL_SIZE) {
+    array_push(&self->free_trees, (MutableSubtree) {.ptr = tree});
+  } else {
+    ts_free(tree);
+  }
+}
+
+// Subtree
+
+static inline bool ts_subtree_can_inline(Length padding, Length size, uint32_t lookahead_bytes) {
+  return
+    padding.bytes < TS_MAX_INLINE_TREE_LENGTH &&
+    padding.extent.row < 16 &&
+    padding.extent.column < TS_MAX_INLINE_TREE_LENGTH &&
+    size.extent.row == 0 &&
+    size.extent.column < TS_MAX_INLINE_TREE_LENGTH &&
+    lookahead_bytes < 16;
+}
+
+Subtree ts_subtree_new_leaf(
+  SubtreePool *pool, TSSymbol symbol, Length padding, Length size,
+  uint32_t lookahead_bytes, TSStateId parse_state,
+  bool has_external_tokens, bool depends_on_column,
+  bool is_keyword, const TSLanguage *language
+) {
+  TSSymbolMetadata metadata = ts_language_symbol_metadata(language, symbol);
+  bool extra = symbol == ts_builtin_sym_end;
+
+  bool is_inline = (
+    symbol <= UINT8_MAX &&
+    !has_external_tokens &&
+    ts_subtree_can_inline(padding, size, lookahead_bytes)
+  );
+
+  if (is_inline) {
+    return (Subtree) {{
+      .parse_state = parse_state,
+      .symbol = symbol,
+      .padding_bytes = padding.bytes,
+      .padding_rows = padding.extent.row,
+      .padding_columns = padding.extent.column,
+      .size_bytes = size.bytes,
+      .lookahead_bytes = lookahead_bytes,
+      .visible = metadata.visible,
+      .named = metadata.named,
+      .extra = extra,
+      .has_changes = false,
+      .is_missing = false,
+      .is_keyword = is_keyword,
+      .is_inline = true,
+    }};
+  } else {
+    SubtreeHeapData *data = ts_subtree_pool_allocate(pool);
+    *data = (SubtreeHeapData) {
+      .ref_count = 1,
+      .padding = padding,
+      .size = size,
+      .lookahead_bytes = lookahead_bytes,
+      .error_cost = 0,
+      .child_count = 0,
+      .symbol = symbol,
+      .parse_state = parse_state,
+      .visible = metadata.visible,
+      .named = metadata.named,
+      .extra = extra,
+      .fragile_left = false,
+      .fragile_right = false,
+      .has_changes = false,
+      .has_external_tokens = has_external_tokens,
+      .has_external_scanner_state_change = false,
+      .depends_on_column = depends_on_column,
+      .is_missing = false,
+      .is_keyword = is_keyword,
+      {{.first_leaf = {.symbol = 0, .parse_state = 0}}}
+    };
+    return (Subtree) {.ptr = data};
+  }
+}
+
+void ts_subtree_set_symbol(
+  MutableSubtree *self,
+  TSSymbol symbol,
+  const TSLanguage *language
+) {
+  TSSymbolMetadata metadata = ts_language_symbol_metadata(language, symbol);
+  if (self->data.is_inline) {
+    ts_assert(symbol < UINT8_MAX);
+    self->data.symbol = symbol;
+    self->data.named = metadata.named;
+    self->data.visible = metadata.visible;
+  } else {
+    self->ptr->symbol = symbol;
+    self->ptr->named = metadata.named;
+    self->ptr->visible = metadata.visible;
+  }
+}
+
+Subtree ts_subtree_new_error(
+  SubtreePool *pool, int32_t lookahead_char, Length padding, Length size,
+  uint32_t bytes_scanned, TSStateId parse_state, const TSLanguage *language
+) {
+  Subtree result = ts_subtree_new_leaf(
+    pool, ts_builtin_sym_error, padding, size, bytes_scanned,
+    parse_state, false, false, false, language
+  );
+  SubtreeHeapData *data = (SubtreeHeapData *)result.ptr;
+  data->fragile_left = true;
+  data->fragile_right = true;
+  data->lookahead_char = lookahead_char;
+  return result;
+}
+
+// Clone a subtree.
+MutableSubtree ts_subtree_clone(Subtree self) {
+  size_t alloc_size = ts_subtree_alloc_size(self.ptr->child_count);
+  Subtree *new_children = ts_malloc(alloc_size);
+  Subtree *old_children = ts_subtree_children(self);
+  memcpy(new_children, old_children, alloc_size);
+  SubtreeHeapData *result = (SubtreeHeapData *)&new_children[self.ptr->child_count];
+  if (self.ptr->child_count > 0) {
+    for (uint32_t i = 0; i < self.ptr->child_count; i++) {
+      ts_subtree_retain(new_children[i]);
+    }
+  } else if (self.ptr->has_external_tokens) {
+    result->external_scanner_state = ts_external_scanner_state_copy(
+      &self.ptr->external_scanner_state
+    );
+  }
+  result->ref_count = 1;
+  return (MutableSubtree) {.ptr = result};
+}
+
+// Get mutable version of a subtree.
+//
+// This takes ownership of the subtree. If the subtree has only one owner,
+// this will directly convert it into a mutable version. Otherwise, it will
+// perform a copy.
+MutableSubtree ts_subtree_make_mut(SubtreePool *pool, Subtree self) {
+  if (self.data.is_inline) return (MutableSubtree) {self.data};
+  if (self.ptr->ref_count == 1) return ts_subtree_to_mut_unsafe(self);
+  MutableSubtree result = ts_subtree_clone(self);
+  ts_subtree_release(pool, self);
+  return result;
+}
+
+static void ts_subtree__compress(
+  MutableSubtree self,
+  unsigned count,
+  const TSLanguage *language,
+  MutableSubtreeArray *stack
+) {
+  unsigned initial_stack_size = stack->size;
+
+  MutableSubtree tree = self;
+  TSSymbol symbol = tree.ptr->symbol;
+  for (unsigned i = 0; i < count; i++) {
+    if (tree.ptr->ref_count > 1 || tree.ptr->child_count < 2) break;
+
+    MutableSubtree child = ts_subtree_to_mut_unsafe(ts_subtree_children(tree)[0]);
+    if (
+      child.data.is_inline ||
+      child.ptr->child_count < 2 ||
+      child.ptr->ref_count > 1 ||
+      child.ptr->symbol != symbol
+    ) break;
+
+    MutableSubtree grandchild = ts_subtree_to_mut_unsafe(ts_subtree_children(child)[0]);
+    if (
+      grandchild.data.is_inline ||
+      grandchild.ptr->child_count < 2 ||
+      grandchild.ptr->ref_count > 1 ||
+      grandchild.ptr->symbol != symbol
+    ) break;
+
+    ts_subtree_children(tree)[0] = ts_subtree_from_mut(grandchild);
+    ts_subtree_children(child)[0] = ts_subtree_children(grandchild)[grandchild.ptr->child_count - 1];
+    ts_subtree_children(grandchild)[grandchild.ptr->child_count - 1] = ts_subtree_from_mut(child);
+    array_push(stack, tree);
+    tree = grandchild;
+  }
+
+  while (stack->size > initial_stack_size) {
+    tree = array_pop(stack);
+    MutableSubtree child = ts_subtree_to_mut_unsafe(ts_subtree_children(tree)[0]);
+    MutableSubtree grandchild = ts_subtree_to_mut_unsafe(ts_subtree_children(child)[child.ptr->child_count - 1]);
+    ts_subtree_summarize_children(grandchild, language);
+    ts_subtree_summarize_children(child, language);
+    ts_subtree_summarize_children(tree, language);
+  }
+}
+
+void ts_subtree_balance(Subtree self, SubtreePool *pool, const TSLanguage *language) {
+  array_clear(&pool->tree_stack);
+
+  if (ts_subtree_child_count(self) > 0 && self.ptr->ref_count == 1) {
+    array_push(&pool->tree_stack, ts_subtree_to_mut_unsafe(self));
+  }
+
+  while (pool->tree_stack.size > 0) {
+    MutableSubtree tree = array_pop(&pool->tree_stack);
+
+    if (tree.ptr->repeat_depth > 0) {
+      Subtree child1 = ts_subtree_children(tree)[0];
+      Subtree child2 = ts_subtree_children(tree)[tree.ptr->child_count - 1];
+      long repeat_delta = (long)ts_subtree_repeat_depth(child1) - (long)ts_subtree_repeat_depth(child2);
+      if (repeat_delta > 0) {
+        unsigned n = (unsigned)repeat_delta;
+        for (unsigned i = n / 2; i > 0; i /= 2) {
+          ts_subtree__compress(tree, i, language, &pool->tree_stack);
+          n -= i;
+        }
+      }
+    }
+
+    for (uint32_t i = 0; i < tree.ptr->child_count; i++) {
+      Subtree child = ts_subtree_children(tree)[i];
+      if (ts_subtree_child_count(child) > 0 && child.ptr->ref_count == 1) {
+        array_push(&pool->tree_stack, ts_subtree_to_mut_unsafe(child));
+      }
+    }
+  }
+}
+
+// Assign all of the node's properties that depend on its children.
+void ts_subtree_summarize_children(
+  MutableSubtree self,
+  const TSLanguage *language
+) {
+  ts_assert(!self.data.is_inline);
+
+  self.ptr->named_child_count = 0;
+  self.ptr->visible_child_count = 0;
+  self.ptr->error_cost = 0;
+  self.ptr->repeat_depth = 0;
+  self.ptr->visible_descendant_count = 0;
+  self.ptr->has_external_tokens = false;
+  self.ptr->depends_on_column = false;
+  self.ptr->has_external_scanner_state_change = false;
+  self.ptr->dynamic_precedence = 0;
+
+  uint32_t structural_index = 0;
+  const TSSymbol *alias_sequence = ts_language_alias_sequence(language, self.ptr->production_id);
+  uint32_t lookahead_end_byte = 0;
+
+  const Subtree *children = ts_subtree_children(self);
+  for (uint32_t i = 0; i < self.ptr->child_count; i++) {
+    Subtree child = children[i];
+
+    if (
+      self.ptr->size.extent.row == 0 &&
+      ts_subtree_depends_on_column(child)
+    ) {
+      self.ptr->depends_on_column = true;
+    }
+
+    if (ts_subtree_has_external_scanner_state_change(child)) {
+      self.ptr->has_external_scanner_state_change = true;
+    }
+
+    if (i == 0) {
+      self.ptr->padding = ts_subtree_padding(child);
+      self.ptr->size = ts_subtree_size(child);
+    } else {
+      self.ptr->size = length_add(self.ptr->size, ts_subtree_total_size(child));
+    }
+
+    uint32_t child_lookahead_end_byte =
+      self.ptr->padding.bytes +
+      self.ptr->size.bytes +
+      ts_subtree_lookahead_bytes(child);
+    if (child_lookahead_end_byte > lookahead_end_byte) {
+      lookahead_end_byte = child_lookahead_end_byte;
+    }
+
+    if (ts_subtree_symbol(child) != ts_builtin_sym_error_repeat) {
+      self.ptr->error_cost += ts_subtree_error_cost(child);
+    }
+
+    uint32_t grandchild_count = ts_subtree_child_count(child);
+    if (
+      self.ptr->symbol == ts_builtin_sym_error ||
+      self.ptr->symbol == ts_builtin_sym_error_repeat
+    ) {
+      if (!ts_subtree_extra(child) && !(ts_subtree_is_error(child) && grandchild_count == 0)) {
+        if (ts_subtree_visible(child)) {
+          self.ptr->error_cost += ERROR_COST_PER_SKIPPED_TREE;
+        } else if (grandchild_count > 0) {
+          self.ptr->error_cost += ERROR_COST_PER_SKIPPED_TREE * child.ptr->visible_child_count;
+        }
+      }
+    }
+
+    self.ptr->dynamic_precedence += ts_subtree_dynamic_precedence(child);
+    self.ptr->visible_descendant_count += ts_subtree_visible_descendant_count(child);
+
+    if (alias_sequence && alias_sequence[structural_index] != 0 && !ts_subtree_extra(child)) {
+      self.ptr->visible_descendant_count++;
+      self.ptr->visible_child_count++;
+      if (ts_language_symbol_metadata(language, alias_sequence[structural_index]).named) {
+        self.ptr->named_child_count++;
+      }
+    } else if (ts_subtree_visible(child)) {
+      self.ptr->visible_descendant_count++;
+      self.ptr->visible_child_count++;
+      if (ts_subtree_named(child)) self.ptr->named_child_count++;
+    } else if (grandchild_count > 0) {
+      self.ptr->visible_child_count += child.ptr->visible_child_count;
+      self.ptr->named_child_count += child.ptr->named_child_count;
+    }
+
+    if (ts_subtree_has_external_tokens(child)) self.ptr->has_external_tokens = true;
+
+    if (ts_subtree_is_error(child)) {
+      self.ptr->fragile_left = self.ptr->fragile_right = true;
+      self.ptr->parse_state = TS_TREE_STATE_NONE;
+    }
+
+    if (!ts_subtree_extra(child)) structural_index++;
+  }
+
+  self.ptr->lookahead_bytes = lookahead_end_byte - self.ptr->size.bytes - self.ptr->padding.bytes;
+
+  if (
+    self.ptr->symbol == ts_builtin_sym_error ||
+    self.ptr->symbol == ts_builtin_sym_error_repeat
+  ) {
+    self.ptr->error_cost +=
+      ERROR_COST_PER_RECOVERY +
+      ERROR_COST_PER_SKIPPED_CHAR * self.ptr->size.bytes +
+      ERROR_COST_PER_SKIPPED_LINE * self.ptr->size.extent.row;
+  }
+
+  if (self.ptr->child_count > 0) {
+    Subtree first_child = children[0];
+    Subtree last_child = children[self.ptr->child_count - 1];
+
+    self.ptr->first_leaf.symbol = ts_subtree_leaf_symbol(first_child);
+    self.ptr->first_leaf.parse_state = ts_subtree_leaf_parse_state(first_child);
+
+    if (ts_subtree_fragile_left(first_child)) self.ptr->fragile_left = true;
+    if (ts_subtree_fragile_right(last_child)) self.ptr->fragile_right = true;
+
+    if (
+      self.ptr->child_count >= 2 &&
+      !self.ptr->visible &&
+      !self.ptr->named &&
+      ts_subtree_symbol(first_child) == self.ptr->symbol
+    ) {
+      if (ts_subtree_repeat_depth(first_child) > ts_subtree_repeat_depth(last_child)) {
+        self.ptr->repeat_depth = ts_subtree_repeat_depth(first_child) + 1;
+      } else {
+        self.ptr->repeat_depth = ts_subtree_repeat_depth(last_child) + 1;
+      }
+    }
+  }
+}
+
+// Create a new parent node with the given children.
+//
+// This takes ownership of the children array.
+MutableSubtree ts_subtree_new_node(
+  TSSymbol symbol,
+  SubtreeArray *children,
+  unsigned production_id,
+  const TSLanguage *language
+) {
+  TSSymbolMetadata metadata = ts_language_symbol_metadata(language, symbol);
+  bool fragile = symbol == ts_builtin_sym_error || symbol == ts_builtin_sym_error_repeat;
+
+  // Allocate the node's data at the end of the array of children.
+  size_t new_byte_size = ts_subtree_alloc_size(children->size);
+  if (children->capacity * sizeof(Subtree) < new_byte_size) {
+    children->contents = ts_realloc(children->contents, new_byte_size);
+    children->capacity = (uint32_t)(new_byte_size / sizeof(Subtree));
+  }
+  SubtreeHeapData *data = (SubtreeHeapData *)&children->contents[children->size];
+
+  *data = (SubtreeHeapData) {
+    .ref_count = 1,
+    .symbol = symbol,
+    .child_count = children->size,
+    .visible = metadata.visible,
+    .named = metadata.named,
+    .has_changes = false,
+    .has_external_scanner_state_change = false,
+    .fragile_left = fragile,
+    .fragile_right = fragile,
+    .is_keyword = false,
+    {{
+      .visible_descendant_count = 0,
+      .production_id = production_id,
+      .first_leaf = {.symbol = 0, .parse_state = 0},
+    }}
+  };
+  MutableSubtree result = {.ptr = data};
+  ts_subtree_summarize_children(result, language);
+  return result;
+}
+
+// Create a new error node containing the given children.
+//
+// This node is treated as 'extra'. Its children are prevented from having
+// having any effect on the parse state.
+Subtree ts_subtree_new_error_node(
+  SubtreeArray *children,
+  bool extra,
+  const TSLanguage *language
+) {
+  MutableSubtree result = ts_subtree_new_node(
+    ts_builtin_sym_error, children, 0, language
+  );
+  result.ptr->extra = extra;
+  return ts_subtree_from_mut(result);
+}
+
+// Create a new 'missing leaf' node.
+//
+// This node is treated as 'extra'. Its children are prevented from having
+// having any effect on the parse state.
+Subtree ts_subtree_new_missing_leaf(
+  SubtreePool *pool,
+  TSSymbol symbol,
+  Length padding,
+  uint32_t lookahead_bytes,
+  const TSLanguage *language
+) {
+  Subtree result = ts_subtree_new_leaf(
+    pool, symbol, padding, length_zero(), lookahead_bytes,
+    0, false, false, false, language
+  );
+  if (result.data.is_inline) {
+    result.data.is_missing = true;
+  } else {
+    ((SubtreeHeapData *)result.ptr)->is_missing = true;
+  }
+  return result;
+}
+
+void ts_subtree_retain(Subtree self) {
+  if (self.data.is_inline) return;
+  ts_assert(self.ptr->ref_count > 0);
+  atomic_inc((volatile uint32_t *)&self.ptr->ref_count);
+  ts_assert(self.ptr->ref_count != 0);
+}
+
+void ts_subtree_release(SubtreePool *pool, Subtree self) {
+  if (self.data.is_inline) return;
+  array_clear(&pool->tree_stack);
+
+  ts_assert(self.ptr->ref_count > 0);
+  if (atomic_dec((volatile uint32_t *)&self.ptr->ref_count) == 0) {
+    array_push(&pool->tree_stack, ts_subtree_to_mut_unsafe(self));
+  }
+
+  while (pool->tree_stack.size > 0) {
+    MutableSubtree tree = array_pop(&pool->tree_stack);
+    if (tree.ptr->child_count > 0) {
+      Subtree *children = ts_subtree_children(tree);
+      for (uint32_t i = 0; i < tree.ptr->child_count; i++) {
+        Subtree child = children[i];
+        if (child.data.is_inline) continue;
+        ts_assert(child.ptr->ref_count > 0);
+        if (atomic_dec((volatile uint32_t *)&child.ptr->ref_count) == 0) {
+          array_push(&pool->tree_stack, ts_subtree_to_mut_unsafe(child));
+        }
+      }
+      ts_free(children);
+    } else {
+      if (tree.ptr->has_external_tokens) {
+        ts_external_scanner_state_delete(&tree.ptr->external_scanner_state);
+      }
+      ts_subtree_pool_free(pool, tree.ptr);
+    }
+  }
+}
+
+int ts_subtree_compare(Subtree left, Subtree right, SubtreePool *pool) {
+  array_push(&pool->tree_stack, ts_subtree_to_mut_unsafe(left));
+  array_push(&pool->tree_stack, ts_subtree_to_mut_unsafe(right));
+
+  while (pool->tree_stack.size > 0) {
+    right = ts_subtree_from_mut(array_pop(&pool->tree_stack));
+    left = ts_subtree_from_mut(array_pop(&pool->tree_stack));
+
+    int result = 0;
+    if (ts_subtree_symbol(left) < ts_subtree_symbol(right)) result = -1;
+    else if (ts_subtree_symbol(right) < ts_subtree_symbol(left)) result = 1;
+    else if (ts_subtree_child_count(left) < ts_subtree_child_count(right)) result = -1;
+    else if (ts_subtree_child_count(right) < ts_subtree_child_count(left)) result = 1;
+    if (result != 0) {
+      array_clear(&pool->tree_stack);
+      return result;
+    }
+
+    for (uint32_t i = ts_subtree_child_count(left); i > 0; i--) {
+      Subtree left_child = ts_subtree_children(left)[i - 1];
+      Subtree right_child = ts_subtree_children(right)[i - 1];
+      array_push(&pool->tree_stack, ts_subtree_to_mut_unsafe(left_child));
+      array_push(&pool->tree_stack, ts_subtree_to_mut_unsafe(right_child));
+    }
+  }
+
+  return 0;
+}
+
+static inline void ts_subtree_set_has_changes(MutableSubtree *self) {
+  if (self->data.is_inline) {
+    self->data.has_changes = true;
+  } else {
+    self->ptr->has_changes = true;
+  }
+}
+
+Subtree ts_subtree_edit(Subtree self, const TSInputEdit *input_edit, SubtreePool *pool) {
+  typedef struct {
+    Subtree *tree;
+    Edit edit;
+  } EditEntry;
+
+  Array(EditEntry) stack = array_new();
+  array_push(&stack, ((EditEntry) {
+    .tree = &self,
+    .edit = (Edit) {
+      .start = {input_edit->start_byte, input_edit->start_point},
+      .old_end = {input_edit->old_end_byte, input_edit->old_end_point},
+      .new_end = {input_edit->new_end_byte, input_edit->new_end_point},
+    },
+  }));
+
+  while (stack.size) {
+    EditEntry entry = array_pop(&stack);
+    Edit edit = entry.edit;
+    bool is_noop = edit.old_end.bytes == edit.start.bytes && edit.new_end.bytes == edit.start.bytes;
+    bool is_pure_insertion = edit.old_end.bytes == edit.start.bytes;
+    bool parent_depends_on_column = ts_subtree_depends_on_column(*entry.tree);
+    bool column_shifted = edit.new_end.extent.column != edit.old_end.extent.column;
+
+    Length size = ts_subtree_size(*entry.tree);
+    Length padding = ts_subtree_padding(*entry.tree);
+    Length total_size = length_add(padding, size);
+    uint32_t lookahead_bytes = ts_subtree_lookahead_bytes(*entry.tree);
+    uint32_t end_byte = total_size.bytes + lookahead_bytes;
+    if (edit.start.bytes > end_byte || (is_noop && edit.start.bytes == end_byte)) continue;
+
+    // If the edit is entirely within the space before this subtree, then shift this
+    // subtree over according to the edit without changing its size.
+    if (edit.old_end.bytes <= padding.bytes) {
+      padding = length_add(edit.new_end, length_sub(padding, edit.old_end));
+    }
+
+    // If the edit starts in the space before this subtree and extends into this subtree,
+    // shrink the subtree's content to compensate for the change in the space before it.
+    else if (edit.start.bytes < padding.bytes) {
+      size = length_saturating_sub(size, length_sub(edit.old_end, padding));
+      padding = edit.new_end;
+    }
+
+    // If the edit is a pure insertion right at the start of the subtree,
+    // shift the subtree over according to the insertion.
+    else if (edit.start.bytes == padding.bytes && is_pure_insertion) {
+      padding = edit.new_end;
+    }
+
+    // If the edit is within this subtree, resize the subtree to reflect the edit.
+    else if (
+      edit.start.bytes < total_size.bytes ||
+      (edit.start.bytes == total_size.bytes && is_pure_insertion)
+    ) {
+      size = length_add(
+        length_sub(edit.new_end, padding),
+        length_saturating_sub(total_size, edit.old_end)
+      );
+    }
+
+    MutableSubtree result = ts_subtree_make_mut(pool, *entry.tree);
+
+    if (result.data.is_inline) {
+      if (ts_subtree_can_inline(padding, size, lookahead_bytes)) {
+        result.data.padding_bytes = padding.bytes;
+        result.data.padding_rows = padding.extent.row;
+        result.data.padding_columns = padding.extent.column;
+        result.data.size_bytes = size.bytes;
+      } else {
+        SubtreeHeapData *data = ts_subtree_pool_allocate(pool);
+        data->ref_count = 1;
+        data->padding = padding;
+        data->size = size;
+        data->lookahead_bytes = lookahead_bytes;
+        data->error_cost = 0;
+        data->child_count = 0;
+        data->symbol = result.data.symbol;
+        data->parse_state = result.data.parse_state;
+        data->visible = result.data.visible;
+        data->named = result.data.named;
+        data->extra = result.data.extra;
+        data->fragile_left = false;
+        data->fragile_right = false;
+        data->has_changes = false;
+        data->has_external_tokens = false;
+        data->depends_on_column = false;
+        data->is_missing = result.data.is_missing;
+        data->is_keyword = result.data.is_keyword;
+        result.ptr = data;
+      }
+    } else {
+      result.ptr->padding = padding;
+      result.ptr->size = size;
+    }
+
+    ts_subtree_set_has_changes(&result);
+    *entry.tree = ts_subtree_from_mut(result);
+
+    Length child_left, child_right = length_zero();
+    for (uint32_t i = 0, n = ts_subtree_child_count(*entry.tree); i < n; i++) {
+      Subtree *child = &ts_subtree_children(*entry.tree)[i];
+      Length child_size = ts_subtree_total_size(*child);
+      child_left = child_right;
+      child_right = length_add(child_left, child_size);
+
+      // If this child ends before the edit, it is not affected.
+      if (child_right.bytes + ts_subtree_lookahead_bytes(*child) < edit.start.bytes) continue;
+
+      // Keep editing child nodes until a node is reached that starts after the edit.
+      // Also, if this node's validity depends on its column position, then continue
+      // invaliditing child nodes until reaching a line break.
+      if ((
+        (child_left.bytes > edit.old_end.bytes) ||
+        (child_left.bytes == edit.old_end.bytes && child_size.bytes > 0 && i > 0)
+      ) && (
+        !parent_depends_on_column ||
+        child_left.extent.row > padding.extent.row
+      ) && (
+        !ts_subtree_depends_on_column(*child) ||
+        !column_shifted ||
+        child_left.extent.row > edit.old_end.extent.row
+      )) {
+        break;
+      }
+
+      // Transform edit into the child's coordinate space.
+      Edit child_edit = {
+        .start = length_saturating_sub(edit.start, child_left),
+        .old_end = length_saturating_sub(edit.old_end, child_left),
+        .new_end = length_saturating_sub(edit.new_end, child_left),
+      };
+
+      // Interpret all inserted text as applying to the *first* child that touches the edit.
+      // Subsequent children are only never have any text inserted into them; they are only
+      // shrunk to compensate for the edit.
+      if (
+        child_right.bytes > edit.start.bytes ||
+        (child_right.bytes == edit.start.bytes && is_pure_insertion)
+      ) {
+        edit.new_end = edit.start;
+      }
+
+      // Children that occur before the edit are not reshaped by the edit.
+      else {
+        child_edit.old_end = child_edit.start;
+        child_edit.new_end = child_edit.start;
+      }
+
+      // Queue processing of this child's subtree.
+      array_push(&stack, ((EditEntry) {
+        .tree = child,
+        .edit = child_edit,
+      }));
+    }
+  }
+
+  array_delete(&stack);
+  return self;
+}
+
+Subtree ts_subtree_last_external_token(Subtree tree) {
+  if (!ts_subtree_has_external_tokens(tree)) return NULL_SUBTREE;
+  while (tree.ptr->child_count > 0) {
+    for (uint32_t i = tree.ptr->child_count - 1; i + 1 > 0; i--) {
+      Subtree child = ts_subtree_children(tree)[i];
+      if (ts_subtree_has_external_tokens(child)) {
+        tree = child;
+        break;
+      }
+    }
+  }
+  return tree;
+}
+
+static size_t ts_subtree__write_char_to_string(char *str, size_t n, int32_t chr) {
+  if (chr == -1)
+    return snprintf(str, n, "INVALID");
+  else if (chr == '\0')
+    return snprintf(str, n, "'\\0'");
+  else if (chr == '\n')
+    return snprintf(str, n, "'\\n'");
+  else if (chr == '\t')
+    return snprintf(str, n, "'\\t'");
+  else if (chr == '\r')
+    return snprintf(str, n, "'\\r'");
+  else if (0 < chr && chr < 128 && isprint(chr))
+    return snprintf(str, n, "'%c'", chr);
+  else
+    return snprintf(str, n, "%d", chr);
+}
+
+static const char *const ROOT_FIELD = "__ROOT__";
+
+static size_t ts_subtree__write_to_string(
+  Subtree self, char *string, size_t limit,
+  const TSLanguage *language, bool include_all,
+  TSSymbol alias_symbol, bool alias_is_named, const char *field_name
+) {
+  if (!self.ptr) return snprintf(string, limit, "(NULL)");
+
+  char *cursor = string;
+  char **writer = (limit > 1) ? &cursor : &string;
+  bool is_root = field_name == ROOT_FIELD;
+  bool is_visible =
+    include_all ||
+    ts_subtree_missing(self) ||
+    (
+      alias_symbol
+        ? alias_is_named
+        : ts_subtree_visible(self) && ts_subtree_named(self)
+    );
+
+  if (is_visible) {
+    if (!is_root) {
+      cursor += snprintf(*writer, limit, " ");
+      if (field_name) {
+        cursor += snprintf(*writer, limit, "%s: ", field_name);
+      }
+    }
+
+    if (ts_subtree_is_error(self) && ts_subtree_child_count(self) == 0 && self.ptr->size.bytes > 0) {
+      cursor += snprintf(*writer, limit, "(UNEXPECTED ");
+      cursor += ts_subtree__write_char_to_string(*writer, limit, self.ptr->lookahead_char);
+    } else {
+      TSSymbol symbol = alias_symbol ? alias_symbol : ts_subtree_symbol(self);
+      const char *symbol_name = ts_language_symbol_name(language, symbol);
+      if (ts_subtree_missing(self)) {
+        cursor += snprintf(*writer, limit, "(MISSING ");
+        if (alias_is_named || ts_subtree_named(self)) {
+          cursor += snprintf(*writer, limit, "%s", symbol_name);
+        } else {
+          cursor += snprintf(*writer, limit, "\"%s\"", symbol_name);
+        }
+      } else {
+        cursor += snprintf(*writer, limit, "(%s", symbol_name);
+      }
+    }
+  } else if (is_root) {
+    TSSymbol symbol = alias_symbol ? alias_symbol : ts_subtree_symbol(self);
+    const char *symbol_name = ts_language_symbol_name(language, symbol);
+    if (ts_subtree_child_count(self) > 0) {
+      cursor += snprintf(*writer, limit, "(%s", symbol_name);
+    } else if (ts_subtree_named(self)) {
+      cursor += snprintf(*writer, limit, "(%s)", symbol_name);
+    } else {
+      cursor += snprintf(*writer, limit, "(\"%s\")", symbol_name);
+    }
+  }
+
+  if (ts_subtree_child_count(self)) {
+    const TSSymbol *alias_sequence = ts_language_alias_sequence(language, self.ptr->production_id);
+    const TSFieldMapEntry *field_map, *field_map_end;
+    ts_language_field_map(
+      language,
+      self.ptr->production_id,
+      &field_map,
+      &field_map_end
+    );
+
+    uint32_t structural_child_index = 0;
+    for (uint32_t i = 0; i < self.ptr->child_count; i++) {
+      Subtree child = ts_subtree_children(self)[i];
+      if (ts_subtree_extra(child)) {
+        cursor += ts_subtree__write_to_string(
+          child, *writer, limit,
+          language, include_all,
+          0, false, NULL
+        );
+      } else {
+        TSSymbol subtree_alias_symbol = alias_sequence
+          ? alias_sequence[structural_child_index]
+          : 0;
+        bool subtree_alias_is_named = subtree_alias_symbol
+          ? ts_language_symbol_metadata(language, subtree_alias_symbol).named
+          : false;
+
+        const char *child_field_name = is_visible ? NULL : field_name;
+        for (const TSFieldMapEntry *map = field_map; map < field_map_end; map++) {
+          if (!map->inherited && map->child_index == structural_child_index) {
+            child_field_name = language->field_names[map->field_id];
+            break;
+          }
+        }
+
+        cursor += ts_subtree__write_to_string(
+          child, *writer, limit,
+          language, include_all,
+          subtree_alias_symbol, subtree_alias_is_named, child_field_name
+        );
+        structural_child_index++;
+      }
+    }
+  }
+
+  if (is_visible) cursor += snprintf(*writer, limit, ")");
+
+  return cursor - string;
+}
+
+char *ts_subtree_string(
+  Subtree self,
+  TSSymbol alias_symbol,
+  bool alias_is_named,
+  const TSLanguage *language,
+  bool include_all
+) {
+  char scratch_string[1];
+  size_t size = ts_subtree__write_to_string(
+    self, scratch_string, 1,
+    language, include_all,
+    alias_symbol, alias_is_named, ROOT_FIELD
+  ) + 1;
+  char *result = ts_malloc(size * sizeof(char));
+  ts_subtree__write_to_string(
+    self, result, size,
+    language, include_all,
+    alias_symbol, alias_is_named, ROOT_FIELD
+  );
+  return result;
+}
+
+void ts_subtree__print_dot_graph(const Subtree *self, uint32_t start_offset,
+                                 const TSLanguage *language, TSSymbol alias_symbol,
+                                 FILE *f) {
+  TSSymbol subtree_symbol = ts_subtree_symbol(*self);
+  TSSymbol symbol = alias_symbol ? alias_symbol : subtree_symbol;
+  uint32_t end_offset = start_offset + ts_subtree_total_bytes(*self);
+  fprintf(f, "tree_%p [label=\"", (void *)self);
+  ts_language_write_symbol_as_dot_string(language, f, symbol);
+  fprintf(f, "\"");
+
+  if (ts_subtree_child_count(*self) == 0) fprintf(f, ", shape=plaintext");
+  if (ts_subtree_extra(*self)) fprintf(f, ", fontcolor=gray");
+
+  fprintf(f, ", tooltip=\""
+    "range: %u - %u\n"
+    "state: %d\n"
+    "error-cost: %u\n"
+    "has-changes: %u\n"
+    "depends-on-column: %u\n"
+    "descendant-count: %u\n"
+    "repeat-depth: %u\n"
+    "lookahead-bytes: %u",
+    start_offset, end_offset,
+    ts_subtree_parse_state(*self),
+    ts_subtree_error_cost(*self),
+    ts_subtree_has_changes(*self),
+    ts_subtree_depends_on_column(*self),
+    ts_subtree_visible_descendant_count(*self),
+    ts_subtree_repeat_depth(*self),
+    ts_subtree_lookahead_bytes(*self)
+  );
+
+  if (ts_subtree_is_error(*self) && ts_subtree_child_count(*self) == 0 && self->ptr->lookahead_char != 0) {
+    fprintf(f, "\ncharacter: '%c'", self->ptr->lookahead_char);
+  }
+
+  fprintf(f, "\"]\n");
+
+  uint32_t child_start_offset = start_offset;
+  uint32_t child_info_offset =
+    language->max_alias_sequence_length *
+    ts_subtree_production_id(*self);
+  for (uint32_t i = 0, n = ts_subtree_child_count(*self); i < n; i++) {
+    const Subtree *child = &ts_subtree_children(*self)[i];
+    TSSymbol subtree_alias_symbol = 0;
+    if (!ts_subtree_extra(*child) && child_info_offset) {
+      subtree_alias_symbol = language->alias_sequences[child_info_offset];
+      child_info_offset++;
+    }
+    ts_subtree__print_dot_graph(child, child_start_offset, language, subtree_alias_symbol, f);
+    fprintf(f, "tree_%p -> tree_%p [tooltip=%u]\n", (void *)self, (void *)child, i);
+    child_start_offset += ts_subtree_total_bytes(*child);
+  }
+}
+
+void ts_subtree_print_dot_graph(Subtree self, const TSLanguage *language, FILE *f) {
+  fprintf(f, "digraph tree {\n");
+  fprintf(f, "edge [arrowhead=none]\n");
+  ts_subtree__print_dot_graph(&self, 0, language, 0, f);
+  fprintf(f, "}\n");
+}
+
+const ExternalScannerState *ts_subtree_external_scanner_state(Subtree self) {
+  static const ExternalScannerState empty_state = {{.short_data = {0}}, .length = 0};
+  if (
+    self.ptr &&
+    !self.data.is_inline &&
+    self.ptr->has_external_tokens &&
+    self.ptr->child_count == 0
+  ) {
+    return &self.ptr->external_scanner_state;
+  } else {
+    return &empty_state;
+  }
+}
+
+bool ts_subtree_external_scanner_state_eq(Subtree self, Subtree other) {
+  const ExternalScannerState *state_self = ts_subtree_external_scanner_state(self);
+  const ExternalScannerState *state_other = ts_subtree_external_scanner_state(other);
+  return ts_external_scanner_state_eq(
+    state_self,
+    ts_external_scanner_state_data(state_other),
+    state_other->length
+  );
+}
diff --git a/vendor/tree-sitter/lib/src/subtree.h b/vendor/tree-sitter/lib/src/subtree.h
new file mode 100644
--- /dev/null
+++ b/vendor/tree-sitter/lib/src/subtree.h
@@ -0,0 +1,382 @@
+#ifndef TREE_SITTER_SUBTREE_H_
+#define TREE_SITTER_SUBTREE_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <limits.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include "./length.h"
+#include "./array.h"
+#include "./error_costs.h"
+#include "./host.h"
+#include "tree_sitter/api.h"
+#include "./parser.h"
+
+#define TS_TREE_STATE_NONE USHRT_MAX
+#define NULL_SUBTREE ((Subtree) {.ptr = NULL})
+
+// The serialized state of an external scanner.
+//
+// Every time an external token subtree is created after a call to an
+// external scanner, the scanner's `serialize` function is called to
+// retrieve a serialized copy of its state. The bytes are then copied
+// onto the subtree itself so that the scanner's state can later be
+// restored using its `deserialize` function.
+//
+// Small byte arrays are stored inline, and long ones are allocated
+// separately on the heap.
+typedef struct {
+  union {
+    char *long_data;
+    char short_data[24];
+  };
+  uint32_t length;
+} ExternalScannerState;
+
+// A compact representation of a subtree.
+//
+// This representation is used for small leaf nodes that are not
+// errors, and were not created by an external scanner.
+//
+// The idea behind the layout of this struct is that the `is_inline`
+// bit will fall exactly into the same location as the least significant
+// bit of the pointer in `Subtree` or `MutableSubtree`, respectively.
+// Because of alignment, for any valid pointer this will be 0, giving
+// us the opportunity to make use of this bit to signify whether to use
+// the pointer or the inline struct.
+typedef struct SubtreeInlineData SubtreeInlineData;
+
+#define SUBTREE_BITS    \
+  bool visible : 1;     \
+  bool named : 1;       \
+  bool extra : 1;       \
+  bool has_changes : 1; \
+  bool is_missing : 1;  \
+  bool is_keyword : 1;
+
+#define SUBTREE_SIZE           \
+  uint8_t padding_columns;     \
+  uint8_t padding_rows : 4;    \
+  uint8_t lookahead_bytes : 4; \
+  uint8_t padding_bytes;       \
+  uint8_t size_bytes;
+
+#if TS_BIG_ENDIAN
+#if TS_PTR_SIZE == 32
+
+struct SubtreeInlineData {
+  uint16_t parse_state;
+  uint8_t symbol;
+  SUBTREE_BITS
+  bool unused : 1;
+  bool is_inline : 1;
+  SUBTREE_SIZE
+};
+
+#else
+
+struct SubtreeInlineData {
+  SUBTREE_SIZE
+  uint16_t parse_state;
+  uint8_t symbol;
+  SUBTREE_BITS
+  bool unused : 1;
+  bool is_inline : 1;
+};
+
+#endif
+#else
+
+struct SubtreeInlineData {
+  bool is_inline : 1;
+  SUBTREE_BITS
+  uint8_t symbol;
+  uint16_t parse_state;
+  SUBTREE_SIZE
+};
+
+#endif
+
+#undef SUBTREE_BITS
+#undef SUBTREE_SIZE
+
+// A heap-allocated representation of a subtree.
+//
+// This representation is used for parent nodes, external tokens,
+// errors, and other leaf nodes whose data is too large to fit into
+// the inline representation.
+typedef struct {
+  volatile uint32_t ref_count;
+  Length padding;
+  Length size;
+  uint32_t lookahead_bytes;
+  uint32_t error_cost;
+  uint32_t child_count;
+  TSSymbol symbol;
+  TSStateId parse_state;
+
+  bool visible : 1;
+  bool named : 1;
+  bool extra : 1;
+  bool fragile_left : 1;
+  bool fragile_right : 1;
+  bool has_changes : 1;
+  bool has_external_tokens : 1;
+  bool has_external_scanner_state_change : 1;
+  bool depends_on_column: 1;
+  bool is_missing : 1;
+  bool is_keyword : 1;
+
+  union {
+    // Non-terminal subtrees (`child_count > 0`)
+    struct {
+      uint32_t visible_child_count;
+      uint32_t named_child_count;
+      uint32_t visible_descendant_count;
+      int32_t dynamic_precedence;
+      uint16_t repeat_depth;
+      uint16_t production_id;
+      struct {
+        TSSymbol symbol;
+        TSStateId parse_state;
+      } first_leaf;
+    };
+
+    // External terminal subtrees (`child_count == 0 && has_external_tokens`)
+    ExternalScannerState external_scanner_state;
+
+    // Error terminal subtrees (`child_count == 0 && symbol == ts_builtin_sym_error`)
+    int32_t lookahead_char;
+  };
+} SubtreeHeapData;
+
+// The fundamental building block of a syntax tree.
+typedef union {
+  SubtreeInlineData data;
+  const SubtreeHeapData *ptr;
+} Subtree;
+
+// Like Subtree, but mutable.
+typedef union {
+  SubtreeInlineData data;
+  SubtreeHeapData *ptr;
+} MutableSubtree;
+
+typedef Array(Subtree) SubtreeArray;
+typedef Array(MutableSubtree) MutableSubtreeArray;
+
+typedef struct {
+  MutableSubtreeArray free_trees;
+  MutableSubtreeArray tree_stack;
+} SubtreePool;
+
+void ts_external_scanner_state_init(ExternalScannerState *, const char *, unsigned);
+const char *ts_external_scanner_state_data(const ExternalScannerState *);
+bool ts_external_scanner_state_eq(const ExternalScannerState *self, const char *, unsigned);
+void ts_external_scanner_state_delete(ExternalScannerState *self);
+
+void ts_subtree_array_copy(SubtreeArray, SubtreeArray *);
+void ts_subtree_array_clear(SubtreePool *, SubtreeArray *);
+void ts_subtree_array_delete(SubtreePool *, SubtreeArray *);
+void ts_subtree_array_remove_trailing_extras(SubtreeArray *, SubtreeArray *);
+void ts_subtree_array_reverse(SubtreeArray *);
+
+SubtreePool ts_subtree_pool_new(uint32_t capacity);
+void ts_subtree_pool_delete(SubtreePool *);
+
+Subtree ts_subtree_new_leaf(
+  SubtreePool *, TSSymbol, Length, Length, uint32_t,
+  TSStateId, bool, bool, bool, const TSLanguage *
+);
+Subtree ts_subtree_new_error(
+  SubtreePool *, int32_t, Length, Length, uint32_t, TSStateId, const TSLanguage *
+);
+MutableSubtree ts_subtree_new_node(TSSymbol, SubtreeArray *, unsigned, const TSLanguage *);
+Subtree ts_subtree_new_error_node(SubtreeArray *, bool, const TSLanguage *);
+Subtree ts_subtree_new_missing_leaf(SubtreePool *, TSSymbol, Length, uint32_t, const TSLanguage *);
+MutableSubtree ts_subtree_make_mut(SubtreePool *, Subtree);
+void ts_subtree_retain(Subtree);
+void ts_subtree_release(SubtreePool *, Subtree);
+int ts_subtree_compare(Subtree, Subtree, SubtreePool *);
+void ts_subtree_set_symbol(MutableSubtree *, TSSymbol, const TSLanguage *);
+void ts_subtree_summarize(MutableSubtree, const Subtree *, uint32_t, const TSLanguage *);
+void ts_subtree_summarize_children(MutableSubtree, const TSLanguage *);
+void ts_subtree_balance(Subtree, SubtreePool *, const TSLanguage *);
+Subtree ts_subtree_edit(Subtree, const TSInputEdit *edit, SubtreePool *);
+char *ts_subtree_string(Subtree, TSSymbol, bool, const TSLanguage *, bool include_all);
+void ts_subtree_print_dot_graph(Subtree, const TSLanguage *, FILE *);
+Subtree ts_subtree_last_external_token(Subtree);
+const ExternalScannerState *ts_subtree_external_scanner_state(Subtree self);
+bool ts_subtree_external_scanner_state_eq(Subtree, Subtree);
+
+#define SUBTREE_GET(self, name) ((self).data.is_inline ? (self).data.name : (self).ptr->name)
+
+static inline TSSymbol ts_subtree_symbol(Subtree self) { return SUBTREE_GET(self, symbol); }
+static inline bool ts_subtree_visible(Subtree self) { return SUBTREE_GET(self, visible); }
+static inline bool ts_subtree_named(Subtree self) { return SUBTREE_GET(self, named); }
+static inline bool ts_subtree_extra(Subtree self) { return SUBTREE_GET(self, extra); }
+static inline bool ts_subtree_has_changes(Subtree self) { return SUBTREE_GET(self, has_changes); }
+static inline bool ts_subtree_missing(Subtree self) { return SUBTREE_GET(self, is_missing); }
+static inline bool ts_subtree_is_keyword(Subtree self) { return SUBTREE_GET(self, is_keyword); }
+static inline TSStateId ts_subtree_parse_state(Subtree self) { return SUBTREE_GET(self, parse_state); }
+static inline uint32_t ts_subtree_lookahead_bytes(Subtree self) { return SUBTREE_GET(self, lookahead_bytes); }
+
+#undef SUBTREE_GET
+
+// Get the size needed to store a heap-allocated subtree with the given
+// number of children.
+static inline size_t ts_subtree_alloc_size(uint32_t child_count) {
+  return child_count * sizeof(Subtree) + sizeof(SubtreeHeapData);
+}
+
+// Get a subtree's children, which are allocated immediately before the
+// tree's own heap data.
+#define ts_subtree_children(self) \
+  ((self).data.is_inline ? NULL : (Subtree *)((self).ptr) - (self).ptr->child_count)
+
+static inline void ts_subtree_set_extra(MutableSubtree *self, bool is_extra) {
+  if (self->data.is_inline) {
+    self->data.extra = is_extra;
+  } else {
+    self->ptr->extra = is_extra;
+  }
+}
+
+static inline TSSymbol ts_subtree_leaf_symbol(Subtree self) {
+  if (self.data.is_inline) return self.data.symbol;
+  if (self.ptr->child_count == 0) return self.ptr->symbol;
+  return self.ptr->first_leaf.symbol;
+}
+
+static inline TSStateId ts_subtree_leaf_parse_state(Subtree self) {
+  if (self.data.is_inline) return self.data.parse_state;
+  if (self.ptr->child_count == 0) return self.ptr->parse_state;
+  return self.ptr->first_leaf.parse_state;
+}
+
+static inline Length ts_subtree_padding(Subtree self) {
+  if (self.data.is_inline) {
+    Length result = {self.data.padding_bytes, {self.data.padding_rows, self.data.padding_columns}};
+    return result;
+  } else {
+    return self.ptr->padding;
+  }
+}
+
+static inline Length ts_subtree_size(Subtree self) {
+  if (self.data.is_inline) {
+    Length result = {self.data.size_bytes, {0, self.data.size_bytes}};
+    return result;
+  } else {
+    return self.ptr->size;
+  }
+}
+
+static inline Length ts_subtree_total_size(Subtree self) {
+  return length_add(ts_subtree_padding(self), ts_subtree_size(self));
+}
+
+static inline uint32_t ts_subtree_total_bytes(Subtree self) {
+  return ts_subtree_total_size(self).bytes;
+}
+
+static inline uint32_t ts_subtree_child_count(Subtree self) {
+  return self.data.is_inline ? 0 : self.ptr->child_count;
+}
+
+static inline uint32_t ts_subtree_repeat_depth(Subtree self) {
+  return self.data.is_inline ? 0 : self.ptr->repeat_depth;
+}
+
+static inline uint32_t ts_subtree_is_repetition(Subtree self) {
+  return self.data.is_inline
+    ? 0
+    : !self.ptr->named && !self.ptr->visible && self.ptr->child_count != 0;
+}
+
+static inline uint32_t ts_subtree_visible_descendant_count(Subtree self) {
+  return (self.data.is_inline || self.ptr->child_count == 0)
+    ? 0
+    : self.ptr->visible_descendant_count;
+}
+
+static inline uint32_t ts_subtree_visible_child_count(Subtree self) {
+  if (ts_subtree_child_count(self) > 0) {
+    return self.ptr->visible_child_count;
+  } else {
+    return 0;
+  }
+}
+
+static inline uint32_t ts_subtree_error_cost(Subtree self) {
+  if (ts_subtree_missing(self)) {
+    return ERROR_COST_PER_MISSING_TREE + ERROR_COST_PER_RECOVERY;
+  } else {
+    return self.data.is_inline ? 0 : self.ptr->error_cost;
+  }
+}
+
+static inline int32_t ts_subtree_dynamic_precedence(Subtree self) {
+  return (self.data.is_inline || self.ptr->child_count == 0) ? 0 : self.ptr->dynamic_precedence;
+}
+
+static inline uint16_t ts_subtree_production_id(Subtree self) {
+  if (ts_subtree_child_count(self) > 0) {
+    return self.ptr->production_id;
+  } else {
+    return 0;
+  }
+}
+
+static inline bool ts_subtree_fragile_left(Subtree self) {
+  return self.data.is_inline ? false : self.ptr->fragile_left;
+}
+
+static inline bool ts_subtree_fragile_right(Subtree self) {
+  return self.data.is_inline ? false : self.ptr->fragile_right;
+}
+
+static inline bool ts_subtree_has_external_tokens(Subtree self) {
+  return self.data.is_inline ? false : self.ptr->has_external_tokens;
+}
+
+static inline bool ts_subtree_has_external_scanner_state_change(Subtree self) {
+  return self.data.is_inline ? false : self.ptr->has_external_scanner_state_change;
+}
+
+static inline bool ts_subtree_depends_on_column(Subtree self) {
+  return self.data.is_inline ? false : self.ptr->depends_on_column;
+}
+
+static inline bool ts_subtree_is_fragile(Subtree self) {
+  return self.data.is_inline ? false : (self.ptr->fragile_left || self.ptr->fragile_right);
+}
+
+static inline bool ts_subtree_is_error(Subtree self) {
+  return ts_subtree_symbol(self) == ts_builtin_sym_error;
+}
+
+static inline bool ts_subtree_is_eof(Subtree self) {
+  return ts_subtree_symbol(self) == ts_builtin_sym_end;
+}
+
+static inline Subtree ts_subtree_from_mut(MutableSubtree self) {
+  Subtree result;
+  result.data = self.data;
+  return result;
+}
+
+static inline MutableSubtree ts_subtree_to_mut_unsafe(Subtree self) {
+  MutableSubtree result;
+  result.data = self.data;
+  return result;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  // TREE_SITTER_SUBTREE_H_
diff --git a/vendor/tree-sitter/lib/src/tree.c b/vendor/tree-sitter/lib/src/tree.c
new file mode 100644
--- /dev/null
+++ b/vendor/tree-sitter/lib/src/tree.c
@@ -0,0 +1,172 @@
+#define _POSIX_C_SOURCE 200112L
+
+#include "tree_sitter/api.h"
+#include "./array.h"
+#include "./get_changed_ranges.h"
+#include "./length.h"
+#include "./subtree.h"
+#include "./tree_cursor.h"
+#include "./tree.h"
+
+TSTree *ts_tree_new(
+  Subtree root, const TSLanguage *language,
+  const TSRange *included_ranges, unsigned included_range_count
+) {
+  TSTree *result = ts_malloc(sizeof(TSTree));
+  result->root = root;
+  result->language = ts_language_copy(language);
+  result->included_ranges = ts_calloc(included_range_count, sizeof(TSRange));
+  memcpy(result->included_ranges, included_ranges, included_range_count * sizeof(TSRange));
+  result->included_range_count = included_range_count;
+  return result;
+}
+
+TSTree *ts_tree_copy(const TSTree *self) {
+  ts_subtree_retain(self->root);
+  return ts_tree_new(self->root, self->language, self->included_ranges, self->included_range_count);
+}
+
+void ts_tree_delete(TSTree *self) {
+  if (!self) return;
+
+  SubtreePool pool = ts_subtree_pool_new(0);
+  ts_subtree_release(&pool, self->root);
+  ts_subtree_pool_delete(&pool);
+  ts_language_delete(self->language);
+  ts_free(self->included_ranges);
+  ts_free(self);
+}
+
+TSNode ts_tree_root_node(const TSTree *self) {
+  return ts_node_new(self, &self->root, ts_subtree_padding(self->root), 0);
+}
+
+TSNode ts_tree_root_node_with_offset(
+  const TSTree *self,
+  uint32_t offset_bytes,
+  TSPoint offset_extent
+) {
+  Length offset = {offset_bytes, offset_extent};
+  return ts_node_new(self, &self->root, length_add(offset, ts_subtree_padding(self->root)), 0);
+}
+
+const TSLanguage *ts_tree_language(const TSTree *self) {
+  return self->language;
+}
+
+void ts_tree_edit(TSTree *self, const TSInputEdit *edit) {
+  for (unsigned i = 0; i < self->included_range_count; i++) {
+    TSRange *range = &self->included_ranges[i];
+    if (range->end_byte >= edit->old_end_byte) {
+      if (range->end_byte != UINT32_MAX) {
+        range->end_byte = edit->new_end_byte + (range->end_byte - edit->old_end_byte);
+        range->end_point = point_add(
+          edit->new_end_point,
+          point_sub(range->end_point, edit->old_end_point)
+        );
+        if (range->end_byte < edit->new_end_byte) {
+          range->end_byte = UINT32_MAX;
+          range->end_point = POINT_MAX;
+        }
+      }
+    } else if (range->end_byte > edit->start_byte) {
+      range->end_byte = edit->start_byte;
+      range->end_point = edit->start_point;
+    }
+    if (range->start_byte >= edit->old_end_byte) {
+      range->start_byte = edit->new_end_byte + (range->start_byte - edit->old_end_byte);
+      range->start_point = point_add(
+        edit->new_end_point,
+        point_sub(range->start_point, edit->old_end_point)
+      );
+      if (range->start_byte < edit->new_end_byte) {
+        range->start_byte = UINT32_MAX;
+        range->start_point = POINT_MAX;
+      }
+    } else if (range->start_byte > edit->start_byte) {
+      range->start_byte = edit->start_byte;
+      range->start_point = edit->start_point;
+    }
+  }
+
+  SubtreePool pool = ts_subtree_pool_new(0);
+  self->root = ts_subtree_edit(self->root, edit, &pool);
+  ts_subtree_pool_delete(&pool);
+}
+
+TSRange *ts_tree_included_ranges(const TSTree *self, uint32_t *length) {
+  *length = self->included_range_count;
+  TSRange *ranges = ts_calloc(self->included_range_count, sizeof(TSRange));
+  memcpy(ranges, self->included_ranges, self->included_range_count * sizeof(TSRange));
+  return ranges;
+}
+
+TSRange *ts_tree_get_changed_ranges(const TSTree *old_tree, const TSTree *new_tree, uint32_t *length) {
+  TreeCursor cursor1 = {NULL, array_new(), 0};
+  TreeCursor cursor2 = {NULL, array_new(), 0};
+  ts_tree_cursor_init(&cursor1, ts_tree_root_node(old_tree));
+  ts_tree_cursor_init(&cursor2, ts_tree_root_node(new_tree));
+
+  TSRangeArray included_range_differences = array_new();
+  ts_range_array_get_changed_ranges(
+    old_tree->included_ranges, old_tree->included_range_count,
+    new_tree->included_ranges, new_tree->included_range_count,
+    &included_range_differences
+  );
+
+  TSRange *result;
+  *length = ts_subtree_get_changed_ranges(
+    &old_tree->root, &new_tree->root, &cursor1, &cursor2,
+    old_tree->language, &included_range_differences, &result
+  );
+
+  array_delete(&included_range_differences);
+  array_delete(&cursor1.stack);
+  array_delete(&cursor2.stack);
+  return result;
+}
+
+#ifdef _WIN32
+
+#include <io.h>
+#include <windows.h>
+
+int _ts_dup(HANDLE handle) {
+  HANDLE dup_handle;
+  if (!DuplicateHandle(
+    GetCurrentProcess(), handle,
+    GetCurrentProcess(), &dup_handle,
+    0, FALSE, DUPLICATE_SAME_ACCESS
+  )) return -1;
+
+  return _open_osfhandle((intptr_t)dup_handle, 0);
+}
+
+void ts_tree_print_dot_graph(const TSTree *self, int fd) {
+  FILE *file = _fdopen(_ts_dup((HANDLE)_get_osfhandle(fd)), "a");
+  ts_subtree_print_dot_graph(self->root, self->language, file);
+  fclose(file);
+}
+
+#elif !defined(__wasi__) // WASI doesn't support dup
+
+#include <unistd.h>
+
+int _ts_dup(int file_descriptor) {
+  return dup(file_descriptor);
+}
+
+void ts_tree_print_dot_graph(const TSTree *self, int file_descriptor) {
+  FILE *file = fdopen(_ts_dup(file_descriptor), "a");
+  ts_subtree_print_dot_graph(self->root, self->language, file);
+  fclose(file);
+}
+
+#else
+
+void ts_tree_print_dot_graph(const TSTree *self, int file_descriptor) {
+  (void)self;
+  (void)file_descriptor;
+}
+
+#endif
diff --git a/vendor/tree-sitter/lib/src/tree.h b/vendor/tree-sitter/lib/src/tree.h
new file mode 100644
--- /dev/null
+++ b/vendor/tree-sitter/lib/src/tree.h
@@ -0,0 +1,31 @@
+#ifndef TREE_SITTER_TREE_H_
+#define TREE_SITTER_TREE_H_
+
+#include "./subtree.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct {
+  const Subtree *child;
+  const Subtree *parent;
+  Length position;
+  TSSymbol alias_symbol;
+} ParentCacheEntry;
+
+struct TSTree {
+  Subtree root;
+  const TSLanguage *language;
+  TSRange *included_ranges;
+  unsigned included_range_count;
+};
+
+TSTree *ts_tree_new(Subtree root, const TSLanguage *language, const TSRange *included_ranges, unsigned included_range_count);
+TSNode ts_node_new(const TSTree *tree, const Subtree *subtree, Length position, TSSymbol alias);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  // TREE_SITTER_TREE_H_
diff --git a/vendor/tree-sitter/lib/src/tree_cursor.c b/vendor/tree-sitter/lib/src/tree_cursor.c
new file mode 100644
--- /dev/null
+++ b/vendor/tree-sitter/lib/src/tree_cursor.c
@@ -0,0 +1,715 @@
+#include "tree_sitter/api.h"
+#include "./alloc.h"
+#include "./tree_cursor.h"
+#include "./language.h"
+#include "./tree.h"
+
+typedef struct {
+  Subtree parent;
+  const TSTree *tree;
+  Length position;
+  uint32_t child_index;
+  uint32_t structural_child_index;
+  uint32_t descendant_index;
+  const TSSymbol *alias_sequence;
+} CursorChildIterator;
+
+// CursorChildIterator
+
+static inline bool ts_tree_cursor_is_entry_visible(const TreeCursor *self, uint32_t index) {
+  TreeCursorEntry *entry = &self->stack.contents[index];
+  if (index == 0 || ts_subtree_visible(*entry->subtree)) {
+    return true;
+  } else if (!ts_subtree_extra(*entry->subtree)) {
+    TreeCursorEntry *parent_entry = &self->stack.contents[index - 1];
+    return ts_language_alias_at(
+      self->tree->language,
+      parent_entry->subtree->ptr->production_id,
+      entry->structural_child_index
+    );
+  } else {
+    return false;
+  }
+}
+
+static inline CursorChildIterator ts_tree_cursor_iterate_children(const TreeCursor *self) {
+  TreeCursorEntry *last_entry = array_back(&self->stack);
+  if (ts_subtree_child_count(*last_entry->subtree) == 0) {
+    return (CursorChildIterator) {NULL_SUBTREE, self->tree, length_zero(), 0, 0, 0, NULL};
+  }
+  const TSSymbol *alias_sequence = ts_language_alias_sequence(
+    self->tree->language,
+    last_entry->subtree->ptr->production_id
+  );
+
+  uint32_t descendant_index = last_entry->descendant_index;
+  if (ts_tree_cursor_is_entry_visible(self, self->stack.size - 1)) {
+    descendant_index += 1;
+  }
+
+  return (CursorChildIterator) {
+    .tree = self->tree,
+    .parent = *last_entry->subtree,
+    .position = last_entry->position,
+    .child_index = 0,
+    .structural_child_index = 0,
+    .descendant_index = descendant_index,
+    .alias_sequence = alias_sequence,
+  };
+}
+
+static inline bool ts_tree_cursor_child_iterator_next(
+  CursorChildIterator *self,
+  TreeCursorEntry *result,
+  bool *visible
+) {
+  if (!self->parent.ptr || self->child_index == self->parent.ptr->child_count) return false;
+  const Subtree *child = &ts_subtree_children(self->parent)[self->child_index];
+  *result = (TreeCursorEntry) {
+    .subtree = child,
+    .position = self->position,
+    .child_index = self->child_index,
+    .structural_child_index = self->structural_child_index,
+    .descendant_index = self->descendant_index,
+  };
+  *visible = ts_subtree_visible(*child);
+  bool extra = ts_subtree_extra(*child);
+  if (!extra) {
+    if (self->alias_sequence) {
+      *visible |= self->alias_sequence[self->structural_child_index];
+    }
+    self->structural_child_index++;
+  }
+
+  self->descendant_index += ts_subtree_visible_descendant_count(*child);
+  if (*visible) {
+    self->descendant_index += 1;
+  }
+
+  self->position = length_add(self->position, ts_subtree_size(*child));
+  self->child_index++;
+
+  if (self->child_index < self->parent.ptr->child_count) {
+    Subtree next_child = ts_subtree_children(self->parent)[self->child_index];
+    self->position = length_add(self->position, ts_subtree_padding(next_child));
+  }
+
+  return true;
+}
+
+// Return a position that, when `b` is added to it, yields `a`. This
+// can only be computed if `b` has zero rows. Otherwise, this function
+// returns `LENGTH_UNDEFINED`, and the caller needs to recompute
+// the position some other way.
+static inline Length length_backtrack(Length a, Length b) {
+  if (length_is_undefined(a) || b.extent.row != 0) {
+    return LENGTH_UNDEFINED;
+  }
+
+  Length result;
+  result.bytes = a.bytes - b.bytes;
+  result.extent.row = a.extent.row;
+  result.extent.column = a.extent.column - b.extent.column;
+  return result;
+}
+
+static inline bool ts_tree_cursor_child_iterator_previous(
+  CursorChildIterator *self,
+  TreeCursorEntry *result,
+  bool *visible
+) {
+  // this is mostly a reverse `ts_tree_cursor_child_iterator_next` taking into
+  // account unsigned underflow
+  if (!self->parent.ptr || (int8_t)self->child_index == -1) return false;
+  const Subtree *child = &ts_subtree_children(self->parent)[self->child_index];
+  *result = (TreeCursorEntry) {
+    .subtree = child,
+    .position = self->position,
+    .child_index = self->child_index,
+    .structural_child_index = self->structural_child_index,
+  };
+  *visible = ts_subtree_visible(*child);
+  bool extra = ts_subtree_extra(*child);
+  if (!extra && self->alias_sequence) {
+    *visible |= self->alias_sequence[self->structural_child_index];
+    self->structural_child_index--;
+  }
+
+  self->position = length_backtrack(self->position, ts_subtree_padding(*child));
+  self->child_index--;
+
+  // unsigned can underflow so compare it to child_count
+  if (self->child_index < self->parent.ptr->child_count) {
+    Subtree previous_child = ts_subtree_children(self->parent)[self->child_index];
+    Length size = ts_subtree_size(previous_child);
+    self->position = length_backtrack(self->position, size);
+  }
+
+  return true;
+}
+
+// TSTreeCursor - lifecycle
+
+TSTreeCursor ts_tree_cursor_new(TSNode node) {
+  TSTreeCursor self = {NULL, NULL, {0, 0, 0}};
+  ts_tree_cursor_init((TreeCursor *)&self, node);
+  return self;
+}
+
+void ts_tree_cursor_reset(TSTreeCursor *_self, TSNode node) {
+  ts_tree_cursor_init((TreeCursor *)_self, node);
+}
+
+void ts_tree_cursor_init(TreeCursor *self, TSNode node) {
+  self->tree = node.tree;
+  self->root_alias_symbol = node.context[3];
+  array_clear(&self->stack);
+  array_push(&self->stack, ((TreeCursorEntry) {
+    .subtree = (const Subtree *)node.id,
+    .position = {
+      ts_node_start_byte(node),
+      ts_node_start_point(node)
+    },
+    .child_index = 0,
+    .structural_child_index = 0,
+    .descendant_index = 0,
+  }));
+}
+
+void ts_tree_cursor_delete(TSTreeCursor *_self) {
+  TreeCursor *self = (TreeCursor *)_self;
+  array_delete(&self->stack);
+}
+
+// TSTreeCursor - walking the tree
+
+TreeCursorStep ts_tree_cursor_goto_first_child_internal(TSTreeCursor *_self) {
+  TreeCursor *self = (TreeCursor *)_self;
+  bool visible;
+  TreeCursorEntry entry;
+  CursorChildIterator iterator = ts_tree_cursor_iterate_children(self);
+  while (ts_tree_cursor_child_iterator_next(&iterator, &entry, &visible)) {
+    if (visible) {
+      array_push(&self->stack, entry);
+      return TreeCursorStepVisible;
+    }
+    if (ts_subtree_visible_child_count(*entry.subtree) > 0) {
+      array_push(&self->stack, entry);
+      return TreeCursorStepHidden;
+    }
+  }
+  return TreeCursorStepNone;
+}
+
+bool ts_tree_cursor_goto_first_child(TSTreeCursor *self) {
+  for (;;) {
+    switch (ts_tree_cursor_goto_first_child_internal(self)) {
+      case TreeCursorStepHidden:
+        continue;
+      case TreeCursorStepVisible:
+        return true;
+      default:
+        return false;
+    }
+  }
+  return false;
+}
+
+TreeCursorStep ts_tree_cursor_goto_last_child_internal(TSTreeCursor *_self) {
+  TreeCursor *self = (TreeCursor *)_self;
+  bool visible;
+  TreeCursorEntry entry;
+  CursorChildIterator iterator = ts_tree_cursor_iterate_children(self);
+  if (!iterator.parent.ptr || iterator.parent.ptr->child_count == 0) return TreeCursorStepNone;
+
+  TreeCursorEntry last_entry = {0};
+  TreeCursorStep last_step = TreeCursorStepNone;
+  while (ts_tree_cursor_child_iterator_next(&iterator, &entry, &visible)) {
+    if (visible) {
+      last_entry = entry;
+      last_step = TreeCursorStepVisible;
+    }
+    else if (ts_subtree_visible_child_count(*entry.subtree) > 0) {
+      last_entry = entry;
+      last_step = TreeCursorStepHidden;
+    }
+  }
+  if (last_entry.subtree) {
+    array_push(&self->stack, last_entry);
+    return last_step;
+  }
+
+  return TreeCursorStepNone;
+}
+
+bool ts_tree_cursor_goto_last_child(TSTreeCursor *self) {
+  for (;;) {
+    switch (ts_tree_cursor_goto_last_child_internal(self)) {
+      case TreeCursorStepHidden:
+        continue;
+      case TreeCursorStepVisible:
+        return true;
+      default:
+        return false;
+    }
+  }
+  return false;
+}
+
+static inline int64_t ts_tree_cursor_goto_first_child_for_byte_and_point(
+  TSTreeCursor *_self,
+  uint32_t goal_byte,
+  TSPoint goal_point
+) {
+  TreeCursor *self = (TreeCursor *)_self;
+  uint32_t initial_size = self->stack.size;
+  uint32_t visible_child_index = 0;
+
+  bool did_descend;
+  do {
+    did_descend = false;
+
+    bool visible;
+    TreeCursorEntry entry;
+    CursorChildIterator iterator = ts_tree_cursor_iterate_children(self);
+    while (ts_tree_cursor_child_iterator_next(&iterator, &entry, &visible)) {
+      Length entry_end = length_add(entry.position, ts_subtree_size(*entry.subtree));
+      bool at_goal = entry_end.bytes > goal_byte && point_gt(entry_end.extent, goal_point);
+      uint32_t visible_child_count = ts_subtree_visible_child_count(*entry.subtree);
+      if (at_goal) {
+        if (visible) {
+          array_push(&self->stack, entry);
+          return visible_child_index;
+        }
+        if (visible_child_count > 0) {
+          array_push(&self->stack, entry);
+          did_descend = true;
+          break;
+        }
+      } else if (visible) {
+        visible_child_index++;
+      } else {
+        visible_child_index += visible_child_count;
+      }
+    }
+  } while (did_descend);
+
+  self->stack.size = initial_size;
+  return -1;
+}
+
+int64_t ts_tree_cursor_goto_first_child_for_byte(TSTreeCursor *self, uint32_t goal_byte) {
+  return ts_tree_cursor_goto_first_child_for_byte_and_point(self, goal_byte, POINT_ZERO);
+}
+
+int64_t ts_tree_cursor_goto_first_child_for_point(TSTreeCursor *self, TSPoint goal_point) {
+  return ts_tree_cursor_goto_first_child_for_byte_and_point(self, 0, goal_point);
+}
+
+TreeCursorStep ts_tree_cursor_goto_sibling_internal(
+    TSTreeCursor *_self,
+    bool (*advance)(CursorChildIterator *, TreeCursorEntry *, bool *)) {
+  TreeCursor *self = (TreeCursor *)_self;
+  uint32_t initial_size = self->stack.size;
+
+  while (self->stack.size > 1) {
+    TreeCursorEntry entry = array_pop(&self->stack);
+    CursorChildIterator iterator = ts_tree_cursor_iterate_children(self);
+    iterator.child_index = entry.child_index;
+    iterator.structural_child_index = entry.structural_child_index;
+    iterator.position = entry.position;
+    iterator.descendant_index = entry.descendant_index;
+
+    bool visible = false;
+    advance(&iterator, &entry, &visible);
+    if (visible && self->stack.size + 1 < initial_size) break;
+
+    while (advance(&iterator, &entry, &visible)) {
+      if (visible) {
+        array_push(&self->stack, entry);
+        return TreeCursorStepVisible;
+      }
+
+      if (ts_subtree_visible_child_count(*entry.subtree)) {
+        array_push(&self->stack, entry);
+        return TreeCursorStepHidden;
+      }
+    }
+  }
+
+  self->stack.size = initial_size;
+  return TreeCursorStepNone;
+}
+
+TreeCursorStep ts_tree_cursor_goto_next_sibling_internal(TSTreeCursor *_self) {
+  return ts_tree_cursor_goto_sibling_internal(_self, ts_tree_cursor_child_iterator_next);
+}
+
+bool ts_tree_cursor_goto_next_sibling(TSTreeCursor *self) {
+  switch (ts_tree_cursor_goto_next_sibling_internal(self)) {
+    case TreeCursorStepHidden:
+      ts_tree_cursor_goto_first_child(self);
+      return true;
+    case TreeCursorStepVisible:
+      return true;
+    default:
+      return false;
+  }
+}
+
+TreeCursorStep ts_tree_cursor_goto_previous_sibling_internal(TSTreeCursor *_self) {
+  // since subtracting across row loses column information, we may have to
+  // restore it
+  TreeCursor *self = (TreeCursor *)_self;
+
+  // for that, save current position before traversing
+  TreeCursorStep step = ts_tree_cursor_goto_sibling_internal(
+      _self, ts_tree_cursor_child_iterator_previous);
+  if (step == TreeCursorStepNone)
+    return step;
+
+  // if length is already valid, there's no need to recompute it
+  if (!length_is_undefined(array_back(&self->stack)->position))
+    return step;
+
+  // restore position from the parent node
+  const TreeCursorEntry *parent = &self->stack.contents[self->stack.size - 2];
+  Length position = parent->position;
+  uint32_t child_index = array_back(&self->stack)->child_index;
+  const Subtree *children = ts_subtree_children((*(parent->subtree)));
+
+  if (child_index > 0) {
+    // skip first child padding since its position should match the position of the parent
+    position = length_add(position, ts_subtree_size(children[0]));
+    for (uint32_t i = 1; i < child_index; ++i) {
+      position = length_add(position, ts_subtree_total_size(children[i]));
+    }
+    position = length_add(position, ts_subtree_padding(children[child_index]));
+  }
+
+  array_back(&self->stack)->position = position;
+
+  return step;
+}
+
+bool ts_tree_cursor_goto_previous_sibling(TSTreeCursor *self) {
+  switch (ts_tree_cursor_goto_previous_sibling_internal(self)) {
+    case TreeCursorStepHidden:
+      ts_tree_cursor_goto_last_child(self);
+      return true;
+    case TreeCursorStepVisible:
+      return true;
+    default:
+      return false;
+  }
+}
+
+bool ts_tree_cursor_goto_parent(TSTreeCursor *_self) {
+  TreeCursor *self = (TreeCursor *)_self;
+  for (unsigned i = self->stack.size - 2; i + 1 > 0; i--) {
+    if (ts_tree_cursor_is_entry_visible(self, i)) {
+      self->stack.size = i + 1;
+      return true;
+    }
+  }
+  return false;
+}
+
+void ts_tree_cursor_goto_descendant(
+  TSTreeCursor *_self,
+  uint32_t goal_descendant_index
+) {
+  TreeCursor *self = (TreeCursor *)_self;
+
+  // Ascend to the lowest ancestor that contains the goal node.
+  for (;;) {
+    uint32_t i = self->stack.size - 1;
+    TreeCursorEntry *entry = &self->stack.contents[i];
+    uint32_t next_descendant_index =
+      entry->descendant_index +
+      (ts_tree_cursor_is_entry_visible(self, i) ? 1 : 0) +
+      ts_subtree_visible_descendant_count(*entry->subtree);
+    if (
+      (entry->descendant_index <= goal_descendant_index) &&
+      (next_descendant_index > goal_descendant_index)
+    ) {
+      break;
+    } else if (self->stack.size <= 1) {
+      return;
+    } else {
+      self->stack.size--;
+    }
+  }
+
+  // Descend to the goal node.
+  bool did_descend = true;
+  do {
+    did_descend = false;
+    bool visible;
+    TreeCursorEntry entry;
+    CursorChildIterator iterator = ts_tree_cursor_iterate_children(self);
+    if (iterator.descendant_index > goal_descendant_index) {
+      return;
+    }
+
+    while (ts_tree_cursor_child_iterator_next(&iterator, &entry, &visible)) {
+      if (iterator.descendant_index > goal_descendant_index) {
+        array_push(&self->stack, entry);
+        if (visible && entry.descendant_index == goal_descendant_index) {
+          return;
+        } else {
+          did_descend = true;
+          break;
+        }
+      }
+    }
+  } while (did_descend);
+}
+
+uint32_t ts_tree_cursor_current_descendant_index(const TSTreeCursor *_self) {
+  const TreeCursor *self = (const TreeCursor *)_self;
+  TreeCursorEntry *last_entry = array_back(&self->stack);
+  return last_entry->descendant_index;
+}
+
+TSNode ts_tree_cursor_current_node(const TSTreeCursor *_self) {
+  const TreeCursor *self = (const TreeCursor *)_self;
+  TreeCursorEntry *last_entry = array_back(&self->stack);
+  bool is_extra = ts_subtree_extra(*last_entry->subtree);
+  TSSymbol alias_symbol = is_extra ? 0 : self->root_alias_symbol;
+  if (self->stack.size > 1 && !is_extra) {
+    TreeCursorEntry *parent_entry = &self->stack.contents[self->stack.size - 2];
+    alias_symbol = ts_language_alias_at(
+      self->tree->language,
+      parent_entry->subtree->ptr->production_id,
+      last_entry->structural_child_index
+    );
+  }
+  return ts_node_new(
+    self->tree,
+    last_entry->subtree,
+    last_entry->position,
+    alias_symbol
+  );
+}
+
+// Private - Get various facts about the current node that are needed
+// when executing tree queries.
+void ts_tree_cursor_current_status(
+  const TSTreeCursor *_self,
+  TSFieldId *field_id,
+  bool *has_later_siblings,
+  bool *has_later_named_siblings,
+  bool *can_have_later_siblings_with_this_field,
+  TSSymbol *supertypes,
+  unsigned *supertype_count
+) {
+  const TreeCursor *self = (const TreeCursor *)_self;
+  unsigned max_supertypes = *supertype_count;
+  *field_id = 0;
+  *supertype_count = 0;
+  *has_later_siblings = false;
+  *has_later_named_siblings = false;
+  *can_have_later_siblings_with_this_field = false;
+
+  // Walk up the tree, visiting the current node and its invisible ancestors,
+  // because fields can refer to nodes through invisible *wrapper* nodes,
+  for (unsigned i = self->stack.size - 1; i > 0; i--) {
+    TreeCursorEntry *entry = &self->stack.contents[i];
+    TreeCursorEntry *parent_entry = &self->stack.contents[i - 1];
+
+    const TSSymbol *alias_sequence = ts_language_alias_sequence(
+      self->tree->language,
+      parent_entry->subtree->ptr->production_id
+    );
+
+    #define subtree_symbol(subtree, structural_child_index) \
+      ((                                                    \
+        !ts_subtree_extra(subtree) &&                       \
+        alias_sequence &&                                   \
+        alias_sequence[structural_child_index]              \
+      ) ?                                                   \
+        alias_sequence[structural_child_index] :            \
+        ts_subtree_symbol(subtree))
+
+    // Stop walking up when a visible ancestor is found.
+    TSSymbol entry_symbol = subtree_symbol(
+      *entry->subtree,
+      entry->structural_child_index
+    );
+    TSSymbolMetadata entry_metadata = ts_language_symbol_metadata(
+      self->tree->language,
+      entry_symbol
+    );
+    if (i != self->stack.size - 1 && entry_metadata.visible) break;
+
+    // Record any supertypes
+    if (entry_metadata.supertype && *supertype_count < max_supertypes) {
+      supertypes[*supertype_count] = entry_symbol;
+      (*supertype_count)++;
+    }
+
+    // Determine if the current node has later siblings.
+    if (!*has_later_siblings) {
+      unsigned sibling_count = parent_entry->subtree->ptr->child_count;
+      unsigned structural_child_index = entry->structural_child_index;
+      if (!ts_subtree_extra(*entry->subtree)) structural_child_index++;
+      for (unsigned j = entry->child_index + 1; j < sibling_count; j++) {
+        Subtree sibling = ts_subtree_children(*parent_entry->subtree)[j];
+        TSSymbolMetadata sibling_metadata = ts_language_symbol_metadata(
+          self->tree->language,
+          subtree_symbol(sibling, structural_child_index)
+        );
+        if (sibling_metadata.visible) {
+          *has_later_siblings = true;
+          if (*has_later_named_siblings) break;
+          if (sibling_metadata.named) {
+            *has_later_named_siblings = true;
+            break;
+          }
+        } else if (ts_subtree_visible_child_count(sibling) > 0) {
+          *has_later_siblings = true;
+          if (*has_later_named_siblings) break;
+          if (sibling.ptr->named_child_count > 0) {
+            *has_later_named_siblings = true;
+            break;
+          }
+        }
+        if (!ts_subtree_extra(sibling)) structural_child_index++;
+      }
+    }
+
+    #undef subtree_symbol
+
+    if (!ts_subtree_extra(*entry->subtree)) {
+      const TSFieldMapEntry *field_map, *field_map_end;
+      ts_language_field_map(
+        self->tree->language,
+        parent_entry->subtree->ptr->production_id,
+        &field_map, &field_map_end
+      );
+
+      // Look for a field name associated with the current node.
+      if (!*field_id) {
+        for (const TSFieldMapEntry *map = field_map; map < field_map_end; map++) {
+          if (!map->inherited && map->child_index == entry->structural_child_index) {
+            *field_id = map->field_id;
+            break;
+          }
+        }
+      }
+
+      // Determine if the current node can have later siblings with the same field name.
+      if (*field_id) {
+        for (const TSFieldMapEntry *map = field_map; map < field_map_end; map++) {
+          if (
+            map->field_id == *field_id &&
+            map->child_index > entry->structural_child_index
+          ) {
+            *can_have_later_siblings_with_this_field = true;
+            break;
+          }
+        }
+      }
+    }
+  }
+}
+
+uint32_t ts_tree_cursor_current_depth(const TSTreeCursor *_self) {
+  const TreeCursor *self = (const TreeCursor *)_self;
+  uint32_t depth = 0;
+  for (unsigned i = 1; i < self->stack.size; i++) {
+    if (ts_tree_cursor_is_entry_visible(self, i)) {
+      depth++;
+    }
+  }
+  return depth;
+}
+
+TSNode ts_tree_cursor_parent_node(const TSTreeCursor *_self) {
+  const TreeCursor *self = (const TreeCursor *)_self;
+  for (int i = (int)self->stack.size - 2; i >= 0; i--) {
+    TreeCursorEntry *entry = &self->stack.contents[i];
+    bool is_visible = true;
+    TSSymbol alias_symbol = 0;
+    if (i > 0) {
+      TreeCursorEntry *parent_entry = &self->stack.contents[i - 1];
+      alias_symbol = ts_language_alias_at(
+        self->tree->language,
+        parent_entry->subtree->ptr->production_id,
+        entry->structural_child_index
+      );
+      is_visible = (alias_symbol != 0) || ts_subtree_visible(*entry->subtree);
+    }
+    if (is_visible) {
+      return ts_node_new(
+        self->tree,
+        entry->subtree,
+        entry->position,
+        alias_symbol
+      );
+    }
+  }
+  return ts_node_new(NULL, NULL, length_zero(), 0);
+}
+
+TSFieldId ts_tree_cursor_current_field_id(const TSTreeCursor *_self) {
+  const TreeCursor *self = (const TreeCursor *)_self;
+
+  // Walk up the tree, visiting the current node and its invisible ancestors.
+  for (unsigned i = self->stack.size - 1; i > 0; i--) {
+    TreeCursorEntry *entry = &self->stack.contents[i];
+    TreeCursorEntry *parent_entry = &self->stack.contents[i - 1];
+
+    // Stop walking up when another visible node is found.
+    if (
+      i != self->stack.size - 1 &&
+      ts_tree_cursor_is_entry_visible(self, i)
+    ) break;
+
+    if (ts_subtree_extra(*entry->subtree)) break;
+
+    const TSFieldMapEntry *field_map, *field_map_end;
+    ts_language_field_map(
+      self->tree->language,
+      parent_entry->subtree->ptr->production_id,
+      &field_map, &field_map_end
+    );
+    for (const TSFieldMapEntry *map = field_map; map < field_map_end; map++) {
+      if (!map->inherited && map->child_index == entry->structural_child_index) {
+        return map->field_id;
+      }
+    }
+  }
+  return 0;
+}
+
+const char *ts_tree_cursor_current_field_name(const TSTreeCursor *_self) {
+  TSFieldId id = ts_tree_cursor_current_field_id(_self);
+  if (id) {
+    const TreeCursor *self = (const TreeCursor *)_self;
+    return self->tree->language->field_names[id];
+  } else {
+    return NULL;
+  }
+}
+
+TSTreeCursor ts_tree_cursor_copy(const TSTreeCursor *_cursor) {
+  const TreeCursor *cursor = (const TreeCursor *)_cursor;
+  TSTreeCursor res = {NULL, NULL, {0, 0}};
+  TreeCursor *copy = (TreeCursor *)&res;
+  copy->tree = cursor->tree;
+  copy->root_alias_symbol = cursor->root_alias_symbol;
+  array_init(&copy->stack);
+  array_push_all(&copy->stack, &cursor->stack);
+  return res;
+}
+
+void ts_tree_cursor_reset_to(TSTreeCursor *_dst, const TSTreeCursor *_src) {
+  const TreeCursor *cursor = (const TreeCursor *)_src;
+  TreeCursor *copy = (TreeCursor *)_dst;
+  copy->tree = cursor->tree;
+  copy->root_alias_symbol = cursor->root_alias_symbol;
+  array_clear(&copy->stack);
+  array_push_all(&copy->stack, &cursor->stack);
+}
diff --git a/vendor/tree-sitter/lib/src/tree_cursor.h b/vendor/tree-sitter/lib/src/tree_cursor.h
new file mode 100644
--- /dev/null
+++ b/vendor/tree-sitter/lib/src/tree_cursor.h
@@ -0,0 +1,48 @@
+#ifndef TREE_SITTER_TREE_CURSOR_H_
+#define TREE_SITTER_TREE_CURSOR_H_
+
+#include "./subtree.h"
+
+typedef struct {
+  const Subtree *subtree;
+  Length position;
+  uint32_t child_index;
+  uint32_t structural_child_index;
+  uint32_t descendant_index;
+} TreeCursorEntry;
+
+typedef struct {
+  const TSTree *tree;
+  Array(TreeCursorEntry) stack;
+  TSSymbol root_alias_symbol;
+} TreeCursor;
+
+typedef enum {
+  TreeCursorStepNone,
+  TreeCursorStepHidden,
+  TreeCursorStepVisible,
+} TreeCursorStep;
+
+void ts_tree_cursor_init(TreeCursor *self, TSNode node);
+void ts_tree_cursor_current_status(
+  const TSTreeCursor *_self,
+  TSFieldId *field_id,
+  bool *has_later_siblings,
+  bool *has_later_named_siblings,
+  bool *can_have_later_siblings_with_this_field,
+  TSSymbol *supertypes,
+  unsigned *supertype_count
+);
+
+TreeCursorStep ts_tree_cursor_goto_first_child_internal(TSTreeCursor *_self);
+TreeCursorStep ts_tree_cursor_goto_next_sibling_internal(TSTreeCursor *_self);
+
+static inline Subtree ts_tree_cursor_current_subtree(const TSTreeCursor *_self) {
+  const TreeCursor *self = (const TreeCursor *)_self;
+  TreeCursorEntry *last_entry = array_back(&self->stack);
+  return *last_entry->subtree;
+}
+
+TSNode ts_tree_cursor_parent_node(const TSTreeCursor *_self);
+
+#endif  // TREE_SITTER_TREE_CURSOR_H_
diff --git a/vendor/tree-sitter/lib/src/ts_assert.h b/vendor/tree-sitter/lib/src/ts_assert.h
new file mode 100644
--- /dev/null
+++ b/vendor/tree-sitter/lib/src/ts_assert.h
@@ -0,0 +1,11 @@
+#ifndef TREE_SITTER_ASSERT_H_
+#define TREE_SITTER_ASSERT_H_
+
+#ifdef NDEBUG
+#define ts_assert(e) ((void)(e))
+#else
+#include <assert.h>
+#define ts_assert(e) assert(e)
+#endif
+
+#endif // TREE_SITTER_ASSERT_H_
diff --git a/vendor/tree-sitter/lib/src/unicode.h b/vendor/tree-sitter/lib/src/unicode.h
new file mode 100644
--- /dev/null
+++ b/vendor/tree-sitter/lib/src/unicode.h
@@ -0,0 +1,50 @@
+#ifndef TREE_SITTER_UNICODE_H_
+#define TREE_SITTER_UNICODE_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <limits.h>
+#include <stdint.h>
+
+#define U_EXPORT
+#define U_EXPORT2
+#include "unicode/utf8.h"
+#include "unicode/utf16.h"
+
+static const int32_t TS_DECODE_ERROR = U_SENTINEL;
+
+// These functions read one unicode code point from the given string,
+// returning the number of bytes consumed.
+typedef uint32_t (*UnicodeDecodeFunction)(
+  const uint8_t *string,
+  uint32_t length,
+  int32_t *code_point
+);
+
+static inline uint32_t ts_decode_utf8(
+  const uint8_t *string,
+  uint32_t length,
+  int32_t *code_point
+) {
+  uint32_t i = 0;
+  U8_NEXT(string, i, length, *code_point);
+  return i;
+}
+
+static inline uint32_t ts_decode_utf16(
+  const uint8_t *string,
+  uint32_t length,
+  int32_t *code_point
+) {
+  uint32_t i = 0;
+  U16_NEXT(((uint16_t *)string), i, length, *code_point);
+  return i * 2;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  // TREE_SITTER_UNICODE_H_
diff --git a/vendor/tree-sitter/lib/src/unicode/ptypes.h b/vendor/tree-sitter/lib/src/unicode/ptypes.h
new file mode 100644
--- /dev/null
+++ b/vendor/tree-sitter/lib/src/unicode/ptypes.h
@@ -0,0 +1,1 @@
+// This file must exist in order for `utf8.h` and `utf16.h` to be used.
diff --git a/vendor/tree-sitter/lib/src/unicode/umachine.h b/vendor/tree-sitter/lib/src/unicode/umachine.h
new file mode 100644
--- /dev/null
+++ b/vendor/tree-sitter/lib/src/unicode/umachine.h
@@ -0,0 +1,448 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
+/*
+******************************************************************************
+*
+*   Copyright (C) 1999-2015, International Business Machines
+*   Corporation and others.  All Rights Reserved.
+*
+******************************************************************************
+*   file name:  umachine.h
+*   encoding:   UTF-8
+*   tab size:   8 (not used)
+*   indentation:4
+*
+*   created on: 1999sep13
+*   created by: Markus W. Scherer
+*
+*   This file defines basic types and constants for ICU to be
+*   platform-independent. umachine.h and utf.h are included into
+*   utypes.h to provide all the general definitions for ICU.
+*   All of these definitions used to be in utypes.h before
+*   the UTF-handling macros made this unmaintainable.
+*/
+
+#ifndef __UMACHINE_H__
+#define __UMACHINE_H__
+
+
+/**
+ * \file
+ * \brief Basic types and constants for UTF
+ *
+ * <h2> Basic types and constants for UTF </h2>
+ *   This file defines basic types and constants for utf.h to be
+ *   platform-independent. umachine.h and utf.h are included into
+ *   utypes.h to provide all the general definitions for ICU.
+ *   All of these definitions used to be in utypes.h before
+ *   the UTF-handling macros made this unmaintainable.
+ *
+ */
+/*==========================================================================*/
+/* Include platform-dependent definitions                                   */
+/* which are contained in the platform-specific file platform.h             */
+/*==========================================================================*/
+
+#include "unicode/ptypes.h" /* platform.h is included in ptypes.h */
+
+/*
+ * ANSI C headers:
+ * stddef.h defines wchar_t
+ */
+#include <stddef.h>
+
+/*==========================================================================*/
+/* For C wrappers, we use the symbol U_STABLE.                                */
+/* This works properly if the includer is C or C++.                         */
+/* Functions are declared   U_STABLE return-type U_EXPORT2 function-name()... */
+/*==========================================================================*/
+
+/**
+ * \def U_CFUNC
+ * This is used in a declaration of a library private ICU C function.
+ * @stable ICU 2.4
+ */
+
+/**
+ * \def U_CDECL_BEGIN
+ * This is used to begin a declaration of a library private ICU C API.
+ * @stable ICU 2.4
+ */
+
+/**
+ * \def U_CDECL_END
+ * This is used to end a declaration of a library private ICU C API
+ * @stable ICU 2.4
+ */
+
+#ifdef __cplusplus
+#   define U_CFUNC extern "C"
+#   define U_CDECL_BEGIN extern "C" {
+#   define U_CDECL_END   }
+#else
+#   define U_CFUNC extern
+#   define U_CDECL_BEGIN
+#   define U_CDECL_END
+#endif
+
+#ifndef U_ATTRIBUTE_DEPRECATED
+/**
+ * \def U_ATTRIBUTE_DEPRECATED
+ *  This is used for GCC specific attributes
+ * @internal
+ */
+#if U_GCC_MAJOR_MINOR >= 302
+#    define U_ATTRIBUTE_DEPRECATED __attribute__ ((deprecated))
+/**
+ * \def U_ATTRIBUTE_DEPRECATED
+ * This is used for Visual C++ specific attributes
+ * @internal
+ */
+#elif defined(_MSC_VER) && (_MSC_VER >= 1400)
+#    define U_ATTRIBUTE_DEPRECATED __declspec(deprecated)
+#else
+#    define U_ATTRIBUTE_DEPRECATED
+#endif
+#endif
+
+/** This is used to declare a function as a public ICU C API @stable ICU 2.0*/
+#define U_CAPI U_CFUNC U_EXPORT
+/** This is used to declare a function as a stable public ICU C API*/
+#define U_STABLE U_CAPI
+/** This is used to declare a function as a draft public ICU C API  */
+#define U_DRAFT  U_CAPI
+/** This is used to declare a function as a deprecated public ICU C API  */
+#define U_DEPRECATED U_CAPI U_ATTRIBUTE_DEPRECATED
+/** This is used to declare a function as an obsolete public ICU C API  */
+#define U_OBSOLETE U_CAPI
+/** This is used to declare a function as an internal ICU C API  */
+#define U_INTERNAL U_CAPI
+
+/**
+ * \def U_OVERRIDE
+ * Defined to the C++11 "override" keyword if available.
+ * Denotes a class or member which is an override of the base class.
+ * May result in an error if it applied to something not an override.
+ * @internal
+ */
+#ifndef U_OVERRIDE
+#define U_OVERRIDE override
+#endif
+
+/**
+ * \def U_FINAL
+ * Defined to the C++11 "final" keyword if available.
+ * Denotes a class or member which may not be overridden in subclasses.
+ * May result in an error if subclasses attempt to override.
+ * @internal
+ */
+#if !defined(U_FINAL) || defined(U_IN_DOXYGEN)
+#define U_FINAL final
+#endif
+
+// Before ICU 65, function-like, multi-statement ICU macros were just defined as
+// series of statements wrapped in { } blocks and the caller could choose to
+// either treat them as if they were actual functions and end the invocation
+// with a trailing ; creating an empty statement after the block or else omit
+// this trailing ; using the knowledge that the macro would expand to { }.
+//
+// But doing so doesn't work well with macros that look like functions and
+// compiler warnings about empty statements (ICU-20601) and ICU 65 therefore
+// switches to the standard solution of wrapping such macros in do { } while.
+//
+// This will however break existing code that depends on being able to invoke
+// these macros without a trailing ; so to be able to remain compatible with
+// such code the wrapper is itself defined as macros so that it's possible to
+// build ICU 65 and later with the old macro behaviour, like this:
+//
+// CPPFLAGS='-DUPRV_BLOCK_MACRO_BEGIN="" -DUPRV_BLOCK_MACRO_END=""'
+// runConfigureICU ...
+
+/**
+ * \def UPRV_BLOCK_MACRO_BEGIN
+ * Defined as the "do" keyword by default.
+ * @internal
+ */
+#ifndef UPRV_BLOCK_MACRO_BEGIN
+#define UPRV_BLOCK_MACRO_BEGIN do
+#endif
+
+/**
+ * \def UPRV_BLOCK_MACRO_END
+ * Defined as "while (FALSE)" by default.
+ * @internal
+ */
+#ifndef UPRV_BLOCK_MACRO_END
+#define UPRV_BLOCK_MACRO_END while (FALSE)
+#endif
+
+/*==========================================================================*/
+/* limits for int32_t etc., like in POSIX inttypes.h                        */
+/*==========================================================================*/
+
+#ifndef INT8_MIN
+/** The smallest value an 8 bit signed integer can hold @stable ICU 2.0 */
+#   define INT8_MIN        ((int8_t)(-128))
+#endif
+#ifndef INT16_MIN
+/** The smallest value a 16 bit signed integer can hold @stable ICU 2.0 */
+#   define INT16_MIN       ((int16_t)(-32767-1))
+#endif
+#ifndef INT32_MIN
+/** The smallest value a 32 bit signed integer can hold @stable ICU 2.0 */
+#   define INT32_MIN       ((int32_t)(-2147483647-1))
+#endif
+
+#ifndef INT8_MAX
+/** The largest value an 8 bit signed integer can hold @stable ICU 2.0 */
+#   define INT8_MAX        ((int8_t)(127))
+#endif
+#ifndef INT16_MAX
+/** The largest value a 16 bit signed integer can hold @stable ICU 2.0 */
+#   define INT16_MAX       ((int16_t)(32767))
+#endif
+#ifndef INT32_MAX
+/** The largest value a 32 bit signed integer can hold @stable ICU 2.0 */
+#   define INT32_MAX       ((int32_t)(2147483647))
+#endif
+
+#ifndef UINT8_MAX
+/** The largest value an 8 bit unsigned integer can hold @stable ICU 2.0 */
+#   define UINT8_MAX       ((uint8_t)(255U))
+#endif
+#ifndef UINT16_MAX
+/** The largest value a 16 bit unsigned integer can hold @stable ICU 2.0 */
+#   define UINT16_MAX      ((uint16_t)(65535U))
+#endif
+#ifndef UINT32_MAX
+/** The largest value a 32 bit unsigned integer can hold @stable ICU 2.0 */
+#   define UINT32_MAX      ((uint32_t)(4294967295U))
+#endif
+
+#if defined(U_INT64_T_UNAVAILABLE)
+# error int64_t is required for decimal format and rule-based number format.
+#else
+# ifndef INT64_C
+/**
+ * Provides a platform independent way to specify a signed 64-bit integer constant.
+ * note: may be wrong for some 64 bit platforms - ensure your compiler provides INT64_C
+ * @stable ICU 2.8
+ */
+#   define INT64_C(c) c ## LL
+# endif
+# ifndef UINT64_C
+/**
+ * Provides a platform independent way to specify an unsigned 64-bit integer constant.
+ * note: may be wrong for some 64 bit platforms - ensure your compiler provides UINT64_C
+ * @stable ICU 2.8
+ */
+#   define UINT64_C(c) c ## ULL
+# endif
+# ifndef U_INT64_MIN
+/** The smallest value a 64 bit signed integer can hold @stable ICU 2.8 */
+#     define U_INT64_MIN       ((int64_t)(INT64_C(-9223372036854775807)-1))
+# endif
+# ifndef U_INT64_MAX
+/** The largest value a 64 bit signed integer can hold @stable ICU 2.8 */
+#     define U_INT64_MAX       ((int64_t)(INT64_C(9223372036854775807)))
+# endif
+# ifndef U_UINT64_MAX
+/** The largest value a 64 bit unsigned integer can hold @stable ICU 2.8 */
+#     define U_UINT64_MAX      ((uint64_t)(UINT64_C(18446744073709551615)))
+# endif
+#endif
+
+/*==========================================================================*/
+/* Boolean data type                                                        */
+/*==========================================================================*/
+
+/** The ICU boolean type @stable ICU 2.0 */
+typedef int8_t UBool;
+
+#ifndef TRUE
+/** The TRUE value of a UBool @stable ICU 2.0 */
+#   define TRUE  1
+#endif
+#ifndef FALSE
+/** The FALSE value of a UBool @stable ICU 2.0 */
+#   define FALSE 0
+#endif
+
+
+/*==========================================================================*/
+/* Unicode data types                                                       */
+/*==========================================================================*/
+
+/* wchar_t-related definitions -------------------------------------------- */
+
+/*
+ * \def U_WCHAR_IS_UTF16
+ * Defined if wchar_t uses UTF-16.
+ *
+ * @stable ICU 2.0
+ */
+/*
+ * \def U_WCHAR_IS_UTF32
+ * Defined if wchar_t uses UTF-32.
+ *
+ * @stable ICU 2.0
+ */
+#if !defined(U_WCHAR_IS_UTF16) && !defined(U_WCHAR_IS_UTF32)
+#   ifdef __STDC_ISO_10646__
+#       if (U_SIZEOF_WCHAR_T==2)
+#           define U_WCHAR_IS_UTF16
+#       elif (U_SIZEOF_WCHAR_T==4)
+#           define  U_WCHAR_IS_UTF32
+#       endif
+#   elif defined __UCS2__
+#       if (U_PF_OS390 <= U_PLATFORM && U_PLATFORM <= U_PF_OS400) && (U_SIZEOF_WCHAR_T==2)
+#           define U_WCHAR_IS_UTF16
+#       endif
+#   elif defined(__UCS4__) || (U_PLATFORM == U_PF_OS400 && defined(__UTF32__))
+#       if (U_SIZEOF_WCHAR_T==4)
+#           define U_WCHAR_IS_UTF32
+#       endif
+#   elif U_PLATFORM_IS_DARWIN_BASED || (U_SIZEOF_WCHAR_T==4 && U_PLATFORM_IS_LINUX_BASED)
+#       define U_WCHAR_IS_UTF32
+#   elif U_PLATFORM_HAS_WIN32_API
+#       define U_WCHAR_IS_UTF16
+#   endif
+#endif
+
+/* UChar and UChar32 definitions -------------------------------------------- */
+
+/** Number of bytes in a UChar. @stable ICU 2.0 */
+#define U_SIZEOF_UCHAR 2
+
+/**
+ * \def U_CHAR16_IS_TYPEDEF
+ * If 1, then char16_t is a typedef and not a real type (yet)
+ * @internal
+ */
+#if (U_PLATFORM == U_PF_AIX) && defined(__cplusplus) &&(U_CPLUSPLUS_VERSION < 11)
+// for AIX, uchar.h needs to be included
+# include <uchar.h>
+# define U_CHAR16_IS_TYPEDEF 1
+#elif defined(_MSC_VER) && (_MSC_VER < 1900)
+// Versions of Visual Studio/MSVC below 2015 do not support char16_t as a real type,
+// and instead use a typedef.  https://msdn.microsoft.com/library/bb531344.aspx
+# define U_CHAR16_IS_TYPEDEF 1
+#else
+# define U_CHAR16_IS_TYPEDEF 0
+#endif
+
+
+/**
+ * \var UChar
+ *
+ * The base type for UTF-16 code units and pointers.
+ * Unsigned 16-bit integer.
+ * Starting with ICU 59, C++ API uses char16_t directly, while C API continues to use UChar.
+ *
+ * UChar is configurable by defining the macro UCHAR_TYPE
+ * on the preprocessor or compiler command line:
+ * -DUCHAR_TYPE=uint16_t or -DUCHAR_TYPE=wchar_t (if U_SIZEOF_WCHAR_T==2) etc.
+ * (The UCHAR_TYPE can also be \#defined earlier in this file, for outside the ICU library code.)
+ * This is for transitional use from application code that uses uint16_t or wchar_t for UTF-16.
+ *
+ * The default is UChar=char16_t.
+ *
+ * C++11 defines char16_t as bit-compatible with uint16_t, but as a distinct type.
+ *
+ * In C, char16_t is a simple typedef of uint_least16_t.
+ * ICU requires uint_least16_t=uint16_t for data memory mapping.
+ * On macOS, char16_t is not available because the uchar.h standard header is missing.
+ *
+ * @stable ICU 4.4
+ */
+
+#if 1
+    // #if 1 is normal. UChar defaults to char16_t in C++.
+    // For configuration testing of UChar=uint16_t temporarily change this to #if 0.
+    // The intltest Makefile #defines UCHAR_TYPE=char16_t,
+    // so we only #define it to uint16_t if it is undefined so far.
+#elif !defined(UCHAR_TYPE)
+#   define UCHAR_TYPE uint16_t
+#endif
+
+#if defined(U_COMBINED_IMPLEMENTATION) || defined(U_COMMON_IMPLEMENTATION) || \
+        defined(U_I18N_IMPLEMENTATION) || defined(U_IO_IMPLEMENTATION)
+    // Inside the ICU library code, never configurable.
+    typedef char16_t UChar;
+#elif defined(UCHAR_TYPE)
+    typedef UCHAR_TYPE UChar;
+#elif defined(__cplusplus)
+    typedef char16_t UChar;
+#else
+    typedef uint16_t UChar;
+#endif
+
+/**
+ * \var OldUChar
+ * Default ICU 58 definition of UChar.
+ * A base type for UTF-16 code units and pointers.
+ * Unsigned 16-bit integer.
+ *
+ * Define OldUChar to be wchar_t if that is 16 bits wide.
+ * If wchar_t is not 16 bits wide, then define UChar to be uint16_t.
+ *
+ * This makes the definition of OldUChar platform-dependent
+ * but allows direct string type compatibility with platforms with
+ * 16-bit wchar_t types.
+ *
+ * This is how UChar was defined in ICU 58, for transition convenience.
+ * Exception: ICU 58 UChar was defined to UCHAR_TYPE if that macro was defined.
+ * The current UChar responds to UCHAR_TYPE but OldUChar does not.
+ *
+ * @stable ICU 59
+ */
+#if U_SIZEOF_WCHAR_T==2
+    typedef wchar_t OldUChar;
+#elif defined(__CHAR16_TYPE__)
+    typedef __CHAR16_TYPE__ OldUChar;
+#else
+    typedef uint16_t OldUChar;
+#endif
+
+/**
+ * Define UChar32 as a type for single Unicode code points.
+ * UChar32 is a signed 32-bit integer (same as int32_t).
+ *
+ * The Unicode code point range is 0..0x10ffff.
+ * All other values (negative or >=0x110000) are illegal as Unicode code points.
+ * They may be used as sentinel values to indicate "done", "error"
+ * or similar non-code point conditions.
+ *
+ * Before ICU 2.4 (Jitterbug 2146), UChar32 was defined
+ * to be wchar_t if that is 32 bits wide (wchar_t may be signed or unsigned)
+ * or else to be uint32_t.
+ * That is, the definition of UChar32 was platform-dependent.
+ *
+ * @see U_SENTINEL
+ * @stable ICU 2.4
+ */
+typedef int32_t UChar32;
+
+/**
+ * This value is intended for sentinel values for APIs that
+ * (take or) return single code points (UChar32).
+ * It is outside of the Unicode code point range 0..0x10ffff.
+ *
+ * For example, a "done" or "error" value in a new API
+ * could be indicated with U_SENTINEL.
+ *
+ * ICU APIs designed before ICU 2.4 usually define service-specific "done"
+ * values, mostly 0xffff.
+ * Those may need to be distinguished from
+ * actual U+ffff text contents by calling functions like
+ * CharacterIterator::hasNext() or UnicodeString::length().
+ *
+ * @return -1
+ * @see UChar32
+ * @stable ICU 2.4
+ */
+#define U_SENTINEL (-1)
+
+#include "unicode/urename.h"
+
+#endif
diff --git a/vendor/tree-sitter/lib/src/unicode/urename.h b/vendor/tree-sitter/lib/src/unicode/urename.h
new file mode 100644
--- /dev/null
+++ b/vendor/tree-sitter/lib/src/unicode/urename.h
@@ -0,0 +1,1 @@
+// This file must exist in order for `utf8.h` and `utf16.h` to be used.
diff --git a/vendor/tree-sitter/lib/src/unicode/utf.h b/vendor/tree-sitter/lib/src/unicode/utf.h
new file mode 100644
--- /dev/null
+++ b/vendor/tree-sitter/lib/src/unicode/utf.h
@@ -0,0 +1,1 @@
+// This file must exist in order for `utf8.h` and `utf16.h` to be used.
diff --git a/vendor/tree-sitter/lib/src/unicode/utf16.h b/vendor/tree-sitter/lib/src/unicode/utf16.h
new file mode 100644
--- /dev/null
+++ b/vendor/tree-sitter/lib/src/unicode/utf16.h
@@ -0,0 +1,733 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
+/*
+*******************************************************************************
+*
+*   Copyright (C) 1999-2012, International Business Machines
+*   Corporation and others.  All Rights Reserved.
+*
+*******************************************************************************
+*   file name:  utf16.h
+*   encoding:   UTF-8
+*   tab size:   8 (not used)
+*   indentation:4
+*
+*   created on: 1999sep09
+*   created by: Markus W. Scherer
+*/
+
+/**
+ * \file
+ * \brief C API: 16-bit Unicode handling macros
+ * 
+ * This file defines macros to deal with 16-bit Unicode (UTF-16) code units and strings.
+ *
+ * For more information see utf.h and the ICU User Guide Strings chapter
+ * (http://userguide.icu-project.org/strings).
+ *
+ * <em>Usage:</em>
+ * ICU coding guidelines for if() statements should be followed when using these macros.
+ * Compound statements (curly braces {}) must be used  for if-else-while... 
+ * bodies and all macro statements should be terminated with semicolon.
+ */
+
+#ifndef __UTF16_H__
+#define __UTF16_H__
+
+#include "unicode/umachine.h"
+#ifndef __UTF_H__
+#   include "unicode/utf.h"
+#endif
+
+/* single-code point definitions -------------------------------------------- */
+
+/**
+ * Does this code unit alone encode a code point (BMP, not a surrogate)?
+ * @param c 16-bit code unit
+ * @return TRUE or FALSE
+ * @stable ICU 2.4
+ */
+#define U16_IS_SINGLE(c) !U_IS_SURROGATE(c)
+
+/**
+ * Is this code unit a lead surrogate (U+d800..U+dbff)?
+ * @param c 16-bit code unit
+ * @return TRUE or FALSE
+ * @stable ICU 2.4
+ */
+#define U16_IS_LEAD(c) (((c)&0xfffffc00)==0xd800)
+
+/**
+ * Is this code unit a trail surrogate (U+dc00..U+dfff)?
+ * @param c 16-bit code unit
+ * @return TRUE or FALSE
+ * @stable ICU 2.4
+ */
+#define U16_IS_TRAIL(c) (((c)&0xfffffc00)==0xdc00)
+
+/**
+ * Is this code unit a surrogate (U+d800..U+dfff)?
+ * @param c 16-bit code unit
+ * @return TRUE or FALSE
+ * @stable ICU 2.4
+ */
+#define U16_IS_SURROGATE(c) U_IS_SURROGATE(c)
+
+/**
+ * Assuming c is a surrogate code point (U16_IS_SURROGATE(c)),
+ * is it a lead surrogate?
+ * @param c 16-bit code unit
+ * @return TRUE or FALSE
+ * @stable ICU 2.4
+ */
+#define U16_IS_SURROGATE_LEAD(c) (((c)&0x400)==0)
+
+/**
+ * Assuming c is a surrogate code point (U16_IS_SURROGATE(c)),
+ * is it a trail surrogate?
+ * @param c 16-bit code unit
+ * @return TRUE or FALSE
+ * @stable ICU 4.2
+ */
+#define U16_IS_SURROGATE_TRAIL(c) (((c)&0x400)!=0)
+
+/**
+ * Helper constant for U16_GET_SUPPLEMENTARY.
+ * @internal
+ */
+#define U16_SURROGATE_OFFSET ((0xd800<<10UL)+0xdc00-0x10000)
+
+/**
+ * Get a supplementary code point value (U+10000..U+10ffff)
+ * from its lead and trail surrogates.
+ * The result is undefined if the input values are not
+ * lead and trail surrogates.
+ *
+ * @param lead lead surrogate (U+d800..U+dbff)
+ * @param trail trail surrogate (U+dc00..U+dfff)
+ * @return supplementary code point (U+10000..U+10ffff)
+ * @stable ICU 2.4
+ */
+#define U16_GET_SUPPLEMENTARY(lead, trail) \
+    (((UChar32)(lead)<<10UL)+(UChar32)(trail)-U16_SURROGATE_OFFSET)
+
+
+/**
+ * Get the lead surrogate (0xd800..0xdbff) for a
+ * supplementary code point (0x10000..0x10ffff).
+ * @param supplementary 32-bit code point (U+10000..U+10ffff)
+ * @return lead surrogate (U+d800..U+dbff) for supplementary
+ * @stable ICU 2.4
+ */
+#define U16_LEAD(supplementary) (UChar)(((supplementary)>>10)+0xd7c0)
+
+/**
+ * Get the trail surrogate (0xdc00..0xdfff) for a
+ * supplementary code point (0x10000..0x10ffff).
+ * @param supplementary 32-bit code point (U+10000..U+10ffff)
+ * @return trail surrogate (U+dc00..U+dfff) for supplementary
+ * @stable ICU 2.4
+ */
+#define U16_TRAIL(supplementary) (UChar)(((supplementary)&0x3ff)|0xdc00)
+
+/**
+ * How many 16-bit code units are used to encode this Unicode code point? (1 or 2)
+ * The result is not defined if c is not a Unicode code point (U+0000..U+10ffff).
+ * @param c 32-bit code point
+ * @return 1 or 2
+ * @stable ICU 2.4
+ */
+#define U16_LENGTH(c) ((uint32_t)(c)<=0xffff ? 1 : 2)
+
+/**
+ * The maximum number of 16-bit code units per Unicode code point (U+0000..U+10ffff).
+ * @return 2
+ * @stable ICU 2.4
+ */
+#define U16_MAX_LENGTH 2
+
+/**
+ * Get a code point from a string at a random-access offset,
+ * without changing the offset.
+ * "Unsafe" macro, assumes well-formed UTF-16.
+ *
+ * The offset may point to either the lead or trail surrogate unit
+ * for a supplementary code point, in which case the macro will read
+ * the adjacent matching surrogate as well.
+ * The result is undefined if the offset points to a single, unpaired surrogate.
+ * Iteration through a string is more efficient with U16_NEXT_UNSAFE or U16_NEXT.
+ *
+ * @param s const UChar * string
+ * @param i string offset
+ * @param c output UChar32 variable
+ * @see U16_GET
+ * @stable ICU 2.4
+ */
+#define U16_GET_UNSAFE(s, i, c) UPRV_BLOCK_MACRO_BEGIN { \
+    (c)=(s)[i]; \
+    if(U16_IS_SURROGATE(c)) { \
+        if(U16_IS_SURROGATE_LEAD(c)) { \
+            (c)=U16_GET_SUPPLEMENTARY((c), (s)[(i)+1]); \
+        } else { \
+            (c)=U16_GET_SUPPLEMENTARY((s)[(i)-1], (c)); \
+        } \
+    } \
+} UPRV_BLOCK_MACRO_END
+
+/**
+ * Get a code point from a string at a random-access offset,
+ * without changing the offset.
+ * "Safe" macro, handles unpaired surrogates and checks for string boundaries.
+ *
+ * The offset may point to either the lead or trail surrogate unit
+ * for a supplementary code point, in which case the macro will read
+ * the adjacent matching surrogate as well.
+ *
+ * The length can be negative for a NUL-terminated string.
+ *
+ * If the offset points to a single, unpaired surrogate, then
+ * c is set to that unpaired surrogate.
+ * Iteration through a string is more efficient with U16_NEXT_UNSAFE or U16_NEXT.
+ *
+ * @param s const UChar * string
+ * @param start starting string offset (usually 0)
+ * @param i string offset, must be start<=i<length
+ * @param length string length
+ * @param c output UChar32 variable
+ * @see U16_GET_UNSAFE
+ * @stable ICU 2.4
+ */
+#define U16_GET(s, start, i, length, c) UPRV_BLOCK_MACRO_BEGIN { \
+    (c)=(s)[i]; \
+    if(U16_IS_SURROGATE(c)) { \
+        uint16_t __c2; \
+        if(U16_IS_SURROGATE_LEAD(c)) { \
+            if((i)+1!=(length) && U16_IS_TRAIL(__c2=(s)[(i)+1])) { \
+                (c)=U16_GET_SUPPLEMENTARY((c), __c2); \
+            } \
+        } else { \
+            if((i)>(start) && U16_IS_LEAD(__c2=(s)[(i)-1])) { \
+                (c)=U16_GET_SUPPLEMENTARY(__c2, (c)); \
+            } \
+        } \
+    } \
+} UPRV_BLOCK_MACRO_END
+
+/**
+ * Get a code point from a string at a random-access offset,
+ * without changing the offset.
+ * "Safe" macro, handles unpaired surrogates and checks for string boundaries.
+ *
+ * The offset may point to either the lead or trail surrogate unit
+ * for a supplementary code point, in which case the macro will read
+ * the adjacent matching surrogate as well.
+ *
+ * The length can be negative for a NUL-terminated string.
+ *
+ * If the offset points to a single, unpaired surrogate, then
+ * c is set to U+FFFD.
+ * Iteration through a string is more efficient with U16_NEXT_UNSAFE or U16_NEXT_OR_FFFD.
+ *
+ * @param s const UChar * string
+ * @param start starting string offset (usually 0)
+ * @param i string offset, must be start<=i<length
+ * @param length string length
+ * @param c output UChar32 variable
+ * @see U16_GET_UNSAFE
+ * @stable ICU 60
+ */
+#define U16_GET_OR_FFFD(s, start, i, length, c) UPRV_BLOCK_MACRO_BEGIN { \
+    (c)=(s)[i]; \
+    if(U16_IS_SURROGATE(c)) { \
+        uint16_t __c2; \
+        if(U16_IS_SURROGATE_LEAD(c)) { \
+            if((i)+1!=(length) && U16_IS_TRAIL(__c2=(s)[(i)+1])) { \
+                (c)=U16_GET_SUPPLEMENTARY((c), __c2); \
+            } else { \
+                (c)=0xfffd; \
+            } \
+        } else { \
+            if((i)>(start) && U16_IS_LEAD(__c2=(s)[(i)-1])) { \
+                (c)=U16_GET_SUPPLEMENTARY(__c2, (c)); \
+            } else { \
+                (c)=0xfffd; \
+            } \
+        } \
+    } \
+} UPRV_BLOCK_MACRO_END
+
+/* definitions with forward iteration --------------------------------------- */
+
+/**
+ * Get a code point from a string at a code point boundary offset,
+ * and advance the offset to the next code point boundary.
+ * (Post-incrementing forward iteration.)
+ * "Unsafe" macro, assumes well-formed UTF-16.
+ *
+ * The offset may point to the lead surrogate unit
+ * for a supplementary code point, in which case the macro will read
+ * the following trail surrogate as well.
+ * If the offset points to a trail surrogate, then that itself
+ * will be returned as the code point.
+ * The result is undefined if the offset points to a single, unpaired lead surrogate.
+ *
+ * @param s const UChar * string
+ * @param i string offset
+ * @param c output UChar32 variable
+ * @see U16_NEXT
+ * @stable ICU 2.4
+ */
+#define U16_NEXT_UNSAFE(s, i, c) UPRV_BLOCK_MACRO_BEGIN { \
+    (c)=(s)[(i)++]; \
+    if(U16_IS_LEAD(c)) { \
+        (c)=U16_GET_SUPPLEMENTARY((c), (s)[(i)++]); \
+    } \
+} UPRV_BLOCK_MACRO_END
+
+/**
+ * Get a code point from a string at a code point boundary offset,
+ * and advance the offset to the next code point boundary.
+ * (Post-incrementing forward iteration.)
+ * "Safe" macro, handles unpaired surrogates and checks for string boundaries.
+ *
+ * The length can be negative for a NUL-terminated string.
+ *
+ * The offset may point to the lead surrogate unit
+ * for a supplementary code point, in which case the macro will read
+ * the following trail surrogate as well.
+ * If the offset points to a trail surrogate or
+ * to a single, unpaired lead surrogate, then c is set to that unpaired surrogate.
+ *
+ * @param s const UChar * string
+ * @param i string offset, must be i<length
+ * @param length string length
+ * @param c output UChar32 variable
+ * @see U16_NEXT_UNSAFE
+ * @stable ICU 2.4
+ */
+#define U16_NEXT(s, i, length, c) UPRV_BLOCK_MACRO_BEGIN { \
+    (c)=(s)[(i)++]; \
+    if(U16_IS_LEAD(c)) { \
+        uint16_t __c2; \
+        if((i)!=(length) && U16_IS_TRAIL(__c2=(s)[(i)])) { \
+            ++(i); \
+            (c)=U16_GET_SUPPLEMENTARY((c), __c2); \
+        } \
+    } \
+} UPRV_BLOCK_MACRO_END
+
+/**
+ * Get a code point from a string at a code point boundary offset,
+ * and advance the offset to the next code point boundary.
+ * (Post-incrementing forward iteration.)
+ * "Safe" macro, handles unpaired surrogates and checks for string boundaries.
+ *
+ * The length can be negative for a NUL-terminated string.
+ *
+ * The offset may point to the lead surrogate unit
+ * for a supplementary code point, in which case the macro will read
+ * the following trail surrogate as well.
+ * If the offset points to a trail surrogate or
+ * to a single, unpaired lead surrogate, then c is set to U+FFFD.
+ *
+ * @param s const UChar * string
+ * @param i string offset, must be i<length
+ * @param length string length
+ * @param c output UChar32 variable
+ * @see U16_NEXT_UNSAFE
+ * @stable ICU 60
+ */
+#define U16_NEXT_OR_FFFD(s, i, length, c) UPRV_BLOCK_MACRO_BEGIN { \
+    (c)=(s)[(i)++]; \
+    if(U16_IS_SURROGATE(c)) { \
+        uint16_t __c2; \
+        if(U16_IS_SURROGATE_LEAD(c) && (i)!=(length) && U16_IS_TRAIL(__c2=(s)[(i)])) { \
+            ++(i); \
+            (c)=U16_GET_SUPPLEMENTARY((c), __c2); \
+        } else { \
+            (c)=0xfffd; \
+        } \
+    } \
+} UPRV_BLOCK_MACRO_END
+
+/**
+ * Append a code point to a string, overwriting 1 or 2 code units.
+ * The offset points to the current end of the string contents
+ * and is advanced (post-increment).
+ * "Unsafe" macro, assumes a valid code point and sufficient space in the string.
+ * Otherwise, the result is undefined.
+ *
+ * @param s const UChar * string buffer
+ * @param i string offset
+ * @param c code point to append
+ * @see U16_APPEND
+ * @stable ICU 2.4
+ */
+#define U16_APPEND_UNSAFE(s, i, c) UPRV_BLOCK_MACRO_BEGIN { \
+    if((uint32_t)(c)<=0xffff) { \
+        (s)[(i)++]=(uint16_t)(c); \
+    } else { \
+        (s)[(i)++]=(uint16_t)(((c)>>10)+0xd7c0); \
+        (s)[(i)++]=(uint16_t)(((c)&0x3ff)|0xdc00); \
+    } \
+} UPRV_BLOCK_MACRO_END
+
+/**
+ * Append a code point to a string, overwriting 1 or 2 code units.
+ * The offset points to the current end of the string contents
+ * and is advanced (post-increment).
+ * "Safe" macro, checks for a valid code point.
+ * If a surrogate pair is written, checks for sufficient space in the string.
+ * If the code point is not valid or a trail surrogate does not fit,
+ * then isError is set to TRUE.
+ *
+ * @param s const UChar * string buffer
+ * @param i string offset, must be i<capacity
+ * @param capacity size of the string buffer
+ * @param c code point to append
+ * @param isError output UBool set to TRUE if an error occurs, otherwise not modified
+ * @see U16_APPEND_UNSAFE
+ * @stable ICU 2.4
+ */
+#define U16_APPEND(s, i, capacity, c, isError) UPRV_BLOCK_MACRO_BEGIN { \
+    if((uint32_t)(c)<=0xffff) { \
+        (s)[(i)++]=(uint16_t)(c); \
+    } else if((uint32_t)(c)<=0x10ffff && (i)+1<(capacity)) { \
+        (s)[(i)++]=(uint16_t)(((c)>>10)+0xd7c0); \
+        (s)[(i)++]=(uint16_t)(((c)&0x3ff)|0xdc00); \
+    } else /* c>0x10ffff or not enough space */ { \
+        (isError)=TRUE; \
+    } \
+} UPRV_BLOCK_MACRO_END
+
+/**
+ * Advance the string offset from one code point boundary to the next.
+ * (Post-incrementing iteration.)
+ * "Unsafe" macro, assumes well-formed UTF-16.
+ *
+ * @param s const UChar * string
+ * @param i string offset
+ * @see U16_FWD_1
+ * @stable ICU 2.4
+ */
+#define U16_FWD_1_UNSAFE(s, i) UPRV_BLOCK_MACRO_BEGIN { \
+    if(U16_IS_LEAD((s)[(i)++])) { \
+        ++(i); \
+    } \
+} UPRV_BLOCK_MACRO_END
+
+/**
+ * Advance the string offset from one code point boundary to the next.
+ * (Post-incrementing iteration.)
+ * "Safe" macro, handles unpaired surrogates and checks for string boundaries.
+ *
+ * The length can be negative for a NUL-terminated string.
+ *
+ * @param s const UChar * string
+ * @param i string offset, must be i<length
+ * @param length string length
+ * @see U16_FWD_1_UNSAFE
+ * @stable ICU 2.4
+ */
+#define U16_FWD_1(s, i, length) UPRV_BLOCK_MACRO_BEGIN { \
+    if(U16_IS_LEAD((s)[(i)++]) && (i)!=(length) && U16_IS_TRAIL((s)[i])) { \
+        ++(i); \
+    } \
+} UPRV_BLOCK_MACRO_END
+
+/**
+ * Advance the string offset from one code point boundary to the n-th next one,
+ * i.e., move forward by n code points.
+ * (Post-incrementing iteration.)
+ * "Unsafe" macro, assumes well-formed UTF-16.
+ *
+ * @param s const UChar * string
+ * @param i string offset
+ * @param n number of code points to skip
+ * @see U16_FWD_N
+ * @stable ICU 2.4
+ */
+#define U16_FWD_N_UNSAFE(s, i, n) UPRV_BLOCK_MACRO_BEGIN { \
+    int32_t __N=(n); \
+    while(__N>0) { \
+        U16_FWD_1_UNSAFE(s, i); \
+        --__N; \
+    } \
+} UPRV_BLOCK_MACRO_END
+
+/**
+ * Advance the string offset from one code point boundary to the n-th next one,
+ * i.e., move forward by n code points.
+ * (Post-incrementing iteration.)
+ * "Safe" macro, handles unpaired surrogates and checks for string boundaries.
+ *
+ * The length can be negative for a NUL-terminated string.
+ *
+ * @param s const UChar * string
+ * @param i int32_t string offset, must be i<length
+ * @param length int32_t string length
+ * @param n number of code points to skip
+ * @see U16_FWD_N_UNSAFE
+ * @stable ICU 2.4
+ */
+#define U16_FWD_N(s, i, length, n) UPRV_BLOCK_MACRO_BEGIN { \
+    int32_t __N=(n); \
+    while(__N>0 && ((i)<(length) || ((length)<0 && (s)[i]!=0))) { \
+        U16_FWD_1(s, i, length); \
+        --__N; \
+    } \
+} UPRV_BLOCK_MACRO_END
+
+/**
+ * Adjust a random-access offset to a code point boundary
+ * at the start of a code point.
+ * If the offset points to the trail surrogate of a surrogate pair,
+ * then the offset is decremented.
+ * Otherwise, it is not modified.
+ * "Unsafe" macro, assumes well-formed UTF-16.
+ *
+ * @param s const UChar * string
+ * @param i string offset
+ * @see U16_SET_CP_START
+ * @stable ICU 2.4
+ */
+#define U16_SET_CP_START_UNSAFE(s, i) UPRV_BLOCK_MACRO_BEGIN { \
+    if(U16_IS_TRAIL((s)[i])) { \
+        --(i); \
+    } \
+} UPRV_BLOCK_MACRO_END
+
+/**
+ * Adjust a random-access offset to a code point boundary
+ * at the start of a code point.
+ * If the offset points to the trail surrogate of a surrogate pair,
+ * then the offset is decremented.
+ * Otherwise, it is not modified.
+ * "Safe" macro, handles unpaired surrogates and checks for string boundaries.
+ *
+ * @param s const UChar * string
+ * @param start starting string offset (usually 0)
+ * @param i string offset, must be start<=i
+ * @see U16_SET_CP_START_UNSAFE
+ * @stable ICU 2.4
+ */
+#define U16_SET_CP_START(s, start, i) UPRV_BLOCK_MACRO_BEGIN { \
+    if(U16_IS_TRAIL((s)[i]) && (i)>(start) && U16_IS_LEAD((s)[(i)-1])) { \
+        --(i); \
+    } \
+} UPRV_BLOCK_MACRO_END
+
+/* definitions with backward iteration -------------------------------------- */
+
+/**
+ * Move the string offset from one code point boundary to the previous one
+ * and get the code point between them.
+ * (Pre-decrementing backward iteration.)
+ * "Unsafe" macro, assumes well-formed UTF-16.
+ *
+ * The input offset may be the same as the string length.
+ * If the offset is behind a trail surrogate unit
+ * for a supplementary code point, then the macro will read
+ * the preceding lead surrogate as well.
+ * If the offset is behind a lead surrogate, then that itself
+ * will be returned as the code point.
+ * The result is undefined if the offset is behind a single, unpaired trail surrogate.
+ *
+ * @param s const UChar * string
+ * @param i string offset
+ * @param c output UChar32 variable
+ * @see U16_PREV
+ * @stable ICU 2.4
+ */
+#define U16_PREV_UNSAFE(s, i, c) UPRV_BLOCK_MACRO_BEGIN { \
+    (c)=(s)[--(i)]; \
+    if(U16_IS_TRAIL(c)) { \
+        (c)=U16_GET_SUPPLEMENTARY((s)[--(i)], (c)); \
+    } \
+} UPRV_BLOCK_MACRO_END
+
+/**
+ * Move the string offset from one code point boundary to the previous one
+ * and get the code point between them.
+ * (Pre-decrementing backward iteration.)
+ * "Safe" macro, handles unpaired surrogates and checks for string boundaries.
+ *
+ * The input offset may be the same as the string length.
+ * If the offset is behind a trail surrogate unit
+ * for a supplementary code point, then the macro will read
+ * the preceding lead surrogate as well.
+ * If the offset is behind a lead surrogate or behind a single, unpaired
+ * trail surrogate, then c is set to that unpaired surrogate.
+ *
+ * @param s const UChar * string
+ * @param start starting string offset (usually 0)
+ * @param i string offset, must be start<i
+ * @param c output UChar32 variable
+ * @see U16_PREV_UNSAFE
+ * @stable ICU 2.4
+ */
+#define U16_PREV(s, start, i, c) UPRV_BLOCK_MACRO_BEGIN { \
+    (c)=(s)[--(i)]; \
+    if(U16_IS_TRAIL(c)) { \
+        uint16_t __c2; \
+        if((i)>(start) && U16_IS_LEAD(__c2=(s)[(i)-1])) { \
+            --(i); \
+            (c)=U16_GET_SUPPLEMENTARY(__c2, (c)); \
+        } \
+    } \
+} UPRV_BLOCK_MACRO_END
+
+/**
+ * Move the string offset from one code point boundary to the previous one
+ * and get the code point between them.
+ * (Pre-decrementing backward iteration.)
+ * "Safe" macro, handles unpaired surrogates and checks for string boundaries.
+ *
+ * The input offset may be the same as the string length.
+ * If the offset is behind a trail surrogate unit
+ * for a supplementary code point, then the macro will read
+ * the preceding lead surrogate as well.
+ * If the offset is behind a lead surrogate or behind a single, unpaired
+ * trail surrogate, then c is set to U+FFFD.
+ *
+ * @param s const UChar * string
+ * @param start starting string offset (usually 0)
+ * @param i string offset, must be start<i
+ * @param c output UChar32 variable
+ * @see U16_PREV_UNSAFE
+ * @stable ICU 60
+ */
+#define U16_PREV_OR_FFFD(s, start, i, c) UPRV_BLOCK_MACRO_BEGIN { \
+    (c)=(s)[--(i)]; \
+    if(U16_IS_SURROGATE(c)) { \
+        uint16_t __c2; \
+        if(U16_IS_SURROGATE_TRAIL(c) && (i)>(start) && U16_IS_LEAD(__c2=(s)[(i)-1])) { \
+            --(i); \
+            (c)=U16_GET_SUPPLEMENTARY(__c2, (c)); \
+        } else { \
+            (c)=0xfffd; \
+        } \
+    } \
+} UPRV_BLOCK_MACRO_END
+
+/**
+ * Move the string offset from one code point boundary to the previous one.
+ * (Pre-decrementing backward iteration.)
+ * The input offset may be the same as the string length.
+ * "Unsafe" macro, assumes well-formed UTF-16.
+ *
+ * @param s const UChar * string
+ * @param i string offset
+ * @see U16_BACK_1
+ * @stable ICU 2.4
+ */
+#define U16_BACK_1_UNSAFE(s, i) UPRV_BLOCK_MACRO_BEGIN { \
+    if(U16_IS_TRAIL((s)[--(i)])) { \
+        --(i); \
+    } \
+} UPRV_BLOCK_MACRO_END
+
+/**
+ * Move the string offset from one code point boundary to the previous one.
+ * (Pre-decrementing backward iteration.)
+ * The input offset may be the same as the string length.
+ * "Safe" macro, handles unpaired surrogates and checks for string boundaries.
+ *
+ * @param s const UChar * string
+ * @param start starting string offset (usually 0)
+ * @param i string offset, must be start<i
+ * @see U16_BACK_1_UNSAFE
+ * @stable ICU 2.4
+ */
+#define U16_BACK_1(s, start, i) UPRV_BLOCK_MACRO_BEGIN { \
+    if(U16_IS_TRAIL((s)[--(i)]) && (i)>(start) && U16_IS_LEAD((s)[(i)-1])) { \
+        --(i); \
+    } \
+} UPRV_BLOCK_MACRO_END
+
+/**
+ * Move the string offset from one code point boundary to the n-th one before it,
+ * i.e., move backward by n code points.
+ * (Pre-decrementing backward iteration.)
+ * The input offset may be the same as the string length.
+ * "Unsafe" macro, assumes well-formed UTF-16.
+ *
+ * @param s const UChar * string
+ * @param i string offset
+ * @param n number of code points to skip
+ * @see U16_BACK_N
+ * @stable ICU 2.4
+ */
+#define U16_BACK_N_UNSAFE(s, i, n) UPRV_BLOCK_MACRO_BEGIN { \
+    int32_t __N=(n); \
+    while(__N>0) { \
+        U16_BACK_1_UNSAFE(s, i); \
+        --__N; \
+    } \
+} UPRV_BLOCK_MACRO_END
+
+/**
+ * Move the string offset from one code point boundary to the n-th one before it,
+ * i.e., move backward by n code points.
+ * (Pre-decrementing backward iteration.)
+ * The input offset may be the same as the string length.
+ * "Safe" macro, handles unpaired surrogates and checks for string boundaries.
+ *
+ * @param s const UChar * string
+ * @param start start of string
+ * @param i string offset, must be start<i
+ * @param n number of code points to skip
+ * @see U16_BACK_N_UNSAFE
+ * @stable ICU 2.4
+ */
+#define U16_BACK_N(s, start, i, n) UPRV_BLOCK_MACRO_BEGIN { \
+    int32_t __N=(n); \
+    while(__N>0 && (i)>(start)) { \
+        U16_BACK_1(s, start, i); \
+        --__N; \
+    } \
+} UPRV_BLOCK_MACRO_END
+
+/**
+ * Adjust a random-access offset to a code point boundary after a code point.
+ * If the offset is behind the lead surrogate of a surrogate pair,
+ * then the offset is incremented.
+ * Otherwise, it is not modified.
+ * The input offset may be the same as the string length.
+ * "Unsafe" macro, assumes well-formed UTF-16.
+ *
+ * @param s const UChar * string
+ * @param i string offset
+ * @see U16_SET_CP_LIMIT
+ * @stable ICU 2.4
+ */
+#define U16_SET_CP_LIMIT_UNSAFE(s, i) UPRV_BLOCK_MACRO_BEGIN { \
+    if(U16_IS_LEAD((s)[(i)-1])) { \
+        ++(i); \
+    } \
+} UPRV_BLOCK_MACRO_END
+
+/**
+ * Adjust a random-access offset to a code point boundary after a code point.
+ * If the offset is behind the lead surrogate of a surrogate pair,
+ * then the offset is incremented.
+ * Otherwise, it is not modified.
+ * The input offset may be the same as the string length.
+ * "Safe" macro, handles unpaired surrogates and checks for string boundaries.
+ *
+ * The length can be negative for a NUL-terminated string.
+ *
+ * @param s const UChar * string
+ * @param start int32_t starting string offset (usually 0)
+ * @param i int32_t string offset, start<=i<=length
+ * @param length int32_t string length
+ * @see U16_SET_CP_LIMIT_UNSAFE
+ * @stable ICU 2.4
+ */
+#define U16_SET_CP_LIMIT(s, start, i, length) UPRV_BLOCK_MACRO_BEGIN { \
+    if((start)<(i) && ((i)<(length) || (length)<0) && U16_IS_LEAD((s)[(i)-1]) && U16_IS_TRAIL((s)[i])) { \
+        ++(i); \
+    } \
+} UPRV_BLOCK_MACRO_END
+
+#endif
diff --git a/vendor/tree-sitter/lib/src/unicode/utf8.h b/vendor/tree-sitter/lib/src/unicode/utf8.h
new file mode 100644
--- /dev/null
+++ b/vendor/tree-sitter/lib/src/unicode/utf8.h
@@ -0,0 +1,881 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
+/*
+*******************************************************************************
+*
+*   Copyright (C) 1999-2015, International Business Machines
+*   Corporation and others.  All Rights Reserved.
+*
+*******************************************************************************
+*   file name:  utf8.h
+*   encoding:   UTF-8
+*   tab size:   8 (not used)
+*   indentation:4
+*
+*   created on: 1999sep13
+*   created by: Markus W. Scherer
+*/
+
+/**
+ * \file
+ * \brief C API: 8-bit Unicode handling macros
+ *
+ * This file defines macros to deal with 8-bit Unicode (UTF-8) code units (bytes) and strings.
+ *
+ * For more information see utf.h and the ICU User Guide Strings chapter
+ * (http://userguide.icu-project.org/strings).
+ *
+ * <em>Usage:</em>
+ * ICU coding guidelines for if() statements should be followed when using these macros.
+ * Compound statements (curly braces {}) must be used  for if-else-while...
+ * bodies and all macro statements should be terminated with semicolon.
+ */
+
+#ifndef __UTF8_H__
+#define __UTF8_H__
+
+#include "unicode/umachine.h"
+#ifndef __UTF_H__
+#   include "unicode/utf.h"
+#endif
+
+/* internal definitions ----------------------------------------------------- */
+
+/**
+ * Counts the trail bytes for a UTF-8 lead byte.
+ * Returns 0 for 0..0xc1 as well as for 0xf5..0xff.
+ * leadByte might be evaluated multiple times.
+ *
+ * This is internal since it is not meant to be called directly by external clients;
+ * however it is called by public macros in this file and thus must remain stable.
+ *
+ * @param leadByte The first byte of a UTF-8 sequence. Must be 0..0xff.
+ * @internal
+ */
+#define U8_COUNT_TRAIL_BYTES(leadByte) \
+    (U8_IS_LEAD(leadByte) ? \
+        ((uint8_t)(leadByte)>=0xe0)+((uint8_t)(leadByte)>=0xf0)+1 : 0)
+
+/**
+ * Counts the trail bytes for a UTF-8 lead byte of a valid UTF-8 sequence.
+ * Returns 0 for 0..0xc1. Undefined for 0xf5..0xff.
+ * leadByte might be evaluated multiple times.
+ *
+ * This is internal since it is not meant to be called directly by external clients;
+ * however it is called by public macros in this file and thus must remain stable.
+ *
+ * @param leadByte The first byte of a UTF-8 sequence. Must be 0..0xff.
+ * @internal
+ */
+#define U8_COUNT_TRAIL_BYTES_UNSAFE(leadByte) \
+    (((uint8_t)(leadByte)>=0xc2)+((uint8_t)(leadByte)>=0xe0)+((uint8_t)(leadByte)>=0xf0))
+
+/**
+ * Mask a UTF-8 lead byte, leave only the lower bits that form part of the code point value.
+ *
+ * This is internal since it is not meant to be called directly by external clients;
+ * however it is called by public macros in this file and thus must remain stable.
+ * @internal
+ */
+#define U8_MASK_LEAD_BYTE(leadByte, countTrailBytes) ((leadByte)&=(1<<(6-(countTrailBytes)))-1)
+
+/**
+ * Internal bit vector for 3-byte UTF-8 validity check, for use in U8_IS_VALID_LEAD3_AND_T1.
+ * Each bit indicates whether one lead byte + first trail byte pair starts a valid sequence.
+ * Lead byte E0..EF bits 3..0 are used as byte index,
+ * first trail byte bits 7..5 are used as bit index into that byte.
+ * @see U8_IS_VALID_LEAD3_AND_T1
+ * @internal
+ */
+#define U8_LEAD3_T1_BITS "\x20\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x10\x30\x30"
+
+/**
+ * Internal 3-byte UTF-8 validity check.
+ * Non-zero if lead byte E0..EF and first trail byte 00..FF start a valid sequence.
+ * @internal
+ */
+#define U8_IS_VALID_LEAD3_AND_T1(lead, t1) (U8_LEAD3_T1_BITS[(lead)&0xf]&(1<<((uint8_t)(t1)>>5)))
+
+/**
+ * Internal bit vector for 4-byte UTF-8 validity check, for use in U8_IS_VALID_LEAD4_AND_T1.
+ * Each bit indicates whether one lead byte + first trail byte pair starts a valid sequence.
+ * First trail byte bits 7..4 are used as byte index,
+ * lead byte F0..F4 bits 2..0 are used as bit index into that byte.
+ * @see U8_IS_VALID_LEAD4_AND_T1
+ * @internal
+ */
+#define U8_LEAD4_T1_BITS "\x00\x00\x00\x00\x00\x00\x00\x00\x1E\x0F\x0F\x0F\x00\x00\x00\x00"
+
+/**
+ * Internal 4-byte UTF-8 validity check.
+ * Non-zero if lead byte F0..F4 and first trail byte 00..FF start a valid sequence.
+ * @internal
+ */
+#define U8_IS_VALID_LEAD4_AND_T1(lead, t1) (U8_LEAD4_T1_BITS[(uint8_t)(t1)>>4]&(1<<((lead)&7)))
+
+/**
+ * Function for handling "next code point" with error-checking.
+ *
+ * This is internal since it is not meant to be called directly by external clients;
+ * however it is U_STABLE (not U_INTERNAL) since it is called by public macros in this
+ * file and thus must remain stable, and should not be hidden when other internal
+ * functions are hidden (otherwise public macros would fail to compile).
+ * @internal
+ */
+U_STABLE UChar32 U_EXPORT2
+utf8_nextCharSafeBody(const uint8_t *s, int32_t *pi, int32_t length, UChar32 c, UBool strict);
+
+/**
+ * Function for handling "append code point" with error-checking.
+ *
+ * This is internal since it is not meant to be called directly by external clients;
+ * however it is U_STABLE (not U_INTERNAL) since it is called by public macros in this
+ * file and thus must remain stable, and should not be hidden when other internal
+ * functions are hidden (otherwise public macros would fail to compile).
+ * @internal
+ */
+U_STABLE int32_t U_EXPORT2
+utf8_appendCharSafeBody(uint8_t *s, int32_t i, int32_t length, UChar32 c, UBool *pIsError);
+
+/**
+ * Function for handling "previous code point" with error-checking.
+ *
+ * This is internal since it is not meant to be called directly by external clients;
+ * however it is U_STABLE (not U_INTERNAL) since it is called by public macros in this
+ * file and thus must remain stable, and should not be hidden when other internal
+ * functions are hidden (otherwise public macros would fail to compile).
+ * @internal
+ */
+U_STABLE UChar32 U_EXPORT2
+utf8_prevCharSafeBody(const uint8_t *s, int32_t start, int32_t *pi, UChar32 c, UBool strict);
+
+/**
+ * Function for handling "skip backward one code point" with error-checking.
+ *
+ * This is internal since it is not meant to be called directly by external clients;
+ * however it is U_STABLE (not U_INTERNAL) since it is called by public macros in this
+ * file and thus must remain stable, and should not be hidden when other internal
+ * functions are hidden (otherwise public macros would fail to compile).
+ * @internal
+ */
+U_STABLE int32_t U_EXPORT2
+utf8_back1SafeBody(const uint8_t *s, int32_t start, int32_t i);
+
+/* single-code point definitions -------------------------------------------- */
+
+/**
+ * Does this code unit (byte) encode a code point by itself (US-ASCII 0..0x7f)?
+ * @param c 8-bit code unit (byte)
+ * @return TRUE or FALSE
+ * @stable ICU 2.4
+ */
+#define U8_IS_SINGLE(c) (((c)&0x80)==0)
+
+/**
+ * Is this code unit (byte) a UTF-8 lead byte? (0xC2..0xF4)
+ * @param c 8-bit code unit (byte)
+ * @return TRUE or FALSE
+ * @stable ICU 2.4
+ */
+#define U8_IS_LEAD(c) ((uint8_t)((c)-0xc2)<=0x32)
+// 0x32=0xf4-0xc2
+
+/**
+ * Is this code unit (byte) a UTF-8 trail byte? (0x80..0xBF)
+ * @param c 8-bit code unit (byte)
+ * @return TRUE or FALSE
+ * @stable ICU 2.4
+ */
+#define U8_IS_TRAIL(c) ((int8_t)(c)<-0x40)
+
+/**
+ * How many code units (bytes) are used for the UTF-8 encoding
+ * of this Unicode code point?
+ * @param c 32-bit code point
+ * @return 1..4, or 0 if c is a surrogate or not a Unicode code point
+ * @stable ICU 2.4
+ */
+#define U8_LENGTH(c) \
+    ((uint32_t)(c)<=0x7f ? 1 : \
+        ((uint32_t)(c)<=0x7ff ? 2 : \
+            ((uint32_t)(c)<=0xd7ff ? 3 : \
+                ((uint32_t)(c)<=0xdfff || (uint32_t)(c)>0x10ffff ? 0 : \
+                    ((uint32_t)(c)<=0xffff ? 3 : 4)\
+                ) \
+            ) \
+        ) \
+    )
+
+/**
+ * The maximum number of UTF-8 code units (bytes) per Unicode code point (U+0000..U+10ffff).
+ * @return 4
+ * @stable ICU 2.4
+ */
+#define U8_MAX_LENGTH 4
+
+/**
+ * Get a code point from a string at a random-access offset,
+ * without changing the offset.
+ * The offset may point to either the lead byte or one of the trail bytes
+ * for a code point, in which case the macro will read all of the bytes
+ * for the code point.
+ * The result is undefined if the offset points to an illegal UTF-8
+ * byte sequence.
+ * Iteration through a string is more efficient with U8_NEXT_UNSAFE or U8_NEXT.
+ *
+ * @param s const uint8_t * string
+ * @param i string offset
+ * @param c output UChar32 variable
+ * @see U8_GET
+ * @stable ICU 2.4
+ */
+#define U8_GET_UNSAFE(s, i, c) UPRV_BLOCK_MACRO_BEGIN { \
+    int32_t _u8_get_unsafe_index=(int32_t)(i); \
+    U8_SET_CP_START_UNSAFE(s, _u8_get_unsafe_index); \
+    U8_NEXT_UNSAFE(s, _u8_get_unsafe_index, c); \
+} UPRV_BLOCK_MACRO_END
+
+/**
+ * Get a code point from a string at a random-access offset,
+ * without changing the offset.
+ * The offset may point to either the lead byte or one of the trail bytes
+ * for a code point, in which case the macro will read all of the bytes
+ * for the code point.
+ *
+ * The length can be negative for a NUL-terminated string.
+ *
+ * If the offset points to an illegal UTF-8 byte sequence, then
+ * c is set to a negative value.
+ * Iteration through a string is more efficient with U8_NEXT_UNSAFE or U8_NEXT.
+ *
+ * @param s const uint8_t * string
+ * @param start int32_t starting string offset
+ * @param i int32_t string offset, must be start<=i<length
+ * @param length int32_t string length
+ * @param c output UChar32 variable, set to <0 in case of an error
+ * @see U8_GET_UNSAFE
+ * @stable ICU 2.4
+ */
+#define U8_GET(s, start, i, length, c) UPRV_BLOCK_MACRO_BEGIN { \
+    int32_t _u8_get_index=(i); \
+    U8_SET_CP_START(s, start, _u8_get_index); \
+    U8_NEXT(s, _u8_get_index, length, c); \
+} UPRV_BLOCK_MACRO_END
+
+/**
+ * Get a code point from a string at a random-access offset,
+ * without changing the offset.
+ * The offset may point to either the lead byte or one of the trail bytes
+ * for a code point, in which case the macro will read all of the bytes
+ * for the code point.
+ *
+ * The length can be negative for a NUL-terminated string.
+ *
+ * If the offset points to an illegal UTF-8 byte sequence, then
+ * c is set to U+FFFD.
+ * Iteration through a string is more efficient with U8_NEXT_UNSAFE or U8_NEXT_OR_FFFD.
+ *
+ * This macro does not distinguish between a real U+FFFD in the text
+ * and U+FFFD returned for an ill-formed sequence.
+ * Use U8_GET() if that distinction is important.
+ *
+ * @param s const uint8_t * string
+ * @param start int32_t starting string offset
+ * @param i int32_t string offset, must be start<=i<length
+ * @param length int32_t string length
+ * @param c output UChar32 variable, set to U+FFFD in case of an error
+ * @see U8_GET
+ * @stable ICU 51
+ */
+#define U8_GET_OR_FFFD(s, start, i, length, c) UPRV_BLOCK_MACRO_BEGIN { \
+    int32_t _u8_get_index=(i); \
+    U8_SET_CP_START(s, start, _u8_get_index); \
+    U8_NEXT_OR_FFFD(s, _u8_get_index, length, c); \
+} UPRV_BLOCK_MACRO_END
+
+/* definitions with forward iteration --------------------------------------- */
+
+/**
+ * Get a code point from a string at a code point boundary offset,
+ * and advance the offset to the next code point boundary.
+ * (Post-incrementing forward iteration.)
+ * "Unsafe" macro, assumes well-formed UTF-8.
+ *
+ * The offset may point to the lead byte of a multi-byte sequence,
+ * in which case the macro will read the whole sequence.
+ * The result is undefined if the offset points to a trail byte
+ * or an illegal UTF-8 sequence.
+ *
+ * @param s const uint8_t * string
+ * @param i string offset
+ * @param c output UChar32 variable
+ * @see U8_NEXT
+ * @stable ICU 2.4
+ */
+#define U8_NEXT_UNSAFE(s, i, c) UPRV_BLOCK_MACRO_BEGIN { \
+    (c)=(uint8_t)(s)[(i)++]; \
+    if(!U8_IS_SINGLE(c)) { \
+        if((c)<0xe0) { \
+            (c)=(((c)&0x1f)<<6)|((s)[(i)++]&0x3f); \
+        } else if((c)<0xf0) { \
+            /* no need for (c&0xf) because the upper bits are truncated after <<12 in the cast to (UChar) */ \
+            (c)=(UChar)(((c)<<12)|(((s)[i]&0x3f)<<6)|((s)[(i)+1]&0x3f)); \
+            (i)+=2; \
+        } else { \
+            (c)=(((c)&7)<<18)|(((s)[i]&0x3f)<<12)|(((s)[(i)+1]&0x3f)<<6)|((s)[(i)+2]&0x3f); \
+            (i)+=3; \
+        } \
+    } \
+} UPRV_BLOCK_MACRO_END
+
+/**
+ * Get a code point from a string at a code point boundary offset,
+ * and advance the offset to the next code point boundary.
+ * (Post-incrementing forward iteration.)
+ * "Safe" macro, checks for illegal sequences and for string boundaries.
+ *
+ * The length can be negative for a NUL-terminated string.
+ *
+ * The offset may point to the lead byte of a multi-byte sequence,
+ * in which case the macro will read the whole sequence.
+ * If the offset points to a trail byte or an illegal UTF-8 sequence, then
+ * c is set to a negative value.
+ *
+ * @param s const uint8_t * string
+ * @param i int32_t string offset, must be i<length
+ * @param length int32_t string length
+ * @param c output UChar32 variable, set to <0 in case of an error
+ * @see U8_NEXT_UNSAFE
+ * @stable ICU 2.4
+ */
+#define U8_NEXT(s, i, length, c) U8_INTERNAL_NEXT_OR_SUB(s, i, length, c, U_SENTINEL)
+
+/**
+ * Get a code point from a string at a code point boundary offset,
+ * and advance the offset to the next code point boundary.
+ * (Post-incrementing forward iteration.)
+ * "Safe" macro, checks for illegal sequences and for string boundaries.
+ *
+ * The length can be negative for a NUL-terminated string.
+ *
+ * The offset may point to the lead byte of a multi-byte sequence,
+ * in which case the macro will read the whole sequence.
+ * If the offset points to a trail byte or an illegal UTF-8 sequence, then
+ * c is set to U+FFFD.
+ *
+ * This macro does not distinguish between a real U+FFFD in the text
+ * and U+FFFD returned for an ill-formed sequence.
+ * Use U8_NEXT() if that distinction is important.
+ *
+ * @param s const uint8_t * string
+ * @param i int32_t string offset, must be i<length
+ * @param length int32_t string length
+ * @param c output UChar32 variable, set to U+FFFD in case of an error
+ * @see U8_NEXT
+ * @stable ICU 51
+ */
+#define U8_NEXT_OR_FFFD(s, i, length, c) U8_INTERNAL_NEXT_OR_SUB(s, i, length, c, 0xfffd)
+
+/** @internal */
+#define U8_INTERNAL_NEXT_OR_SUB(s, i, length, c, sub) UPRV_BLOCK_MACRO_BEGIN { \
+    (c)=(uint8_t)(s)[(i)++]; \
+    if(!U8_IS_SINGLE(c)) { \
+        uint8_t __t = 0; \
+        if((i)!=(length) && \
+            /* fetch/validate/assemble all but last trail byte */ \
+            ((c)>=0xe0 ? \
+                ((c)<0xf0 ?  /* U+0800..U+FFFF except surrogates */ \
+                    U8_LEAD3_T1_BITS[(c)&=0xf]&(1<<((__t=(s)[i])>>5)) && \
+                    (__t&=0x3f, 1) \
+                :  /* U+10000..U+10FFFF */ \
+                    ((c)-=0xf0)<=4 && \
+                    U8_LEAD4_T1_BITS[(__t=(s)[i])>>4]&(1<<(c)) && \
+                    ((c)=((c)<<6)|(__t&0x3f), ++(i)!=(length)) && \
+                    (__t=(s)[i]-0x80)<=0x3f) && \
+                /* valid second-to-last trail byte */ \
+                ((c)=((c)<<6)|__t, ++(i)!=(length)) \
+            :  /* U+0080..U+07FF */ \
+                (c)>=0xc2 && ((c)&=0x1f, 1)) && \
+            /* last trail byte */ \
+            (__t=(s)[i]-0x80)<=0x3f && \
+            ((c)=((c)<<6)|__t, ++(i), 1)) { \
+        } else { \
+            (c)=(sub);  /* ill-formed*/ \
+        } \
+    } \
+} UPRV_BLOCK_MACRO_END
+
+/**
+ * Append a code point to a string, overwriting 1 to 4 bytes.
+ * The offset points to the current end of the string contents
+ * and is advanced (post-increment).
+ * "Unsafe" macro, assumes a valid code point and sufficient space in the string.
+ * Otherwise, the result is undefined.
+ *
+ * @param s const uint8_t * string buffer
+ * @param i string offset
+ * @param c code point to append
+ * @see U8_APPEND
+ * @stable ICU 2.4
+ */
+#define U8_APPEND_UNSAFE(s, i, c) UPRV_BLOCK_MACRO_BEGIN { \
+    uint32_t __uc=(c); \
+    if(__uc<=0x7f) { \
+        (s)[(i)++]=(uint8_t)__uc; \
+    } else { \
+        if(__uc<=0x7ff) { \
+            (s)[(i)++]=(uint8_t)((__uc>>6)|0xc0); \
+        } else { \
+            if(__uc<=0xffff) { \
+                (s)[(i)++]=(uint8_t)((__uc>>12)|0xe0); \
+            } else { \
+                (s)[(i)++]=(uint8_t)((__uc>>18)|0xf0); \
+                (s)[(i)++]=(uint8_t)(((__uc>>12)&0x3f)|0x80); \
+            } \
+            (s)[(i)++]=(uint8_t)(((__uc>>6)&0x3f)|0x80); \
+        } \
+        (s)[(i)++]=(uint8_t)((__uc&0x3f)|0x80); \
+    } \
+} UPRV_BLOCK_MACRO_END
+
+/**
+ * Append a code point to a string, overwriting 1 to 4 bytes.
+ * The offset points to the current end of the string contents
+ * and is advanced (post-increment).
+ * "Safe" macro, checks for a valid code point.
+ * If a non-ASCII code point is written, checks for sufficient space in the string.
+ * If the code point is not valid or trail bytes do not fit,
+ * then isError is set to TRUE.
+ *
+ * @param s const uint8_t * string buffer
+ * @param i int32_t string offset, must be i<capacity
+ * @param capacity int32_t size of the string buffer
+ * @param c UChar32 code point to append
+ * @param isError output UBool set to TRUE if an error occurs, otherwise not modified
+ * @see U8_APPEND_UNSAFE
+ * @stable ICU 2.4
+ */
+#define U8_APPEND(s, i, capacity, c, isError) UPRV_BLOCK_MACRO_BEGIN { \
+    uint32_t __uc=(c); \
+    if(__uc<=0x7f) { \
+        (s)[(i)++]=(uint8_t)__uc; \
+    } else if(__uc<=0x7ff && (i)+1<(capacity)) { \
+        (s)[(i)++]=(uint8_t)((__uc>>6)|0xc0); \
+        (s)[(i)++]=(uint8_t)((__uc&0x3f)|0x80); \
+    } else if((__uc<=0xd7ff || (0xe000<=__uc && __uc<=0xffff)) && (i)+2<(capacity)) { \
+        (s)[(i)++]=(uint8_t)((__uc>>12)|0xe0); \
+        (s)[(i)++]=(uint8_t)(((__uc>>6)&0x3f)|0x80); \
+        (s)[(i)++]=(uint8_t)((__uc&0x3f)|0x80); \
+    } else if(0xffff<__uc && __uc<=0x10ffff && (i)+3<(capacity)) { \
+        (s)[(i)++]=(uint8_t)((__uc>>18)|0xf0); \
+        (s)[(i)++]=(uint8_t)(((__uc>>12)&0x3f)|0x80); \
+        (s)[(i)++]=(uint8_t)(((__uc>>6)&0x3f)|0x80); \
+        (s)[(i)++]=(uint8_t)((__uc&0x3f)|0x80); \
+    } else { \
+        (isError)=TRUE; \
+    } \
+} UPRV_BLOCK_MACRO_END
+
+/**
+ * Advance the string offset from one code point boundary to the next.
+ * (Post-incrementing iteration.)
+ * "Unsafe" macro, assumes well-formed UTF-8.
+ *
+ * @param s const uint8_t * string
+ * @param i string offset
+ * @see U8_FWD_1
+ * @stable ICU 2.4
+ */
+#define U8_FWD_1_UNSAFE(s, i) UPRV_BLOCK_MACRO_BEGIN { \
+    (i)+=1+U8_COUNT_TRAIL_BYTES_UNSAFE((s)[i]); \
+} UPRV_BLOCK_MACRO_END
+
+/**
+ * Advance the string offset from one code point boundary to the next.
+ * (Post-incrementing iteration.)
+ * "Safe" macro, checks for illegal sequences and for string boundaries.
+ *
+ * The length can be negative for a NUL-terminated string.
+ *
+ * @param s const uint8_t * string
+ * @param i int32_t string offset, must be i<length
+ * @param length int32_t string length
+ * @see U8_FWD_1_UNSAFE
+ * @stable ICU 2.4
+ */
+#define U8_FWD_1(s, i, length) UPRV_BLOCK_MACRO_BEGIN { \
+    uint8_t __b=(s)[(i)++]; \
+    if(U8_IS_LEAD(__b) && (i)!=(length)) { \
+        uint8_t __t1=(s)[i]; \
+        if((0xe0<=__b && __b<0xf0)) { \
+            if(U8_IS_VALID_LEAD3_AND_T1(__b, __t1) && \
+                    ++(i)!=(length) && U8_IS_TRAIL((s)[i])) { \
+                ++(i); \
+            } \
+        } else if(__b<0xe0) { \
+            if(U8_IS_TRAIL(__t1)) { \
+                ++(i); \
+            } \
+        } else /* c>=0xf0 */ { \
+            if(U8_IS_VALID_LEAD4_AND_T1(__b, __t1) && \
+                    ++(i)!=(length) && U8_IS_TRAIL((s)[i]) && \
+                    ++(i)!=(length) && U8_IS_TRAIL((s)[i])) { \
+                ++(i); \
+            } \
+        } \
+    } \
+} UPRV_BLOCK_MACRO_END
+
+/**
+ * Advance the string offset from one code point boundary to the n-th next one,
+ * i.e., move forward by n code points.
+ * (Post-incrementing iteration.)
+ * "Unsafe" macro, assumes well-formed UTF-8.
+ *
+ * @param s const uint8_t * string
+ * @param i string offset
+ * @param n number of code points to skip
+ * @see U8_FWD_N
+ * @stable ICU 2.4
+ */
+#define U8_FWD_N_UNSAFE(s, i, n) UPRV_BLOCK_MACRO_BEGIN { \
+    int32_t __N=(n); \
+    while(__N>0) { \
+        U8_FWD_1_UNSAFE(s, i); \
+        --__N; \
+    } \
+} UPRV_BLOCK_MACRO_END
+
+/**
+ * Advance the string offset from one code point boundary to the n-th next one,
+ * i.e., move forward by n code points.
+ * (Post-incrementing iteration.)
+ * "Safe" macro, checks for illegal sequences and for string boundaries.
+ *
+ * The length can be negative for a NUL-terminated string.
+ *
+ * @param s const uint8_t * string
+ * @param i int32_t string offset, must be i<length
+ * @param length int32_t string length
+ * @param n number of code points to skip
+ * @see U8_FWD_N_UNSAFE
+ * @stable ICU 2.4
+ */
+#define U8_FWD_N(s, i, length, n) UPRV_BLOCK_MACRO_BEGIN { \
+    int32_t __N=(n); \
+    while(__N>0 && ((i)<(length) || ((length)<0 && (s)[i]!=0))) { \
+        U8_FWD_1(s, i, length); \
+        --__N; \
+    } \
+} UPRV_BLOCK_MACRO_END
+
+/**
+ * Adjust a random-access offset to a code point boundary
+ * at the start of a code point.
+ * If the offset points to a UTF-8 trail byte,
+ * then the offset is moved backward to the corresponding lead byte.
+ * Otherwise, it is not modified.
+ * "Unsafe" macro, assumes well-formed UTF-8.
+ *
+ * @param s const uint8_t * string
+ * @param i string offset
+ * @see U8_SET_CP_START
+ * @stable ICU 2.4
+ */
+#define U8_SET_CP_START_UNSAFE(s, i) UPRV_BLOCK_MACRO_BEGIN { \
+    while(U8_IS_TRAIL((s)[i])) { --(i); } \
+} UPRV_BLOCK_MACRO_END
+
+/**
+ * Adjust a random-access offset to a code point boundary
+ * at the start of a code point.
+ * If the offset points to a UTF-8 trail byte,
+ * then the offset is moved backward to the corresponding lead byte.
+ * Otherwise, it is not modified.
+ *
+ * "Safe" macro, checks for illegal sequences and for string boundaries.
+ * Unlike U8_TRUNCATE_IF_INCOMPLETE(), this macro always reads s[i].
+ *
+ * @param s const uint8_t * string
+ * @param start int32_t starting string offset (usually 0)
+ * @param i int32_t string offset, must be start<=i
+ * @see U8_SET_CP_START_UNSAFE
+ * @see U8_TRUNCATE_IF_INCOMPLETE
+ * @stable ICU 2.4
+ */
+#define U8_SET_CP_START(s, start, i) UPRV_BLOCK_MACRO_BEGIN { \
+    if(U8_IS_TRAIL((s)[(i)])) { \
+        (i)=utf8_back1SafeBody(s, start, (i)); \
+    } \
+} UPRV_BLOCK_MACRO_END
+
+/**
+ * If the string ends with a UTF-8 byte sequence that is valid so far
+ * but incomplete, then reduce the length of the string to end before
+ * the lead byte of that incomplete sequence.
+ * For example, if the string ends with E1 80, the length is reduced by 2.
+ *
+ * In all other cases (the string ends with a complete sequence, or it is not
+ * possible for any further trail byte to extend the trailing sequence)
+ * the length remains unchanged.
+ *
+ * Useful for processing text split across multiple buffers
+ * (save the incomplete sequence for later)
+ * and for optimizing iteration
+ * (check for string length only once per character).
+ *
+ * "Safe" macro, checks for illegal sequences and for string boundaries.
+ * Unlike U8_SET_CP_START(), this macro never reads s[length].
+ *
+ * (In UTF-16, simply check for U16_IS_LEAD(last code unit).)
+ *
+ * @param s const uint8_t * string
+ * @param start int32_t starting string offset (usually 0)
+ * @param length int32_t string length (usually start<=length)
+ * @see U8_SET_CP_START
+ * @stable ICU 61
+ */
+#define U8_TRUNCATE_IF_INCOMPLETE(s, start, length) UPRV_BLOCK_MACRO_BEGIN { \
+    if((length)>(start)) { \
+        uint8_t __b1=s[(length)-1]; \
+        if(U8_IS_SINGLE(__b1)) { \
+            /* common ASCII character */ \
+        } else if(U8_IS_LEAD(__b1)) { \
+            --(length); \
+        } else if(U8_IS_TRAIL(__b1) && ((length)-2)>=(start)) { \
+            uint8_t __b2=s[(length)-2]; \
+            if(0xe0<=__b2 && __b2<=0xf4) { \
+                if(__b2<0xf0 ? U8_IS_VALID_LEAD3_AND_T1(__b2, __b1) : \
+                        U8_IS_VALID_LEAD4_AND_T1(__b2, __b1)) { \
+                    (length)-=2; \
+                } \
+            } else if(U8_IS_TRAIL(__b2) && ((length)-3)>=(start)) { \
+                uint8_t __b3=s[(length)-3]; \
+                if(0xf0<=__b3 && __b3<=0xf4 && U8_IS_VALID_LEAD4_AND_T1(__b3, __b2)) { \
+                    (length)-=3; \
+                } \
+            } \
+        } \
+    } \
+} UPRV_BLOCK_MACRO_END
+
+/* definitions with backward iteration -------------------------------------- */
+
+/**
+ * Move the string offset from one code point boundary to the previous one
+ * and get the code point between them.
+ * (Pre-decrementing backward iteration.)
+ * "Unsafe" macro, assumes well-formed UTF-8.
+ *
+ * The input offset may be the same as the string length.
+ * If the offset is behind a multi-byte sequence, then the macro will read
+ * the whole sequence.
+ * If the offset is behind a lead byte, then that itself
+ * will be returned as the code point.
+ * The result is undefined if the offset is behind an illegal UTF-8 sequence.
+ *
+ * @param s const uint8_t * string
+ * @param i string offset
+ * @param c output UChar32 variable
+ * @see U8_PREV
+ * @stable ICU 2.4
+ */
+#define U8_PREV_UNSAFE(s, i, c) UPRV_BLOCK_MACRO_BEGIN { \
+    (c)=(uint8_t)(s)[--(i)]; \
+    if(U8_IS_TRAIL(c)) { \
+        uint8_t __b, __count=1, __shift=6; \
+\
+        /* c is a trail byte */ \
+        (c)&=0x3f; \
+        for(;;) { \
+            __b=(s)[--(i)]; \
+            if(__b>=0xc0) { \
+                U8_MASK_LEAD_BYTE(__b, __count); \
+                (c)|=(UChar32)__b<<__shift; \
+                break; \
+            } else { \
+                (c)|=(UChar32)(__b&0x3f)<<__shift; \
+                ++__count; \
+                __shift+=6; \
+            } \
+        } \
+    } \
+} UPRV_BLOCK_MACRO_END
+
+/**
+ * Move the string offset from one code point boundary to the previous one
+ * and get the code point between them.
+ * (Pre-decrementing backward iteration.)
+ * "Safe" macro, checks for illegal sequences and for string boundaries.
+ *
+ * The input offset may be the same as the string length.
+ * If the offset is behind a multi-byte sequence, then the macro will read
+ * the whole sequence.
+ * If the offset is behind a lead byte, then that itself
+ * will be returned as the code point.
+ * If the offset is behind an illegal UTF-8 sequence, then c is set to a negative value.
+ *
+ * @param s const uint8_t * string
+ * @param start int32_t starting string offset (usually 0)
+ * @param i int32_t string offset, must be start<i
+ * @param c output UChar32 variable, set to <0 in case of an error
+ * @see U8_PREV_UNSAFE
+ * @stable ICU 2.4
+ */
+#define U8_PREV(s, start, i, c) UPRV_BLOCK_MACRO_BEGIN { \
+    (c)=(uint8_t)(s)[--(i)]; \
+    if(!U8_IS_SINGLE(c)) { \
+        (c)=utf8_prevCharSafeBody((const uint8_t *)s, start, &(i), c, -1); \
+    } \
+} UPRV_BLOCK_MACRO_END
+
+/**
+ * Move the string offset from one code point boundary to the previous one
+ * and get the code point between them.
+ * (Pre-decrementing backward iteration.)
+ * "Safe" macro, checks for illegal sequences and for string boundaries.
+ *
+ * The input offset may be the same as the string length.
+ * If the offset is behind a multi-byte sequence, then the macro will read
+ * the whole sequence.
+ * If the offset is behind a lead byte, then that itself
+ * will be returned as the code point.
+ * If the offset is behind an illegal UTF-8 sequence, then c is set to U+FFFD.
+ *
+ * This macro does not distinguish between a real U+FFFD in the text
+ * and U+FFFD returned for an ill-formed sequence.
+ * Use U8_PREV() if that distinction is important.
+ *
+ * @param s const uint8_t * string
+ * @param start int32_t starting string offset (usually 0)
+ * @param i int32_t string offset, must be start<i
+ * @param c output UChar32 variable, set to U+FFFD in case of an error
+ * @see U8_PREV
+ * @stable ICU 51
+ */
+#define U8_PREV_OR_FFFD(s, start, i, c) UPRV_BLOCK_MACRO_BEGIN { \
+    (c)=(uint8_t)(s)[--(i)]; \
+    if(!U8_IS_SINGLE(c)) { \
+        (c)=utf8_prevCharSafeBody((const uint8_t *)s, start, &(i), c, -3); \
+    } \
+} UPRV_BLOCK_MACRO_END
+
+/**
+ * Move the string offset from one code point boundary to the previous one.
+ * (Pre-decrementing backward iteration.)
+ * The input offset may be the same as the string length.
+ * "Unsafe" macro, assumes well-formed UTF-8.
+ *
+ * @param s const uint8_t * string
+ * @param i string offset
+ * @see U8_BACK_1
+ * @stable ICU 2.4
+ */
+#define U8_BACK_1_UNSAFE(s, i) UPRV_BLOCK_MACRO_BEGIN { \
+    while(U8_IS_TRAIL((s)[--(i)])) {} \
+} UPRV_BLOCK_MACRO_END
+
+/**
+ * Move the string offset from one code point boundary to the previous one.
+ * (Pre-decrementing backward iteration.)
+ * The input offset may be the same as the string length.
+ * "Safe" macro, checks for illegal sequences and for string boundaries.
+ *
+ * @param s const uint8_t * string
+ * @param start int32_t starting string offset (usually 0)
+ * @param i int32_t string offset, must be start<i
+ * @see U8_BACK_1_UNSAFE
+ * @stable ICU 2.4
+ */
+#define U8_BACK_1(s, start, i) UPRV_BLOCK_MACRO_BEGIN { \
+    if(U8_IS_TRAIL((s)[--(i)])) { \
+        (i)=utf8_back1SafeBody(s, start, (i)); \
+    } \
+} UPRV_BLOCK_MACRO_END
+
+/**
+ * Move the string offset from one code point boundary to the n-th one before it,
+ * i.e., move backward by n code points.
+ * (Pre-decrementing backward iteration.)
+ * The input offset may be the same as the string length.
+ * "Unsafe" macro, assumes well-formed UTF-8.
+ *
+ * @param s const uint8_t * string
+ * @param i string offset
+ * @param n number of code points to skip
+ * @see U8_BACK_N
+ * @stable ICU 2.4
+ */
+#define U8_BACK_N_UNSAFE(s, i, n) UPRV_BLOCK_MACRO_BEGIN { \
+    int32_t __N=(n); \
+    while(__N>0) { \
+        U8_BACK_1_UNSAFE(s, i); \
+        --__N; \
+    } \
+} UPRV_BLOCK_MACRO_END
+
+/**
+ * Move the string offset from one code point boundary to the n-th one before it,
+ * i.e., move backward by n code points.
+ * (Pre-decrementing backward iteration.)
+ * The input offset may be the same as the string length.
+ * "Safe" macro, checks for illegal sequences and for string boundaries.
+ *
+ * @param s const uint8_t * string
+ * @param start int32_t index of the start of the string
+ * @param i int32_t string offset, must be start<i
+ * @param n number of code points to skip
+ * @see U8_BACK_N_UNSAFE
+ * @stable ICU 2.4
+ */
+#define U8_BACK_N(s, start, i, n) UPRV_BLOCK_MACRO_BEGIN { \
+    int32_t __N=(n); \
+    while(__N>0 && (i)>(start)) { \
+        U8_BACK_1(s, start, i); \
+        --__N; \
+    } \
+} UPRV_BLOCK_MACRO_END
+
+/**
+ * Adjust a random-access offset to a code point boundary after a code point.
+ * If the offset is behind a partial multi-byte sequence,
+ * then the offset is incremented to behind the whole sequence.
+ * Otherwise, it is not modified.
+ * The input offset may be the same as the string length.
+ * "Unsafe" macro, assumes well-formed UTF-8.
+ *
+ * @param s const uint8_t * string
+ * @param i string offset
+ * @see U8_SET_CP_LIMIT
+ * @stable ICU 2.4
+ */
+#define U8_SET_CP_LIMIT_UNSAFE(s, i) UPRV_BLOCK_MACRO_BEGIN { \
+    U8_BACK_1_UNSAFE(s, i); \
+    U8_FWD_1_UNSAFE(s, i); \
+} UPRV_BLOCK_MACRO_END
+
+/**
+ * Adjust a random-access offset to a code point boundary after a code point.
+ * If the offset is behind a partial multi-byte sequence,
+ * then the offset is incremented to behind the whole sequence.
+ * Otherwise, it is not modified.
+ * The input offset may be the same as the string length.
+ * "Safe" macro, checks for illegal sequences and for string boundaries.
+ *
+ * The length can be negative for a NUL-terminated string.
+ *
+ * @param s const uint8_t * string
+ * @param start int32_t starting string offset (usually 0)
+ * @param i int32_t string offset, must be start<=i<=length
+ * @param length int32_t string length
+ * @see U8_SET_CP_LIMIT_UNSAFE
+ * @stable ICU 2.4
+ */
+#define U8_SET_CP_LIMIT(s, start, i, length) UPRV_BLOCK_MACRO_BEGIN { \
+    if((start)<(i) && ((i)<(length) || (length)<0)) { \
+        U8_BACK_1(s, start, i); \
+        U8_FWD_1(s, i, length); \
+    } \
+} UPRV_BLOCK_MACRO_END
+
+#endif
diff --git a/vendor/tree-sitter/lib/src/wasm/stdlib.c b/vendor/tree-sitter/lib/src/wasm/stdlib.c
new file mode 100644
--- /dev/null
+++ b/vendor/tree-sitter/lib/src/wasm/stdlib.c
@@ -0,0 +1,109 @@
+// This file implements a very simple allocator for external scanners running
+// in WASM. Allocation is just bumping a static pointer and growing the heap
+// as needed, and freeing is mostly a noop. But in the special case of freeing
+// the last-allocated pointer, we'll reuse that pointer again.
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+
+extern void tree_sitter_debug_message(const char *, size_t);
+
+#define PAGESIZE 0x10000
+#define MAX_HEAP_SIZE (4 * 1024 * 1024)
+
+typedef struct {
+  size_t size;
+  char data[0];
+} Region;
+
+static Region *heap_end = NULL;
+static Region *heap_start = NULL;
+static Region *next = NULL;
+
+// Get the region metadata for the given heap pointer.
+static inline Region *region_for_ptr(void *ptr) {
+  return ((Region *)ptr) - 1;
+}
+
+// Get the location of the next region after the given region,
+// if the given region had the given size.
+static inline Region *region_after(Region *self, size_t len) {
+  char *address = self->data + len;
+  char *aligned = (char *)((uintptr_t)(address + 3) & ~0x3);
+  return (Region *)aligned;
+}
+
+static void *get_heap_end() {
+  return (void *)(__builtin_wasm_memory_size(0) * PAGESIZE);
+}
+
+static int grow_heap(size_t size) {
+  size_t new_page_count = ((size - 1) / PAGESIZE) + 1;
+  return __builtin_wasm_memory_grow(0, new_page_count) != SIZE_MAX;
+}
+
+// Clear out the heap, and move it to the given address.
+void reset_heap(void *new_heap_start) {
+  heap_start = new_heap_start;
+  next = new_heap_start;
+  heap_end = get_heap_end();
+}
+
+void *malloc(size_t size) {
+  Region *region_end = region_after(next, size);
+
+  if (region_end > heap_end) {
+    if ((char *)region_end - (char *)heap_start > MAX_HEAP_SIZE) {
+      return NULL;
+    }
+    if (!grow_heap(size)) return NULL;
+    heap_end = get_heap_end();
+  }
+
+  void *result = &next->data;
+  next->size = size;
+  next = region_end;
+
+  return result;
+}
+
+void free(void *ptr) {
+  if (ptr == NULL) return;
+
+  Region *region = region_for_ptr(ptr);
+  Region *region_end = region_after(region, region->size);
+
+  // When freeing the last allocated pointer, re-use that
+  // pointer for the next allocation.
+  if (region_end == next) {
+    next = region;
+  }
+}
+
+void *calloc(size_t count, size_t size) {
+  void *result = malloc(count * size);
+  memset(result, 0, count * size);
+  return result;
+}
+
+void *realloc(void *ptr, size_t new_size) {
+  if (ptr == NULL) {
+    return malloc(new_size);
+  }
+
+  Region *region = region_for_ptr(ptr);
+  Region *region_end = region_after(region, region->size);
+
+  // When reallocating the last allocated region, return
+  // the same pointer, and skip copying the data.
+  if (region_end == next) {
+    next = region;
+    return malloc(new_size);
+  }
+
+  void *result = malloc(new_size);
+  memcpy(result, &region->data, region->size);
+  return result;
+}
diff --git a/vendor/tree-sitter/lib/src/wasm/wasm-stdlib.h b/vendor/tree-sitter/lib/src/wasm/wasm-stdlib.h
new file mode 100644
--- /dev/null
+++ b/vendor/tree-sitter/lib/src/wasm/wasm-stdlib.h
@@ -0,0 +1,1302 @@
+unsigned char STDLIB_WASM[] = {
+  0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x1e, 0x06, 0x60,
+  0x02, 0x7f, 0x7f, 0x01, 0x7f, 0x60, 0x01, 0x7f, 0x00, 0x60, 0x00, 0x00,
+  0x60, 0x01, 0x7f, 0x01, 0x7f, 0x60, 0x00, 0x01, 0x7f, 0x60, 0x03, 0x7f,
+  0x7f, 0x7f, 0x01, 0x7f, 0x02, 0x9e, 0x01, 0x05, 0x03, 0x65, 0x6e, 0x76,
+  0x06, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x02, 0x00, 0x02, 0x03, 0x65,
+  0x6e, 0x76, 0x19, 0x5f, 0x5f, 0x69, 0x6e, 0x64, 0x69, 0x72, 0x65, 0x63,
+  0x74, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74,
+  0x61, 0x62, 0x6c, 0x65, 0x01, 0x70, 0x00, 0x01, 0x16, 0x77, 0x61, 0x73,
+  0x69, 0x5f, 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x5f, 0x70,
+  0x72, 0x65, 0x76, 0x69, 0x65, 0x77, 0x31, 0x08, 0x61, 0x72, 0x67, 0x73,
+  0x5f, 0x67, 0x65, 0x74, 0x00, 0x00, 0x16, 0x77, 0x61, 0x73, 0x69, 0x5f,
+  0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x5f, 0x70, 0x72, 0x65,
+  0x76, 0x69, 0x65, 0x77, 0x31, 0x0e, 0x61, 0x72, 0x67, 0x73, 0x5f, 0x73,
+  0x69, 0x7a, 0x65, 0x73, 0x5f, 0x67, 0x65, 0x74, 0x00, 0x00, 0x16, 0x77,
+  0x61, 0x73, 0x69, 0x5f, 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74,
+  0x5f, 0x70, 0x72, 0x65, 0x76, 0x69, 0x65, 0x77, 0x31, 0x09, 0x70, 0x72,
+  0x6f, 0x63, 0x5f, 0x65, 0x78, 0x69, 0x74, 0x00, 0x01, 0x03, 0x2a, 0x29,
+  0x02, 0x00, 0x02, 0x02, 0x01, 0x03, 0x01, 0x00, 0x00, 0x01, 0x04, 0x00,
+  0x00, 0x01, 0x02, 0x02, 0x05, 0x05, 0x03, 0x03, 0x05, 0x05, 0x00, 0x03,
+  0x00, 0x03, 0x05, 0x03, 0x05, 0x03, 0x03, 0x03, 0x03, 0x05, 0x05, 0x05,
+  0x03, 0x03, 0x00, 0x03, 0x03, 0x06, 0x0d, 0x02, 0x7f, 0x01, 0x41, 0x80,
+  0x80, 0x04, 0x0b, 0x7f, 0x00, 0x41, 0x00, 0x0b, 0x07, 0xad, 0x02, 0x1c,
+  0x11, 0x5f, 0x5f, 0x77, 0x61, 0x73, 0x6d, 0x5f, 0x63, 0x61, 0x6c, 0x6c,
+  0x5f, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x00, 0x03, 0x0f, 0x5f, 0x5f, 0x73,
+  0x74, 0x61, 0x63, 0x6b, 0x5f, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x65, 0x72,
+  0x03, 0x00, 0x06, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x00, 0x06, 0x0a,
+  0x72, 0x65, 0x73, 0x65, 0x74, 0x5f, 0x68, 0x65, 0x61, 0x70, 0x00, 0x07,
+  0x06, 0x6d, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x00, 0x08, 0x04, 0x66, 0x72,
+  0x65, 0x65, 0x00, 0x09, 0x06, 0x63, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x00,
+  0x0a, 0x06, 0x6d, 0x65, 0x6d, 0x73, 0x65, 0x74, 0x00, 0x14, 0x07, 0x72,
+  0x65, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x00, 0x0b, 0x06, 0x6d, 0x65, 0x6d,
+  0x63, 0x70, 0x79, 0x00, 0x13, 0x06, 0x73, 0x74, 0x72, 0x6c, 0x65, 0x6e,
+  0x00, 0x15, 0x08, 0x69, 0x73, 0x77, 0x61, 0x6c, 0x6e, 0x75, 0x6d, 0x00,
+  0x2b, 0x08, 0x69, 0x73, 0x77, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x00, 0x16,
+  0x08, 0x69, 0x73, 0x77, 0x62, 0x6c, 0x61, 0x6e, 0x6b, 0x00, 0x22, 0x08,
+  0x69, 0x73, 0x77, 0x64, 0x69, 0x67, 0x69, 0x74, 0x00, 0x23, 0x08, 0x69,
+  0x73, 0x77, 0x6c, 0x6f, 0x77, 0x65, 0x72, 0x00, 0x20, 0x08, 0x69, 0x73,
+  0x77, 0x73, 0x70, 0x61, 0x63, 0x65, 0x00, 0x2a, 0x08, 0x69, 0x73, 0x77,
+  0x75, 0x70, 0x70, 0x65, 0x72, 0x00, 0x1e, 0x09, 0x69, 0x73, 0x77, 0x78,
+  0x64, 0x69, 0x67, 0x69, 0x74, 0x00, 0x27, 0x08, 0x74, 0x6f, 0x77, 0x6c,
+  0x6f, 0x77, 0x65, 0x72, 0x00, 0x1a, 0x08, 0x74, 0x6f, 0x77, 0x75, 0x70,
+  0x70, 0x65, 0x72, 0x00, 0x1c, 0x06, 0x6d, 0x65, 0x6d, 0x63, 0x68, 0x72,
+  0x00, 0x18, 0x06, 0x6d, 0x65, 0x6d, 0x63, 0x6d, 0x70, 0x00, 0x17, 0x07,
+  0x6d, 0x65, 0x6d, 0x6d, 0x6f, 0x76, 0x65, 0x00, 0x1f, 0x06, 0x73, 0x74,
+  0x72, 0x63, 0x6d, 0x70, 0x00, 0x19, 0x07, 0x73, 0x74, 0x72, 0x6e, 0x63,
+  0x61, 0x74, 0x00, 0x24, 0x07, 0x73, 0x74, 0x72, 0x6e, 0x63, 0x6d, 0x70,
+  0x00, 0x1d, 0x07, 0x73, 0x74, 0x72, 0x6e, 0x63, 0x70, 0x79, 0x00, 0x26,
+  0x08, 0x01, 0x05, 0x0a, 0xe8, 0x2b, 0x29, 0x02, 0x00, 0x0b, 0x03, 0x00,
+  0x00, 0x0b, 0x0d, 0x00, 0x41, 0xe8, 0xc2, 0x04, 0x41, 0x00, 0x41, 0x10,
+  0xfc, 0x0b, 0x00, 0x0b, 0x52, 0x01, 0x01, 0x7f, 0x02, 0x40, 0x02, 0x40,
+  0x23, 0x81, 0x80, 0x80, 0x80, 0x00, 0x41, 0xe8, 0xc2, 0x84, 0x80, 0x00,
+  0x6a, 0x28, 0x02, 0x00, 0x0d, 0x00, 0x23, 0x81, 0x80, 0x80, 0x80, 0x00,
+  0x41, 0xe8, 0xc2, 0x84, 0x80, 0x00, 0x6a, 0x41, 0x01, 0x36, 0x02, 0x00,
+  0x10, 0x83, 0x80, 0x80, 0x80, 0x00, 0x10, 0x8d, 0x80, 0x80, 0x80, 0x00,
+  0x21, 0x00, 0x10, 0x92, 0x80, 0x80, 0x80, 0x00, 0x20, 0x00, 0x0d, 0x01,
+  0x0f, 0x0b, 0x00, 0x00, 0x0b, 0x20, 0x00, 0x10, 0x90, 0x80, 0x80, 0x80,
+  0x00, 0x00, 0x0b, 0x37, 0x01, 0x01, 0x7f, 0x23, 0x81, 0x80, 0x80, 0x80,
+  0x00, 0x22, 0x01, 0x41, 0xf0, 0xc2, 0x84, 0x80, 0x00, 0x6a, 0x20, 0x00,
+  0x36, 0x02, 0x00, 0x20, 0x01, 0x41, 0xec, 0xc2, 0x84, 0x80, 0x00, 0x6a,
+  0x20, 0x00, 0x36, 0x02, 0x00, 0x20, 0x01, 0x41, 0xf4, 0xc2, 0x84, 0x80,
+  0x00, 0x6a, 0x3f, 0x00, 0x41, 0x10, 0x74, 0x36, 0x02, 0x00, 0x0b, 0xb4,
+  0x01, 0x01, 0x03, 0x7f, 0x02, 0x40, 0x02, 0x40, 0x23, 0x81, 0x80, 0x80,
+  0x80, 0x00, 0x22, 0x01, 0x41, 0xf4, 0xc2, 0x84, 0x80, 0x00, 0x6a, 0x28,
+  0x02, 0x00, 0x20, 0x01, 0x41, 0xf0, 0xc2, 0x84, 0x80, 0x00, 0x6a, 0x28,
+  0x02, 0x00, 0x22, 0x01, 0x20, 0x00, 0x6a, 0x41, 0x07, 0x6a, 0x41, 0x7c,
+  0x71, 0x22, 0x02, 0x4f, 0x0d, 0x00, 0x41, 0x00, 0x21, 0x01, 0x20, 0x02,
+  0x23, 0x81, 0x80, 0x80, 0x80, 0x00, 0x41, 0xec, 0xc2, 0x84, 0x80, 0x00,
+  0x6a, 0x28, 0x02, 0x00, 0x6b, 0x41, 0x80, 0x80, 0x80, 0x02, 0x4a, 0x0d,
+  0x01, 0x20, 0x00, 0x41, 0x7f, 0x6a, 0x41, 0x10, 0x76, 0x41, 0x01, 0x6a,
+  0x40, 0x00, 0x41, 0x7f, 0x46, 0x0d, 0x01, 0x3f, 0x00, 0x21, 0x01, 0x23,
+  0x81, 0x80, 0x80, 0x80, 0x00, 0x22, 0x03, 0x41, 0xf4, 0xc2, 0x84, 0x80,
+  0x00, 0x6a, 0x20, 0x01, 0x41, 0x10, 0x74, 0x36, 0x02, 0x00, 0x20, 0x03,
+  0x41, 0xf0, 0xc2, 0x84, 0x80, 0x00, 0x6a, 0x28, 0x02, 0x00, 0x21, 0x01,
+  0x0b, 0x20, 0x01, 0x20, 0x00, 0x36, 0x02, 0x00, 0x23, 0x81, 0x80, 0x80,
+  0x80, 0x00, 0x41, 0xf0, 0xc2, 0x84, 0x80, 0x00, 0x6a, 0x20, 0x02, 0x36,
+  0x02, 0x00, 0x20, 0x01, 0x41, 0x04, 0x6a, 0x21, 0x01, 0x0b, 0x20, 0x01,
+  0x0b, 0x48, 0x01, 0x02, 0x7f, 0x02, 0x40, 0x20, 0x00, 0x45, 0x0d, 0x00,
+  0x20, 0x00, 0x41, 0x7c, 0x6a, 0x22, 0x01, 0x28, 0x02, 0x00, 0x21, 0x02,
+  0x23, 0x81, 0x80, 0x80, 0x80, 0x00, 0x41, 0xf0, 0xc2, 0x84, 0x80, 0x00,
+  0x6a, 0x28, 0x02, 0x00, 0x20, 0x00, 0x20, 0x02, 0x6a, 0x41, 0x03, 0x6a,
+  0x41, 0x7c, 0x71, 0x47, 0x0d, 0x00, 0x23, 0x81, 0x80, 0x80, 0x80, 0x00,
+  0x41, 0xf0, 0xc2, 0x84, 0x80, 0x00, 0x6a, 0x20, 0x01, 0x36, 0x02, 0x00,
+  0x0b, 0x0b, 0x19, 0x00, 0x20, 0x01, 0x20, 0x00, 0x6c, 0x22, 0x00, 0x10,
+  0x88, 0x80, 0x80, 0x80, 0x00, 0x41, 0x00, 0x20, 0x00, 0x10, 0x94, 0x80,
+  0x80, 0x80, 0x00, 0x0b, 0x6b, 0x01, 0x02, 0x7f, 0x02, 0x40, 0x20, 0x00,
+  0x45, 0x0d, 0x00, 0x20, 0x00, 0x41, 0x7c, 0x6a, 0x22, 0x02, 0x28, 0x02,
+  0x00, 0x21, 0x03, 0x02, 0x40, 0x23, 0x81, 0x80, 0x80, 0x80, 0x00, 0x41,
+  0xf0, 0xc2, 0x84, 0x80, 0x00, 0x6a, 0x28, 0x02, 0x00, 0x20, 0x00, 0x20,
+  0x03, 0x6a, 0x41, 0x03, 0x6a, 0x41, 0x7c, 0x71, 0x47, 0x0d, 0x00, 0x23,
+  0x81, 0x80, 0x80, 0x80, 0x00, 0x41, 0xf0, 0xc2, 0x84, 0x80, 0x00, 0x6a,
+  0x20, 0x02, 0x36, 0x02, 0x00, 0x0c, 0x01, 0x0b, 0x20, 0x01, 0x10, 0x88,
+  0x80, 0x80, 0x80, 0x00, 0x20, 0x00, 0x20, 0x02, 0x28, 0x02, 0x00, 0x10,
+  0x93, 0x80, 0x80, 0x80, 0x00, 0x0f, 0x0b, 0x20, 0x01, 0x10, 0x88, 0x80,
+  0x80, 0x80, 0x00, 0x0b, 0x0b, 0x00, 0x20, 0x00, 0x10, 0x90, 0x80, 0x80,
+  0x80, 0x00, 0x00, 0x0b, 0xd5, 0x01, 0x01, 0x03, 0x7f, 0x23, 0x80, 0x80,
+  0x80, 0x80, 0x00, 0x41, 0x10, 0x6b, 0x22, 0x00, 0x24, 0x80, 0x80, 0x80,
+  0x80, 0x00, 0x02, 0x40, 0x02, 0x40, 0x02, 0x40, 0x02, 0x40, 0x02, 0x40,
+  0x20, 0x00, 0x41, 0x08, 0x6a, 0x20, 0x00, 0x41, 0x0c, 0x6a, 0x10, 0x8f,
+  0x80, 0x80, 0x80, 0x00, 0x0d, 0x00, 0x20, 0x00, 0x28, 0x02, 0x08, 0x41,
+  0x01, 0x6a, 0x22, 0x01, 0x45, 0x0d, 0x01, 0x20, 0x00, 0x28, 0x02, 0x0c,
+  0x10, 0x88, 0x80, 0x80, 0x80, 0x00, 0x22, 0x02, 0x45, 0x0d, 0x02, 0x20,
+  0x01, 0x41, 0x04, 0x10, 0x8a, 0x80, 0x80, 0x80, 0x00, 0x22, 0x01, 0x45,
+  0x0d, 0x03, 0x20, 0x01, 0x20, 0x02, 0x10, 0x8e, 0x80, 0x80, 0x80, 0x00,
+  0x0d, 0x04, 0x20, 0x00, 0x28, 0x02, 0x08, 0x20, 0x01, 0x10, 0x84, 0x80,
+  0x80, 0x80, 0x00, 0x21, 0x01, 0x20, 0x00, 0x41, 0x10, 0x6a, 0x24, 0x80,
+  0x80, 0x80, 0x80, 0x00, 0x20, 0x01, 0x0f, 0x0b, 0x41, 0xc7, 0x00, 0x10,
+  0x8c, 0x80, 0x80, 0x80, 0x00, 0x00, 0x0b, 0x41, 0xc6, 0x00, 0x10, 0x8c,
+  0x80, 0x80, 0x80, 0x00, 0x00, 0x0b, 0x41, 0xc6, 0x00, 0x10, 0x8c, 0x80,
+  0x80, 0x80, 0x00, 0x00, 0x0b, 0x20, 0x02, 0x10, 0x89, 0x80, 0x80, 0x80,
+  0x00, 0x41, 0xc6, 0x00, 0x10, 0x8c, 0x80, 0x80, 0x80, 0x00, 0x00, 0x0b,
+  0x20, 0x02, 0x10, 0x89, 0x80, 0x80, 0x80, 0x00, 0x20, 0x01, 0x10, 0x89,
+  0x80, 0x80, 0x80, 0x00, 0x41, 0xc7, 0x00, 0x10, 0x8c, 0x80, 0x80, 0x80,
+  0x00, 0x00, 0x0b, 0x11, 0x00, 0x20, 0x00, 0x20, 0x01, 0x10, 0x80, 0x80,
+  0x80, 0x80, 0x00, 0x41, 0xff, 0xff, 0x03, 0x71, 0x0b, 0x11, 0x00, 0x20,
+  0x00, 0x20, 0x01, 0x10, 0x81, 0x80, 0x80, 0x80, 0x00, 0x41, 0xff, 0xff,
+  0x03, 0x71, 0x0b, 0x0b, 0x00, 0x20, 0x00, 0x10, 0x82, 0x80, 0x80, 0x80,
+  0x00, 0x00, 0x0b, 0x02, 0x00, 0x0b, 0x0e, 0x00, 0x10, 0x91, 0x80, 0x80,
+  0x80, 0x00, 0x10, 0x91, 0x80, 0x80, 0x80, 0x00, 0x0b, 0xe6, 0x07, 0x01,
+  0x04, 0x7f, 0x02, 0x40, 0x02, 0x40, 0x02, 0x40, 0x20, 0x02, 0x41, 0x20,
+  0x4b, 0x0d, 0x00, 0x20, 0x01, 0x41, 0x03, 0x71, 0x45, 0x0d, 0x01, 0x20,
+  0x02, 0x45, 0x0d, 0x01, 0x20, 0x00, 0x20, 0x01, 0x2d, 0x00, 0x00, 0x3a,
+  0x00, 0x00, 0x20, 0x02, 0x41, 0x7f, 0x6a, 0x21, 0x03, 0x20, 0x00, 0x41,
+  0x01, 0x6a, 0x21, 0x04, 0x20, 0x01, 0x41, 0x01, 0x6a, 0x22, 0x05, 0x41,
+  0x03, 0x71, 0x45, 0x0d, 0x02, 0x20, 0x03, 0x45, 0x0d, 0x02, 0x20, 0x00,
+  0x20, 0x01, 0x2d, 0x00, 0x01, 0x3a, 0x00, 0x01, 0x20, 0x02, 0x41, 0x7e,
+  0x6a, 0x21, 0x03, 0x20, 0x00, 0x41, 0x02, 0x6a, 0x21, 0x04, 0x20, 0x01,
+  0x41, 0x02, 0x6a, 0x22, 0x05, 0x41, 0x03, 0x71, 0x45, 0x0d, 0x02, 0x20,
+  0x03, 0x45, 0x0d, 0x02, 0x20, 0x00, 0x20, 0x01, 0x2d, 0x00, 0x02, 0x3a,
+  0x00, 0x02, 0x20, 0x02, 0x41, 0x7d, 0x6a, 0x21, 0x03, 0x20, 0x00, 0x41,
+  0x03, 0x6a, 0x21, 0x04, 0x20, 0x01, 0x41, 0x03, 0x6a, 0x22, 0x05, 0x41,
+  0x03, 0x71, 0x45, 0x0d, 0x02, 0x20, 0x03, 0x45, 0x0d, 0x02, 0x20, 0x00,
+  0x20, 0x01, 0x2d, 0x00, 0x03, 0x3a, 0x00, 0x03, 0x20, 0x02, 0x41, 0x7c,
+  0x6a, 0x21, 0x03, 0x20, 0x00, 0x41, 0x04, 0x6a, 0x21, 0x04, 0x20, 0x01,
+  0x41, 0x04, 0x6a, 0x21, 0x05, 0x0c, 0x02, 0x0b, 0x20, 0x00, 0x20, 0x01,
+  0x20, 0x02, 0xfc, 0x0a, 0x00, 0x00, 0x20, 0x00, 0x0f, 0x0b, 0x20, 0x02,
+  0x21, 0x03, 0x20, 0x00, 0x21, 0x04, 0x20, 0x01, 0x21, 0x05, 0x0b, 0x02,
+  0x40, 0x02, 0x40, 0x20, 0x04, 0x41, 0x03, 0x71, 0x22, 0x02, 0x0d, 0x00,
+  0x02, 0x40, 0x02, 0x40, 0x20, 0x03, 0x41, 0x10, 0x4f, 0x0d, 0x00, 0x20,
+  0x03, 0x21, 0x02, 0x0c, 0x01, 0x0b, 0x02, 0x40, 0x20, 0x03, 0x41, 0x70,
+  0x6a, 0x22, 0x02, 0x41, 0x10, 0x71, 0x0d, 0x00, 0x20, 0x04, 0x20, 0x05,
+  0x29, 0x02, 0x00, 0x37, 0x02, 0x00, 0x20, 0x04, 0x20, 0x05, 0x29, 0x02,
+  0x08, 0x37, 0x02, 0x08, 0x20, 0x04, 0x41, 0x10, 0x6a, 0x21, 0x04, 0x20,
+  0x05, 0x41, 0x10, 0x6a, 0x21, 0x05, 0x20, 0x02, 0x21, 0x03, 0x0b, 0x20,
+  0x02, 0x41, 0x10, 0x49, 0x0d, 0x00, 0x20, 0x03, 0x21, 0x02, 0x03, 0x40,
+  0x20, 0x04, 0x20, 0x05, 0x29, 0x02, 0x00, 0x37, 0x02, 0x00, 0x20, 0x04,
+  0x20, 0x05, 0x29, 0x02, 0x08, 0x37, 0x02, 0x08, 0x20, 0x04, 0x20, 0x05,
+  0x29, 0x02, 0x10, 0x37, 0x02, 0x10, 0x20, 0x04, 0x20, 0x05, 0x29, 0x02,
+  0x18, 0x37, 0x02, 0x18, 0x20, 0x04, 0x41, 0x20, 0x6a, 0x21, 0x04, 0x20,
+  0x05, 0x41, 0x20, 0x6a, 0x21, 0x05, 0x20, 0x02, 0x41, 0x60, 0x6a, 0x22,
+  0x02, 0x41, 0x0f, 0x4b, 0x0d, 0x00, 0x0b, 0x0b, 0x02, 0x40, 0x20, 0x02,
+  0x41, 0x08, 0x49, 0x0d, 0x00, 0x20, 0x04, 0x20, 0x05, 0x29, 0x02, 0x00,
+  0x37, 0x02, 0x00, 0x20, 0x05, 0x41, 0x08, 0x6a, 0x21, 0x05, 0x20, 0x04,
+  0x41, 0x08, 0x6a, 0x21, 0x04, 0x0b, 0x02, 0x40, 0x20, 0x02, 0x41, 0x04,
+  0x71, 0x45, 0x0d, 0x00, 0x20, 0x04, 0x20, 0x05, 0x28, 0x02, 0x00, 0x36,
+  0x02, 0x00, 0x20, 0x05, 0x41, 0x04, 0x6a, 0x21, 0x05, 0x20, 0x04, 0x41,
+  0x04, 0x6a, 0x21, 0x04, 0x0b, 0x02, 0x40, 0x20, 0x02, 0x41, 0x02, 0x71,
+  0x45, 0x0d, 0x00, 0x20, 0x04, 0x20, 0x05, 0x2f, 0x00, 0x00, 0x3b, 0x00,
+  0x00, 0x20, 0x04, 0x41, 0x02, 0x6a, 0x21, 0x04, 0x20, 0x05, 0x41, 0x02,
+  0x6a, 0x21, 0x05, 0x0b, 0x20, 0x02, 0x41, 0x01, 0x71, 0x45, 0x0d, 0x01,
+  0x20, 0x04, 0x20, 0x05, 0x2d, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x20, 0x00,
+  0x0f, 0x0b, 0x02, 0x40, 0x02, 0x40, 0x02, 0x40, 0x02, 0x40, 0x02, 0x40,
+  0x20, 0x03, 0x41, 0x20, 0x49, 0x0d, 0x00, 0x02, 0x40, 0x02, 0x40, 0x20,
+  0x02, 0x41, 0x7f, 0x6a, 0x0e, 0x03, 0x03, 0x00, 0x01, 0x07, 0x0b, 0x20,
+  0x04, 0x20, 0x05, 0x28, 0x02, 0x00, 0x3b, 0x00, 0x00, 0x20, 0x04, 0x20,
+  0x05, 0x41, 0x02, 0x6a, 0x28, 0x01, 0x00, 0x36, 0x02, 0x02, 0x20, 0x04,
+  0x20, 0x05, 0x41, 0x06, 0x6a, 0x29, 0x01, 0x00, 0x37, 0x02, 0x06, 0x20,
+  0x04, 0x41, 0x12, 0x6a, 0x21, 0x02, 0x20, 0x05, 0x41, 0x12, 0x6a, 0x21,
+  0x01, 0x41, 0x0e, 0x21, 0x06, 0x20, 0x05, 0x41, 0x0e, 0x6a, 0x28, 0x01,
+  0x00, 0x21, 0x05, 0x41, 0x0e, 0x21, 0x03, 0x0c, 0x03, 0x0b, 0x20, 0x04,
+  0x20, 0x05, 0x28, 0x02, 0x00, 0x3a, 0x00, 0x00, 0x20, 0x04, 0x20, 0x05,
+  0x41, 0x01, 0x6a, 0x28, 0x00, 0x00, 0x36, 0x02, 0x01, 0x20, 0x04, 0x20,
+  0x05, 0x41, 0x05, 0x6a, 0x29, 0x00, 0x00, 0x37, 0x02, 0x05, 0x20, 0x04,
+  0x41, 0x11, 0x6a, 0x21, 0x02, 0x20, 0x05, 0x41, 0x11, 0x6a, 0x21, 0x01,
+  0x41, 0x0d, 0x21, 0x06, 0x20, 0x05, 0x41, 0x0d, 0x6a, 0x28, 0x00, 0x00,
+  0x21, 0x05, 0x41, 0x0f, 0x21, 0x03, 0x0c, 0x02, 0x0b, 0x02, 0x40, 0x02,
+  0x40, 0x20, 0x03, 0x41, 0x10, 0x4f, 0x0d, 0x00, 0x20, 0x04, 0x21, 0x02,
+  0x20, 0x05, 0x21, 0x01, 0x0c, 0x01, 0x0b, 0x20, 0x04, 0x20, 0x05, 0x2d,
+  0x00, 0x00, 0x3a, 0x00, 0x00, 0x20, 0x04, 0x20, 0x05, 0x28, 0x00, 0x01,
+  0x36, 0x00, 0x01, 0x20, 0x04, 0x20, 0x05, 0x29, 0x00, 0x05, 0x37, 0x00,
+  0x05, 0x20, 0x04, 0x20, 0x05, 0x2f, 0x00, 0x0d, 0x3b, 0x00, 0x0d, 0x20,
+  0x04, 0x20, 0x05, 0x2d, 0x00, 0x0f, 0x3a, 0x00, 0x0f, 0x20, 0x04, 0x41,
+  0x10, 0x6a, 0x21, 0x02, 0x20, 0x05, 0x41, 0x10, 0x6a, 0x21, 0x01, 0x0b,
+  0x20, 0x03, 0x41, 0x08, 0x71, 0x0d, 0x02, 0x0c, 0x03, 0x0b, 0x20, 0x04,
+  0x20, 0x05, 0x28, 0x02, 0x00, 0x22, 0x02, 0x3a, 0x00, 0x00, 0x20, 0x04,
+  0x20, 0x02, 0x41, 0x10, 0x76, 0x3a, 0x00, 0x02, 0x20, 0x04, 0x20, 0x02,
+  0x41, 0x08, 0x76, 0x3a, 0x00, 0x01, 0x20, 0x04, 0x20, 0x05, 0x41, 0x03,
+  0x6a, 0x28, 0x00, 0x00, 0x36, 0x02, 0x03, 0x20, 0x04, 0x20, 0x05, 0x41,
+  0x07, 0x6a, 0x29, 0x00, 0x00, 0x37, 0x02, 0x07, 0x20, 0x04, 0x41, 0x13,
+  0x6a, 0x21, 0x02, 0x20, 0x05, 0x41, 0x13, 0x6a, 0x21, 0x01, 0x41, 0x0f,
+  0x21, 0x06, 0x20, 0x05, 0x41, 0x0f, 0x6a, 0x28, 0x00, 0x00, 0x21, 0x05,
+  0x41, 0x0d, 0x21, 0x03, 0x0b, 0x20, 0x04, 0x20, 0x06, 0x6a, 0x20, 0x05,
+  0x36, 0x02, 0x00, 0x0b, 0x20, 0x02, 0x20, 0x01, 0x29, 0x00, 0x00, 0x37,
+  0x00, 0x00, 0x20, 0x02, 0x41, 0x08, 0x6a, 0x21, 0x02, 0x20, 0x01, 0x41,
+  0x08, 0x6a, 0x21, 0x01, 0x0b, 0x02, 0x40, 0x20, 0x03, 0x41, 0x04, 0x71,
+  0x45, 0x0d, 0x00, 0x20, 0x02, 0x20, 0x01, 0x28, 0x00, 0x00, 0x36, 0x00,
+  0x00, 0x20, 0x02, 0x41, 0x04, 0x6a, 0x21, 0x02, 0x20, 0x01, 0x41, 0x04,
+  0x6a, 0x21, 0x01, 0x0b, 0x02, 0x40, 0x20, 0x03, 0x41, 0x02, 0x71, 0x45,
+  0x0d, 0x00, 0x20, 0x02, 0x20, 0x01, 0x2f, 0x00, 0x00, 0x3b, 0x00, 0x00,
+  0x20, 0x02, 0x41, 0x02, 0x6a, 0x21, 0x02, 0x20, 0x01, 0x41, 0x02, 0x6a,
+  0x21, 0x01, 0x0b, 0x20, 0x03, 0x41, 0x01, 0x71, 0x45, 0x0d, 0x00, 0x20,
+  0x02, 0x20, 0x01, 0x2d, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x0b, 0x20, 0x00,
+  0x0b, 0x88, 0x03, 0x02, 0x03, 0x7f, 0x01, 0x7e, 0x02, 0x40, 0x20, 0x02,
+  0x41, 0x21, 0x49, 0x0d, 0x00, 0x20, 0x00, 0x20, 0x01, 0x20, 0x02, 0xfc,
+  0x0b, 0x00, 0x20, 0x00, 0x0f, 0x0b, 0x02, 0x40, 0x20, 0x02, 0x45, 0x0d,
+  0x00, 0x20, 0x00, 0x20, 0x01, 0x3a, 0x00, 0x00, 0x20, 0x02, 0x20, 0x00,
+  0x6a, 0x22, 0x03, 0x41, 0x7f, 0x6a, 0x20, 0x01, 0x3a, 0x00, 0x00, 0x20,
+  0x02, 0x41, 0x03, 0x49, 0x0d, 0x00, 0x20, 0x00, 0x20, 0x01, 0x3a, 0x00,
+  0x02, 0x20, 0x00, 0x20, 0x01, 0x3a, 0x00, 0x01, 0x20, 0x03, 0x41, 0x7d,
+  0x6a, 0x20, 0x01, 0x3a, 0x00, 0x00, 0x20, 0x03, 0x41, 0x7e, 0x6a, 0x20,
+  0x01, 0x3a, 0x00, 0x00, 0x20, 0x02, 0x41, 0x07, 0x49, 0x0d, 0x00, 0x20,
+  0x00, 0x20, 0x01, 0x3a, 0x00, 0x03, 0x20, 0x03, 0x41, 0x7c, 0x6a, 0x20,
+  0x01, 0x3a, 0x00, 0x00, 0x20, 0x02, 0x41, 0x09, 0x49, 0x0d, 0x00, 0x20,
+  0x00, 0x41, 0x00, 0x20, 0x00, 0x6b, 0x41, 0x03, 0x71, 0x22, 0x04, 0x6a,
+  0x22, 0x05, 0x20, 0x01, 0x41, 0xff, 0x01, 0x71, 0x41, 0x81, 0x82, 0x84,
+  0x08, 0x6c, 0x22, 0x03, 0x36, 0x02, 0x00, 0x20, 0x05, 0x20, 0x02, 0x20,
+  0x04, 0x6b, 0x41, 0x7c, 0x71, 0x22, 0x01, 0x6a, 0x22, 0x02, 0x41, 0x7c,
+  0x6a, 0x20, 0x03, 0x36, 0x02, 0x00, 0x20, 0x01, 0x41, 0x09, 0x49, 0x0d,
+  0x00, 0x20, 0x05, 0x20, 0x03, 0x36, 0x02, 0x08, 0x20, 0x05, 0x20, 0x03,
+  0x36, 0x02, 0x04, 0x20, 0x02, 0x41, 0x78, 0x6a, 0x20, 0x03, 0x36, 0x02,
+  0x00, 0x20, 0x02, 0x41, 0x74, 0x6a, 0x20, 0x03, 0x36, 0x02, 0x00, 0x20,
+  0x01, 0x41, 0x19, 0x49, 0x0d, 0x00, 0x20, 0x05, 0x20, 0x03, 0x36, 0x02,
+  0x18, 0x20, 0x05, 0x20, 0x03, 0x36, 0x02, 0x14, 0x20, 0x05, 0x20, 0x03,
+  0x36, 0x02, 0x10, 0x20, 0x05, 0x20, 0x03, 0x36, 0x02, 0x0c, 0x20, 0x02,
+  0x41, 0x70, 0x6a, 0x20, 0x03, 0x36, 0x02, 0x00, 0x20, 0x02, 0x41, 0x6c,
+  0x6a, 0x20, 0x03, 0x36, 0x02, 0x00, 0x20, 0x02, 0x41, 0x68, 0x6a, 0x20,
+  0x03, 0x36, 0x02, 0x00, 0x20, 0x02, 0x41, 0x64, 0x6a, 0x20, 0x03, 0x36,
+  0x02, 0x00, 0x20, 0x01, 0x20, 0x05, 0x41, 0x04, 0x71, 0x41, 0x18, 0x72,
+  0x22, 0x02, 0x6b, 0x22, 0x01, 0x41, 0x20, 0x49, 0x0d, 0x00, 0x20, 0x03,
+  0xad, 0x42, 0x81, 0x80, 0x80, 0x80, 0x10, 0x7e, 0x21, 0x06, 0x20, 0x05,
+  0x20, 0x02, 0x6a, 0x21, 0x02, 0x03, 0x40, 0x20, 0x02, 0x20, 0x06, 0x37,
+  0x03, 0x18, 0x20, 0x02, 0x20, 0x06, 0x37, 0x03, 0x10, 0x20, 0x02, 0x20,
+  0x06, 0x37, 0x03, 0x08, 0x20, 0x02, 0x20, 0x06, 0x37, 0x03, 0x00, 0x20,
+  0x02, 0x41, 0x20, 0x6a, 0x21, 0x02, 0x20, 0x01, 0x41, 0x60, 0x6a, 0x22,
+  0x01, 0x41, 0x1f, 0x4b, 0x0d, 0x00, 0x0b, 0x0b, 0x20, 0x00, 0x0b, 0xcc,
+  0x01, 0x01, 0x03, 0x7f, 0x20, 0x00, 0x21, 0x01, 0x02, 0x40, 0x02, 0x40,
+  0x20, 0x00, 0x41, 0x03, 0x71, 0x45, 0x0d, 0x00, 0x02, 0x40, 0x20, 0x00,
+  0x2d, 0x00, 0x00, 0x0d, 0x00, 0x20, 0x00, 0x20, 0x00, 0x6b, 0x0f, 0x0b,
+  0x20, 0x00, 0x41, 0x01, 0x6a, 0x22, 0x01, 0x41, 0x03, 0x71, 0x45, 0x0d,
+  0x00, 0x20, 0x01, 0x2d, 0x00, 0x00, 0x45, 0x0d, 0x01, 0x20, 0x00, 0x41,
+  0x02, 0x6a, 0x22, 0x01, 0x41, 0x03, 0x71, 0x45, 0x0d, 0x00, 0x20, 0x01,
+  0x2d, 0x00, 0x00, 0x45, 0x0d, 0x01, 0x20, 0x00, 0x41, 0x03, 0x6a, 0x22,
+  0x01, 0x41, 0x03, 0x71, 0x45, 0x0d, 0x00, 0x20, 0x01, 0x2d, 0x00, 0x00,
+  0x45, 0x0d, 0x01, 0x20, 0x00, 0x41, 0x04, 0x6a, 0x22, 0x01, 0x41, 0x03,
+  0x71, 0x0d, 0x01, 0x0b, 0x20, 0x01, 0x41, 0x7c, 0x6a, 0x21, 0x02, 0x20,
+  0x01, 0x41, 0x7b, 0x6a, 0x21, 0x01, 0x03, 0x40, 0x20, 0x01, 0x41, 0x04,
+  0x6a, 0x21, 0x01, 0x20, 0x02, 0x41, 0x04, 0x6a, 0x22, 0x02, 0x28, 0x02,
+  0x00, 0x22, 0x03, 0x41, 0x7f, 0x73, 0x20, 0x03, 0x41, 0xff, 0xfd, 0xfb,
+  0x77, 0x6a, 0x71, 0x41, 0x80, 0x81, 0x82, 0x84, 0x78, 0x71, 0x45, 0x0d,
+  0x00, 0x0b, 0x03, 0x40, 0x20, 0x01, 0x41, 0x01, 0x6a, 0x21, 0x01, 0x20,
+  0x02, 0x2d, 0x00, 0x00, 0x21, 0x03, 0x20, 0x02, 0x41, 0x01, 0x6a, 0x21,
+  0x02, 0x20, 0x03, 0x0d, 0x00, 0x0b, 0x0b, 0x20, 0x01, 0x20, 0x00, 0x6b,
+  0x0b, 0x44, 0x00, 0x02, 0x40, 0x20, 0x00, 0x41, 0xff, 0xff, 0x07, 0x4b,
+  0x0d, 0x00, 0x20, 0x00, 0x41, 0x08, 0x76, 0x41, 0x80, 0x80, 0x84, 0x80,
+  0x00, 0x6a, 0x2d, 0x00, 0x00, 0x41, 0x05, 0x74, 0x20, 0x00, 0x41, 0x03,
+  0x76, 0x41, 0x1f, 0x71, 0x72, 0x41, 0x80, 0x80, 0x84, 0x80, 0x00, 0x6a,
+  0x2d, 0x00, 0x00, 0x20, 0x00, 0x41, 0x07, 0x71, 0x76, 0x41, 0x01, 0x71,
+  0x0f, 0x0b, 0x20, 0x00, 0x41, 0xfe, 0xff, 0x0b, 0x49, 0x0b, 0x49, 0x01,
+  0x03, 0x7f, 0x41, 0x00, 0x21, 0x03, 0x02, 0x40, 0x20, 0x02, 0x45, 0x0d,
+  0x00, 0x02, 0x40, 0x03, 0x40, 0x20, 0x00, 0x2d, 0x00, 0x00, 0x22, 0x04,
+  0x20, 0x01, 0x2d, 0x00, 0x00, 0x22, 0x05, 0x47, 0x0d, 0x01, 0x20, 0x01,
+  0x41, 0x01, 0x6a, 0x21, 0x01, 0x20, 0x00, 0x41, 0x01, 0x6a, 0x21, 0x00,
+  0x20, 0x02, 0x41, 0x7f, 0x6a, 0x22, 0x02, 0x0d, 0x00, 0x0c, 0x02, 0x0b,
+  0x0b, 0x20, 0x04, 0x20, 0x05, 0x6b, 0x21, 0x03, 0x0b, 0x20, 0x03, 0x0b,
+  0xf2, 0x02, 0x01, 0x03, 0x7f, 0x20, 0x02, 0x41, 0x00, 0x47, 0x21, 0x03,
+  0x02, 0x40, 0x02, 0x40, 0x02, 0x40, 0x02, 0x40, 0x20, 0x00, 0x41, 0x03,
+  0x71, 0x45, 0x0d, 0x00, 0x20, 0x02, 0x45, 0x0d, 0x00, 0x02, 0x40, 0x20,
+  0x00, 0x2d, 0x00, 0x00, 0x20, 0x01, 0x41, 0xff, 0x01, 0x71, 0x47, 0x0d,
+  0x00, 0x20, 0x00, 0x21, 0x04, 0x20, 0x02, 0x21, 0x05, 0x0c, 0x03, 0x0b,
+  0x20, 0x02, 0x41, 0x7f, 0x6a, 0x22, 0x05, 0x41, 0x00, 0x47, 0x21, 0x03,
+  0x20, 0x00, 0x41, 0x01, 0x6a, 0x22, 0x04, 0x41, 0x03, 0x71, 0x45, 0x0d,
+  0x01, 0x20, 0x05, 0x45, 0x0d, 0x01, 0x20, 0x04, 0x2d, 0x00, 0x00, 0x20,
+  0x01, 0x41, 0xff, 0x01, 0x71, 0x46, 0x0d, 0x02, 0x20, 0x02, 0x41, 0x7e,
+  0x6a, 0x22, 0x05, 0x41, 0x00, 0x47, 0x21, 0x03, 0x20, 0x00, 0x41, 0x02,
+  0x6a, 0x22, 0x04, 0x41, 0x03, 0x71, 0x45, 0x0d, 0x01, 0x20, 0x05, 0x45,
+  0x0d, 0x01, 0x20, 0x04, 0x2d, 0x00, 0x00, 0x20, 0x01, 0x41, 0xff, 0x01,
+  0x71, 0x46, 0x0d, 0x02, 0x20, 0x02, 0x41, 0x7d, 0x6a, 0x22, 0x05, 0x41,
+  0x00, 0x47, 0x21, 0x03, 0x20, 0x00, 0x41, 0x03, 0x6a, 0x22, 0x04, 0x41,
+  0x03, 0x71, 0x45, 0x0d, 0x01, 0x20, 0x05, 0x45, 0x0d, 0x01, 0x20, 0x04,
+  0x2d, 0x00, 0x00, 0x20, 0x01, 0x41, 0xff, 0x01, 0x71, 0x46, 0x0d, 0x02,
+  0x20, 0x00, 0x41, 0x04, 0x6a, 0x21, 0x04, 0x20, 0x02, 0x41, 0x7c, 0x6a,
+  0x22, 0x05, 0x41, 0x00, 0x47, 0x21, 0x03, 0x0c, 0x01, 0x0b, 0x20, 0x02,
+  0x21, 0x05, 0x20, 0x00, 0x21, 0x04, 0x0b, 0x20, 0x03, 0x45, 0x0d, 0x01,
+  0x02, 0x40, 0x20, 0x04, 0x2d, 0x00, 0x00, 0x20, 0x01, 0x41, 0xff, 0x01,
+  0x71, 0x46, 0x0d, 0x00, 0x20, 0x05, 0x41, 0x04, 0x49, 0x0d, 0x00, 0x20,
+  0x01, 0x41, 0xff, 0x01, 0x71, 0x41, 0x81, 0x82, 0x84, 0x08, 0x6c, 0x21,
+  0x00, 0x03, 0x40, 0x20, 0x04, 0x28, 0x02, 0x00, 0x20, 0x00, 0x73, 0x22,
+  0x02, 0x41, 0x7f, 0x73, 0x20, 0x02, 0x41, 0xff, 0xfd, 0xfb, 0x77, 0x6a,
+  0x71, 0x41, 0x80, 0x81, 0x82, 0x84, 0x78, 0x71, 0x0d, 0x02, 0x20, 0x04,
+  0x41, 0x04, 0x6a, 0x21, 0x04, 0x20, 0x05, 0x41, 0x7c, 0x6a, 0x22, 0x05,
+  0x41, 0x03, 0x4b, 0x0d, 0x00, 0x0b, 0x0b, 0x20, 0x05, 0x45, 0x0d, 0x01,
+  0x0b, 0x20, 0x01, 0x41, 0xff, 0x01, 0x71, 0x21, 0x02, 0x03, 0x40, 0x02,
+  0x40, 0x20, 0x04, 0x2d, 0x00, 0x00, 0x20, 0x02, 0x47, 0x0d, 0x00, 0x20,
+  0x04, 0x0f, 0x0b, 0x20, 0x04, 0x41, 0x01, 0x6a, 0x21, 0x04, 0x20, 0x05,
+  0x41, 0x7f, 0x6a, 0x22, 0x05, 0x0d, 0x00, 0x0b, 0x0b, 0x41, 0x00, 0x0b,
+  0x67, 0x01, 0x02, 0x7f, 0x20, 0x01, 0x2d, 0x00, 0x00, 0x21, 0x02, 0x02,
+  0x40, 0x20, 0x00, 0x2d, 0x00, 0x00, 0x22, 0x03, 0x45, 0x0d, 0x00, 0x20,
+  0x03, 0x20, 0x02, 0x41, 0xff, 0x01, 0x71, 0x47, 0x0d, 0x00, 0x20, 0x00,
+  0x41, 0x01, 0x6a, 0x21, 0x00, 0x20, 0x01, 0x41, 0x01, 0x6a, 0x21, 0x01,
+  0x03, 0x40, 0x20, 0x01, 0x2d, 0x00, 0x00, 0x21, 0x02, 0x20, 0x00, 0x2d,
+  0x00, 0x00, 0x22, 0x03, 0x45, 0x0d, 0x01, 0x20, 0x00, 0x41, 0x01, 0x6a,
+  0x21, 0x00, 0x20, 0x01, 0x41, 0x01, 0x6a, 0x21, 0x01, 0x20, 0x03, 0x20,
+  0x02, 0x41, 0xff, 0x01, 0x71, 0x46, 0x0d, 0x00, 0x0b, 0x0b, 0x20, 0x03,
+  0x20, 0x02, 0x41, 0xff, 0x01, 0x71, 0x6b, 0x0b, 0x0c, 0x00, 0x20, 0x00,
+  0x41, 0x00, 0x10, 0x9b, 0x80, 0x80, 0x80, 0x00, 0x0b, 0xbc, 0x02, 0x01,
+  0x06, 0x7f, 0x02, 0x40, 0x20, 0x00, 0x41, 0xff, 0xff, 0x07, 0x4b, 0x0d,
+  0x00, 0x20, 0x00, 0x20, 0x00, 0x41, 0xff, 0x01, 0x71, 0x22, 0x02, 0x41,
+  0x03, 0x6e, 0x22, 0x03, 0x41, 0x03, 0x6c, 0x6b, 0x41, 0xff, 0x01, 0x71,
+  0x41, 0x02, 0x74, 0x41, 0xc0, 0x9e, 0x84, 0x80, 0x00, 0x6a, 0x28, 0x02,
+  0x00, 0x20, 0x00, 0x41, 0x08, 0x76, 0x22, 0x04, 0x41, 0xa0, 0xa9, 0x84,
+  0x80, 0x00, 0x6a, 0x2d, 0x00, 0x00, 0x41, 0xd6, 0x00, 0x6c, 0x20, 0x03,
+  0x6a, 0x41, 0xa0, 0xa9, 0x84, 0x80, 0x00, 0x6a, 0x2d, 0x00, 0x00, 0x6c,
+  0x41, 0x0b, 0x76, 0x41, 0x06, 0x70, 0x20, 0x04, 0x41, 0x90, 0xbe, 0x84,
+  0x80, 0x00, 0x6a, 0x2d, 0x00, 0x00, 0x6a, 0x41, 0x02, 0x74, 0x41, 0xd0,
+  0x9e, 0x84, 0x80, 0x00, 0x6a, 0x28, 0x02, 0x00, 0x22, 0x03, 0x41, 0x08,
+  0x75, 0x21, 0x04, 0x02, 0x40, 0x20, 0x03, 0x41, 0xff, 0x01, 0x71, 0x22,
+  0x03, 0x41, 0x01, 0x4b, 0x0d, 0x00, 0x20, 0x04, 0x41, 0x00, 0x20, 0x03,
+  0x20, 0x01, 0x73, 0x6b, 0x71, 0x20, 0x00, 0x6a, 0x0f, 0x0b, 0x20, 0x04,
+  0x41, 0xff, 0x01, 0x71, 0x22, 0x03, 0x45, 0x0d, 0x00, 0x20, 0x04, 0x41,
+  0x08, 0x76, 0x21, 0x04, 0x03, 0x40, 0x02, 0x40, 0x20, 0x02, 0x20, 0x03,
+  0x41, 0x01, 0x76, 0x22, 0x05, 0x20, 0x04, 0x6a, 0x22, 0x06, 0x41, 0x01,
+  0x74, 0x41, 0x90, 0xa6, 0x84, 0x80, 0x00, 0x6a, 0x2d, 0x00, 0x00, 0x22,
+  0x07, 0x47, 0x0d, 0x00, 0x02, 0x40, 0x20, 0x06, 0x41, 0x01, 0x74, 0x41,
+  0x91, 0xa6, 0x84, 0x80, 0x00, 0x6a, 0x2d, 0x00, 0x00, 0x41, 0x02, 0x74,
+  0x41, 0xd0, 0x9e, 0x84, 0x80, 0x00, 0x6a, 0x28, 0x02, 0x00, 0x22, 0x03,
+  0x41, 0xff, 0x01, 0x71, 0x22, 0x04, 0x41, 0x01, 0x4b, 0x0d, 0x00, 0x20,
+  0x03, 0x41, 0x08, 0x75, 0x41, 0x00, 0x20, 0x04, 0x20, 0x01, 0x73, 0x6b,
+  0x71, 0x20, 0x00, 0x6a, 0x0f, 0x0b, 0x41, 0x7f, 0x41, 0x01, 0x20, 0x01,
+  0x1b, 0x20, 0x00, 0x6a, 0x0f, 0x0b, 0x20, 0x04, 0x20, 0x06, 0x20, 0x02,
+  0x20, 0x07, 0x49, 0x22, 0x07, 0x1b, 0x21, 0x04, 0x20, 0x05, 0x20, 0x03,
+  0x20, 0x05, 0x6b, 0x20, 0x07, 0x1b, 0x22, 0x03, 0x0d, 0x00, 0x0b, 0x0b,
+  0x20, 0x00, 0x0b, 0x0c, 0x00, 0x20, 0x00, 0x41, 0x01, 0x10, 0x9b, 0x80,
+  0x80, 0x80, 0x00, 0x0b, 0x7b, 0x01, 0x02, 0x7f, 0x02, 0x40, 0x20, 0x02,
+  0x0d, 0x00, 0x41, 0x00, 0x0f, 0x0b, 0x02, 0x40, 0x02, 0x40, 0x20, 0x00,
+  0x2d, 0x00, 0x00, 0x22, 0x03, 0x45, 0x0d, 0x00, 0x20, 0x00, 0x41, 0x01,
+  0x6a, 0x21, 0x00, 0x20, 0x02, 0x41, 0x7f, 0x6a, 0x21, 0x02, 0x03, 0x40,
+  0x20, 0x03, 0x41, 0xff, 0x01, 0x71, 0x20, 0x01, 0x2d, 0x00, 0x00, 0x22,
+  0x04, 0x47, 0x0d, 0x02, 0x20, 0x04, 0x45, 0x0d, 0x02, 0x20, 0x02, 0x41,
+  0x00, 0x46, 0x0d, 0x02, 0x20, 0x02, 0x41, 0x7f, 0x6a, 0x21, 0x02, 0x20,
+  0x01, 0x41, 0x01, 0x6a, 0x21, 0x01, 0x20, 0x00, 0x2d, 0x00, 0x00, 0x21,
+  0x03, 0x20, 0x00, 0x41, 0x01, 0x6a, 0x21, 0x00, 0x20, 0x03, 0x0d, 0x00,
+  0x0b, 0x0b, 0x41, 0x00, 0x21, 0x03, 0x0b, 0x20, 0x03, 0x41, 0xff, 0x01,
+  0x71, 0x20, 0x01, 0x2d, 0x00, 0x00, 0x6b, 0x0b, 0x0d, 0x00, 0x20, 0x00,
+  0x10, 0x9a, 0x80, 0x80, 0x80, 0x00, 0x20, 0x00, 0x47, 0x0b, 0xbf, 0x09,
+  0x01, 0x04, 0x7f, 0x02, 0x40, 0x02, 0x40, 0x02, 0x40, 0x20, 0x02, 0x41,
+  0x21, 0x4f, 0x0d, 0x00, 0x20, 0x00, 0x20, 0x01, 0x46, 0x0d, 0x02, 0x20,
+  0x01, 0x20, 0x00, 0x20, 0x02, 0x6a, 0x22, 0x03, 0x6b, 0x41, 0x00, 0x20,
+  0x02, 0x41, 0x01, 0x74, 0x6b, 0x4b, 0x0d, 0x01, 0x0b, 0x20, 0x00, 0x20,
+  0x01, 0x20, 0x02, 0xfc, 0x0a, 0x00, 0x00, 0x0c, 0x01, 0x0b, 0x20, 0x01,
+  0x20, 0x00, 0x73, 0x41, 0x03, 0x71, 0x21, 0x04, 0x02, 0x40, 0x02, 0x40,
+  0x02, 0x40, 0x20, 0x00, 0x20, 0x01, 0x4f, 0x0d, 0x00, 0x02, 0x40, 0x20,
+  0x04, 0x45, 0x0d, 0x00, 0x20, 0x02, 0x21, 0x05, 0x20, 0x00, 0x21, 0x03,
+  0x0c, 0x03, 0x0b, 0x02, 0x40, 0x20, 0x00, 0x41, 0x03, 0x71, 0x0d, 0x00,
+  0x20, 0x02, 0x21, 0x05, 0x20, 0x00, 0x21, 0x03, 0x0c, 0x02, 0x0b, 0x20,
+  0x02, 0x45, 0x0d, 0x03, 0x20, 0x00, 0x20, 0x01, 0x2d, 0x00, 0x00, 0x3a,
+  0x00, 0x00, 0x20, 0x02, 0x41, 0x7f, 0x6a, 0x21, 0x05, 0x02, 0x40, 0x20,
+  0x00, 0x41, 0x01, 0x6a, 0x22, 0x03, 0x41, 0x03, 0x71, 0x0d, 0x00, 0x20,
+  0x01, 0x41, 0x01, 0x6a, 0x21, 0x01, 0x0c, 0x02, 0x0b, 0x20, 0x05, 0x45,
+  0x0d, 0x03, 0x20, 0x00, 0x20, 0x01, 0x2d, 0x00, 0x01, 0x3a, 0x00, 0x01,
+  0x20, 0x02, 0x41, 0x7e, 0x6a, 0x21, 0x05, 0x02, 0x40, 0x20, 0x00, 0x41,
+  0x02, 0x6a, 0x22, 0x03, 0x41, 0x03, 0x71, 0x0d, 0x00, 0x20, 0x01, 0x41,
+  0x02, 0x6a, 0x21, 0x01, 0x0c, 0x02, 0x0b, 0x20, 0x05, 0x45, 0x0d, 0x03,
+  0x20, 0x00, 0x20, 0x01, 0x2d, 0x00, 0x02, 0x3a, 0x00, 0x02, 0x20, 0x02,
+  0x41, 0x7d, 0x6a, 0x21, 0x05, 0x02, 0x40, 0x20, 0x00, 0x41, 0x03, 0x6a,
+  0x22, 0x03, 0x41, 0x03, 0x71, 0x0d, 0x00, 0x20, 0x01, 0x41, 0x03, 0x6a,
+  0x21, 0x01, 0x0c, 0x02, 0x0b, 0x20, 0x05, 0x45, 0x0d, 0x03, 0x20, 0x00,
+  0x20, 0x01, 0x2d, 0x00, 0x03, 0x3a, 0x00, 0x03, 0x20, 0x00, 0x41, 0x04,
+  0x6a, 0x21, 0x03, 0x20, 0x01, 0x41, 0x04, 0x6a, 0x21, 0x01, 0x20, 0x02,
+  0x41, 0x7c, 0x6a, 0x21, 0x05, 0x0c, 0x01, 0x0b, 0x02, 0x40, 0x20, 0x04,
+  0x0d, 0x00, 0x02, 0x40, 0x20, 0x03, 0x41, 0x03, 0x71, 0x45, 0x0d, 0x00,
+  0x20, 0x02, 0x45, 0x0d, 0x04, 0x20, 0x00, 0x20, 0x02, 0x41, 0x7f, 0x6a,
+  0x22, 0x03, 0x6a, 0x22, 0x04, 0x20, 0x01, 0x20, 0x03, 0x6a, 0x2d, 0x00,
+  0x00, 0x3a, 0x00, 0x00, 0x02, 0x40, 0x20, 0x04, 0x41, 0x03, 0x71, 0x0d,
+  0x00, 0x20, 0x03, 0x21, 0x02, 0x0c, 0x01, 0x0b, 0x20, 0x03, 0x45, 0x0d,
+  0x04, 0x20, 0x00, 0x20, 0x02, 0x41, 0x7e, 0x6a, 0x22, 0x03, 0x6a, 0x22,
+  0x04, 0x20, 0x01, 0x20, 0x03, 0x6a, 0x2d, 0x00, 0x00, 0x3a, 0x00, 0x00,
+  0x02, 0x40, 0x20, 0x04, 0x41, 0x03, 0x71, 0x0d, 0x00, 0x20, 0x03, 0x21,
+  0x02, 0x0c, 0x01, 0x0b, 0x20, 0x03, 0x45, 0x0d, 0x04, 0x20, 0x00, 0x20,
+  0x02, 0x41, 0x7d, 0x6a, 0x22, 0x03, 0x6a, 0x22, 0x04, 0x20, 0x01, 0x20,
+  0x03, 0x6a, 0x2d, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x02, 0x40, 0x20, 0x04,
+  0x41, 0x03, 0x71, 0x0d, 0x00, 0x20, 0x03, 0x21, 0x02, 0x0c, 0x01, 0x0b,
+  0x20, 0x03, 0x45, 0x0d, 0x04, 0x20, 0x00, 0x20, 0x02, 0x41, 0x7c, 0x6a,
+  0x22, 0x02, 0x6a, 0x20, 0x01, 0x20, 0x02, 0x6a, 0x2d, 0x00, 0x00, 0x3a,
+  0x00, 0x00, 0x0b, 0x20, 0x02, 0x41, 0x04, 0x49, 0x0d, 0x00, 0x02, 0x40,
+  0x20, 0x02, 0x41, 0x7c, 0x6a, 0x22, 0x06, 0x41, 0x02, 0x76, 0x41, 0x01,
+  0x6a, 0x41, 0x03, 0x71, 0x22, 0x03, 0x45, 0x0d, 0x00, 0x20, 0x01, 0x41,
+  0x7c, 0x6a, 0x21, 0x04, 0x20, 0x00, 0x41, 0x7c, 0x6a, 0x21, 0x05, 0x03,
+  0x40, 0x20, 0x05, 0x20, 0x02, 0x6a, 0x20, 0x04, 0x20, 0x02, 0x6a, 0x28,
+  0x02, 0x00, 0x36, 0x02, 0x00, 0x20, 0x02, 0x41, 0x7c, 0x6a, 0x21, 0x02,
+  0x20, 0x03, 0x41, 0x7f, 0x6a, 0x22, 0x03, 0x0d, 0x00, 0x0b, 0x0b, 0x20,
+  0x06, 0x41, 0x0c, 0x49, 0x0d, 0x00, 0x20, 0x01, 0x41, 0x70, 0x6a, 0x21,
+  0x05, 0x20, 0x00, 0x41, 0x70, 0x6a, 0x21, 0x06, 0x03, 0x40, 0x20, 0x06,
+  0x20, 0x02, 0x6a, 0x22, 0x03, 0x41, 0x0c, 0x6a, 0x20, 0x05, 0x20, 0x02,
+  0x6a, 0x22, 0x04, 0x41, 0x0c, 0x6a, 0x28, 0x02, 0x00, 0x36, 0x02, 0x00,
+  0x20, 0x03, 0x41, 0x08, 0x6a, 0x20, 0x04, 0x41, 0x08, 0x6a, 0x28, 0x02,
+  0x00, 0x36, 0x02, 0x00, 0x20, 0x03, 0x41, 0x04, 0x6a, 0x20, 0x04, 0x41,
+  0x04, 0x6a, 0x28, 0x02, 0x00, 0x36, 0x02, 0x00, 0x20, 0x03, 0x20, 0x04,
+  0x28, 0x02, 0x00, 0x36, 0x02, 0x00, 0x20, 0x02, 0x41, 0x70, 0x6a, 0x22,
+  0x02, 0x41, 0x03, 0x4b, 0x0d, 0x00, 0x0b, 0x0b, 0x20, 0x02, 0x45, 0x0d,
+  0x02, 0x20, 0x02, 0x21, 0x03, 0x02, 0x40, 0x20, 0x02, 0x41, 0x03, 0x71,
+  0x22, 0x04, 0x45, 0x0d, 0x00, 0x20, 0x01, 0x41, 0x7f, 0x6a, 0x21, 0x05,
+  0x20, 0x00, 0x41, 0x7f, 0x6a, 0x21, 0x06, 0x20, 0x02, 0x21, 0x03, 0x03,
+  0x40, 0x20, 0x06, 0x20, 0x03, 0x6a, 0x20, 0x05, 0x20, 0x03, 0x6a, 0x2d,
+  0x00, 0x00, 0x3a, 0x00, 0x00, 0x20, 0x03, 0x41, 0x7f, 0x6a, 0x21, 0x03,
+  0x20, 0x04, 0x41, 0x7f, 0x6a, 0x22, 0x04, 0x0d, 0x00, 0x0b, 0x0b, 0x20,
+  0x02, 0x41, 0x04, 0x49, 0x0d, 0x02, 0x20, 0x01, 0x41, 0x7c, 0x6a, 0x21,
+  0x04, 0x20, 0x00, 0x41, 0x7c, 0x6a, 0x21, 0x05, 0x03, 0x40, 0x20, 0x05,
+  0x20, 0x03, 0x6a, 0x22, 0x01, 0x41, 0x03, 0x6a, 0x20, 0x04, 0x20, 0x03,
+  0x6a, 0x22, 0x02, 0x41, 0x03, 0x6a, 0x2d, 0x00, 0x00, 0x3a, 0x00, 0x00,
+  0x20, 0x01, 0x41, 0x02, 0x6a, 0x20, 0x02, 0x41, 0x02, 0x6a, 0x2d, 0x00,
+  0x00, 0x3a, 0x00, 0x00, 0x20, 0x01, 0x41, 0x01, 0x6a, 0x20, 0x02, 0x41,
+  0x01, 0x6a, 0x2d, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x20, 0x01, 0x20, 0x02,
+  0x2d, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x20, 0x03, 0x41, 0x7c, 0x6a, 0x22,
+  0x03, 0x0d, 0x00, 0x0c, 0x03, 0x0b, 0x0b, 0x20, 0x05, 0x41, 0x04, 0x49,
+  0x0d, 0x00, 0x02, 0x40, 0x20, 0x05, 0x41, 0x7c, 0x6a, 0x22, 0x04, 0x41,
+  0x02, 0x76, 0x41, 0x01, 0x6a, 0x41, 0x07, 0x71, 0x22, 0x02, 0x45, 0x0d,
+  0x00, 0x20, 0x05, 0x20, 0x02, 0x41, 0x02, 0x74, 0x6b, 0x21, 0x05, 0x03,
+  0x40, 0x20, 0x03, 0x20, 0x01, 0x28, 0x02, 0x00, 0x36, 0x02, 0x00, 0x20,
+  0x01, 0x41, 0x04, 0x6a, 0x21, 0x01, 0x20, 0x03, 0x41, 0x04, 0x6a, 0x21,
+  0x03, 0x20, 0x02, 0x41, 0x7f, 0x6a, 0x22, 0x02, 0x0d, 0x00, 0x0b, 0x0b,
+  0x20, 0x04, 0x41, 0x1c, 0x49, 0x0d, 0x00, 0x03, 0x40, 0x20, 0x03, 0x20,
+  0x01, 0x28, 0x02, 0x00, 0x36, 0x02, 0x00, 0x20, 0x03, 0x20, 0x01, 0x28,
+  0x02, 0x04, 0x36, 0x02, 0x04, 0x20, 0x03, 0x20, 0x01, 0x28, 0x02, 0x08,
+  0x36, 0x02, 0x08, 0x20, 0x03, 0x20, 0x01, 0x28, 0x02, 0x0c, 0x36, 0x02,
+  0x0c, 0x20, 0x03, 0x20, 0x01, 0x28, 0x02, 0x10, 0x36, 0x02, 0x10, 0x20,
+  0x03, 0x20, 0x01, 0x28, 0x02, 0x14, 0x36, 0x02, 0x14, 0x20, 0x03, 0x20,
+  0x01, 0x28, 0x02, 0x18, 0x36, 0x02, 0x18, 0x20, 0x03, 0x20, 0x01, 0x28,
+  0x02, 0x1c, 0x36, 0x02, 0x1c, 0x20, 0x01, 0x41, 0x20, 0x6a, 0x21, 0x01,
+  0x20, 0x03, 0x41, 0x20, 0x6a, 0x21, 0x03, 0x20, 0x05, 0x41, 0x60, 0x6a,
+  0x22, 0x05, 0x41, 0x03, 0x4b, 0x0d, 0x00, 0x0b, 0x0b, 0x20, 0x05, 0x45,
+  0x0d, 0x00, 0x02, 0x40, 0x02, 0x40, 0x20, 0x05, 0x41, 0x07, 0x71, 0x22,
+  0x02, 0x0d, 0x00, 0x20, 0x05, 0x21, 0x04, 0x0c, 0x01, 0x0b, 0x20, 0x05,
+  0x41, 0x78, 0x71, 0x21, 0x04, 0x03, 0x40, 0x20, 0x03, 0x20, 0x01, 0x2d,
+  0x00, 0x00, 0x3a, 0x00, 0x00, 0x20, 0x03, 0x41, 0x01, 0x6a, 0x21, 0x03,
+  0x20, 0x01, 0x41, 0x01, 0x6a, 0x21, 0x01, 0x20, 0x02, 0x41, 0x7f, 0x6a,
+  0x22, 0x02, 0x0d, 0x00, 0x0b, 0x0b, 0x20, 0x05, 0x41, 0x08, 0x49, 0x0d,
+  0x00, 0x03, 0x40, 0x20, 0x03, 0x20, 0x01, 0x2d, 0x00, 0x00, 0x3a, 0x00,
+  0x00, 0x20, 0x03, 0x20, 0x01, 0x2d, 0x00, 0x01, 0x3a, 0x00, 0x01, 0x20,
+  0x03, 0x20, 0x01, 0x2d, 0x00, 0x02, 0x3a, 0x00, 0x02, 0x20, 0x03, 0x20,
+  0x01, 0x2d, 0x00, 0x03, 0x3a, 0x00, 0x03, 0x20, 0x03, 0x20, 0x01, 0x2d,
+  0x00, 0x04, 0x3a, 0x00, 0x04, 0x20, 0x03, 0x20, 0x01, 0x2d, 0x00, 0x05,
+  0x3a, 0x00, 0x05, 0x20, 0x03, 0x20, 0x01, 0x2d, 0x00, 0x06, 0x3a, 0x00,
+  0x06, 0x20, 0x03, 0x20, 0x01, 0x2d, 0x00, 0x07, 0x3a, 0x00, 0x07, 0x20,
+  0x03, 0x41, 0x08, 0x6a, 0x21, 0x03, 0x20, 0x01, 0x41, 0x08, 0x6a, 0x21,
+  0x01, 0x20, 0x04, 0x41, 0x78, 0x6a, 0x22, 0x04, 0x0d, 0x00, 0x0b, 0x0b,
+  0x20, 0x00, 0x0b, 0x0d, 0x00, 0x20, 0x00, 0x10, 0x9c, 0x80, 0x80, 0x80,
+  0x00, 0x20, 0x00, 0x47, 0x0b, 0x0d, 0x00, 0x20, 0x00, 0x41, 0x20, 0x46,
+  0x20, 0x00, 0x41, 0x09, 0x46, 0x72, 0x0b, 0x0a, 0x00, 0x20, 0x00, 0x10,
+  0xa1, 0x80, 0x80, 0x80, 0x00, 0x0b, 0x0a, 0x00, 0x20, 0x00, 0x41, 0x50,
+  0x6a, 0x41, 0x0a, 0x49, 0x0b, 0x4d, 0x01, 0x02, 0x7f, 0x20, 0x00, 0x20,
+  0x00, 0x10, 0x95, 0x80, 0x80, 0x80, 0x00, 0x6a, 0x21, 0x03, 0x02, 0x40,
+  0x20, 0x02, 0x45, 0x0d, 0x00, 0x03, 0x40, 0x20, 0x01, 0x2d, 0x00, 0x00,
+  0x22, 0x04, 0x45, 0x0d, 0x01, 0x20, 0x03, 0x20, 0x04, 0x3a, 0x00, 0x00,
+  0x20, 0x03, 0x41, 0x01, 0x6a, 0x21, 0x03, 0x20, 0x01, 0x41, 0x01, 0x6a,
+  0x21, 0x01, 0x20, 0x02, 0x41, 0x7f, 0x6a, 0x22, 0x02, 0x0d, 0x00, 0x0b,
+  0x0b, 0x20, 0x03, 0x41, 0x00, 0x3a, 0x00, 0x00, 0x20, 0x00, 0x0b, 0xef,
+  0x03, 0x01, 0x04, 0x7f, 0x02, 0x40, 0x02, 0x40, 0x02, 0x40, 0x02, 0x40,
+  0x02, 0x40, 0x20, 0x01, 0x20, 0x00, 0x73, 0x41, 0x03, 0x71, 0x45, 0x0d,
+  0x00, 0x20, 0x00, 0x21, 0x03, 0x0c, 0x01, 0x0b, 0x20, 0x02, 0x41, 0x00,
+  0x47, 0x21, 0x04, 0x02, 0x40, 0x02, 0x40, 0x20, 0x01, 0x41, 0x03, 0x71,
+  0x0d, 0x00, 0x20, 0x00, 0x21, 0x03, 0x0c, 0x01, 0x0b, 0x02, 0x40, 0x20,
+  0x02, 0x0d, 0x00, 0x20, 0x00, 0x21, 0x03, 0x0c, 0x01, 0x0b, 0x20, 0x00,
+  0x20, 0x01, 0x2d, 0x00, 0x00, 0x22, 0x03, 0x3a, 0x00, 0x00, 0x02, 0x40,
+  0x20, 0x03, 0x0d, 0x00, 0x20, 0x00, 0x21, 0x03, 0x20, 0x02, 0x21, 0x05,
+  0x0c, 0x05, 0x0b, 0x20, 0x00, 0x41, 0x01, 0x6a, 0x21, 0x03, 0x20, 0x02,
+  0x41, 0x7f, 0x6a, 0x22, 0x05, 0x41, 0x00, 0x47, 0x21, 0x04, 0x02, 0x40,
+  0x20, 0x01, 0x41, 0x01, 0x6a, 0x22, 0x06, 0x41, 0x03, 0x71, 0x45, 0x0d,
+  0x00, 0x20, 0x05, 0x45, 0x0d, 0x00, 0x20, 0x03, 0x20, 0x06, 0x2d, 0x00,
+  0x00, 0x22, 0x04, 0x3a, 0x00, 0x00, 0x20, 0x04, 0x45, 0x0d, 0x05, 0x20,
+  0x00, 0x41, 0x02, 0x6a, 0x21, 0x03, 0x20, 0x02, 0x41, 0x7e, 0x6a, 0x22,
+  0x05, 0x41, 0x00, 0x47, 0x21, 0x04, 0x02, 0x40, 0x20, 0x01, 0x41, 0x02,
+  0x6a, 0x22, 0x06, 0x41, 0x03, 0x71, 0x45, 0x0d, 0x00, 0x20, 0x05, 0x45,
+  0x0d, 0x00, 0x20, 0x03, 0x20, 0x06, 0x2d, 0x00, 0x00, 0x22, 0x04, 0x3a,
+  0x00, 0x00, 0x20, 0x04, 0x45, 0x0d, 0x06, 0x20, 0x00, 0x41, 0x03, 0x6a,
+  0x21, 0x03, 0x20, 0x02, 0x41, 0x7d, 0x6a, 0x22, 0x05, 0x41, 0x00, 0x47,
+  0x21, 0x04, 0x02, 0x40, 0x20, 0x01, 0x41, 0x03, 0x6a, 0x22, 0x06, 0x41,
+  0x03, 0x71, 0x45, 0x0d, 0x00, 0x20, 0x05, 0x45, 0x0d, 0x00, 0x20, 0x03,
+  0x20, 0x06, 0x2d, 0x00, 0x00, 0x22, 0x04, 0x3a, 0x00, 0x00, 0x20, 0x04,
+  0x45, 0x0d, 0x07, 0x20, 0x00, 0x41, 0x04, 0x6a, 0x21, 0x03, 0x20, 0x01,
+  0x41, 0x04, 0x6a, 0x21, 0x01, 0x20, 0x02, 0x41, 0x7c, 0x6a, 0x22, 0x02,
+  0x41, 0x00, 0x47, 0x21, 0x04, 0x0c, 0x03, 0x0b, 0x20, 0x06, 0x21, 0x01,
+  0x20, 0x05, 0x21, 0x02, 0x0c, 0x02, 0x0b, 0x20, 0x06, 0x21, 0x01, 0x20,
+  0x05, 0x21, 0x02, 0x0c, 0x01, 0x0b, 0x20, 0x06, 0x21, 0x01, 0x20, 0x05,
+  0x21, 0x02, 0x0b, 0x20, 0x04, 0x45, 0x0d, 0x02, 0x02, 0x40, 0x20, 0x01,
+  0x2d, 0x00, 0x00, 0x0d, 0x00, 0x20, 0x02, 0x21, 0x05, 0x0c, 0x04, 0x0b,
+  0x20, 0x02, 0x41, 0x04, 0x49, 0x0d, 0x00, 0x03, 0x40, 0x20, 0x01, 0x28,
+  0x02, 0x00, 0x22, 0x00, 0x41, 0x7f, 0x73, 0x20, 0x00, 0x41, 0xff, 0xfd,
+  0xfb, 0x77, 0x6a, 0x71, 0x41, 0x80, 0x81, 0x82, 0x84, 0x78, 0x71, 0x0d,
+  0x02, 0x20, 0x03, 0x20, 0x00, 0x36, 0x02, 0x00, 0x20, 0x03, 0x41, 0x04,
+  0x6a, 0x21, 0x03, 0x20, 0x01, 0x41, 0x04, 0x6a, 0x21, 0x01, 0x20, 0x02,
+  0x41, 0x7c, 0x6a, 0x22, 0x02, 0x41, 0x03, 0x4b, 0x0d, 0x00, 0x0b, 0x0b,
+  0x20, 0x02, 0x45, 0x0d, 0x01, 0x0b, 0x03, 0x40, 0x20, 0x03, 0x20, 0x01,
+  0x2d, 0x00, 0x00, 0x22, 0x00, 0x3a, 0x00, 0x00, 0x02, 0x40, 0x20, 0x00,
+  0x0d, 0x00, 0x20, 0x02, 0x21, 0x05, 0x0c, 0x03, 0x0b, 0x20, 0x03, 0x41,
+  0x01, 0x6a, 0x21, 0x03, 0x20, 0x01, 0x41, 0x01, 0x6a, 0x21, 0x01, 0x20,
+  0x02, 0x41, 0x7f, 0x6a, 0x22, 0x02, 0x0d, 0x00, 0x0b, 0x0b, 0x41, 0x00,
+  0x21, 0x05, 0x0b, 0x20, 0x03, 0x41, 0x00, 0x20, 0x05, 0x10, 0x94, 0x80,
+  0x80, 0x80, 0x00, 0x0b, 0x11, 0x00, 0x20, 0x00, 0x20, 0x01, 0x20, 0x02,
+  0x10, 0xa5, 0x80, 0x80, 0x80, 0x00, 0x1a, 0x20, 0x00, 0x0b, 0x17, 0x00,
+  0x20, 0x00, 0x41, 0x50, 0x6a, 0x41, 0x0a, 0x49, 0x20, 0x00, 0x41, 0x20,
+  0x72, 0x41, 0x9f, 0x7f, 0x6a, 0x41, 0x06, 0x49, 0x72, 0x0b, 0x2a, 0x01,
+  0x03, 0x7f, 0x41, 0x00, 0x21, 0x01, 0x03, 0x40, 0x20, 0x00, 0x20, 0x01,
+  0x6a, 0x21, 0x02, 0x20, 0x01, 0x41, 0x04, 0x6a, 0x22, 0x03, 0x21, 0x01,
+  0x20, 0x02, 0x28, 0x02, 0x00, 0x0d, 0x00, 0x0b, 0x20, 0x03, 0x41, 0x7c,
+  0x6a, 0x41, 0x02, 0x75, 0x0b, 0x45, 0x01, 0x01, 0x7f, 0x02, 0x40, 0x20,
+  0x01, 0x45, 0x0d, 0x00, 0x20, 0x00, 0x41, 0x7c, 0x6a, 0x21, 0x00, 0x02,
+  0x40, 0x03, 0x40, 0x20, 0x00, 0x41, 0x04, 0x6a, 0x22, 0x00, 0x28, 0x02,
+  0x00, 0x22, 0x02, 0x45, 0x0d, 0x01, 0x20, 0x02, 0x20, 0x01, 0x47, 0x0d,
+  0x00, 0x0b, 0x0b, 0x20, 0x00, 0x41, 0x00, 0x20, 0x02, 0x1b, 0x0f, 0x0b,
+  0x20, 0x00, 0x20, 0x00, 0x10, 0xa8, 0x80, 0x80, 0x80, 0x00, 0x41, 0x02,
+  0x74, 0x6a, 0x0b, 0x1d, 0x00, 0x02, 0x40, 0x20, 0x00, 0x0d, 0x00, 0x41,
+  0x00, 0x0f, 0x0b, 0x41, 0x90, 0xc2, 0x84, 0x80, 0x00, 0x20, 0x00, 0x10,
+  0xa9, 0x80, 0x80, 0x80, 0x00, 0x41, 0x00, 0x47, 0x0b, 0x24, 0x01, 0x01,
+  0x7f, 0x41, 0x01, 0x21, 0x01, 0x02, 0x40, 0x20, 0x00, 0x41, 0x50, 0x6a,
+  0x41, 0x0a, 0x49, 0x0d, 0x00, 0x20, 0x00, 0x10, 0x96, 0x80, 0x80, 0x80,
+  0x00, 0x41, 0x00, 0x47, 0x21, 0x01, 0x0b, 0x20, 0x01, 0x0b, 0x0b, 0xf1,
+  0x42, 0x01, 0x00, 0x41, 0x80, 0x80, 0x04, 0x0b, 0xe8, 0x42, 0x12, 0x11,
+  0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e,
+  0x1f, 0x20, 0x21, 0x11, 0x22, 0x23, 0x24, 0x11, 0x25, 0x26, 0x27, 0x28,
+  0x29, 0x2a, 0x2b, 0x2c, 0x11, 0x2d, 0x2e, 0x2f, 0x10, 0x10, 0x30, 0x10,
+  0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x31, 0x32, 0x33, 0x10, 0x34, 0x35,
+  0x10, 0x10, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
+  0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
+  0x11, 0x11, 0x11, 0x36, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
+  0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
+  0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
+  0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
+  0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
+  0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
+  0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
+  0x11, 0x37, 0x11, 0x11, 0x11, 0x11, 0x38, 0x11, 0x39, 0x3a, 0x3b, 0x3c,
+  0x3d, 0x3e, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
+  0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
+  0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
+  0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x3f, 0x10, 0x10,
+  0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+  0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+  0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x11, 0x40, 0x41, 0x11, 0x42,
+  0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x11, 0x4b, 0x4c, 0x4d,
+  0x4e, 0x4f, 0x50, 0x51, 0x10, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
+  0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x10, 0x5e, 0x5f, 0x60, 0x10, 0x11, 0x11,
+  0x11, 0x61, 0x62, 0x63, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+  0x10, 0x10, 0x11, 0x11, 0x11, 0x11, 0x64, 0x10, 0x10, 0x10, 0x10, 0x10,
+  0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x11, 0x11,
+  0x65, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+  0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+  0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x11, 0x11,
+  0x66, 0x67, 0x10, 0x10, 0x68, 0x69, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
+  0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
+  0x11, 0x11, 0x11, 0x11, 0x11, 0x6a, 0x11, 0x11, 0x6b, 0x10, 0x10, 0x10,
+  0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+  0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+  0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x11, 0x6c,
+  0x6d, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x6e, 0x10,
+  0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+  0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x6f, 0x70,
+  0x71, 0x72, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x73, 0x74,
+  0x75, 0x10, 0x10, 0x10, 0x10, 0x10, 0x76, 0x77, 0x10, 0x10, 0x10, 0x10,
+  0x78, 0x10, 0x10, 0x79, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+  0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0x07, 0xfe, 0xff,
+  0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x20, 0x04, 0xff, 0xff,
+  0x7f, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0xff, 0x03, 0x00, 0x1f, 0x50,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xdf, 0xbc, 0x40, 0xd7, 0xff, 0xff, 0xfb, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0x03, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xfe, 0xff, 0xff, 0xff, 0x7f, 0x02, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01,
+  0x00, 0x00, 0x00, 0x00, 0xff, 0xbf, 0xb6, 0x00, 0xff, 0xff, 0xff, 0x87,
+  0x07, 0x00, 0x00, 0x00, 0xff, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xfe, 0xff, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xef, 0x1f, 0xfe, 0xe1, 0xff, 0x9f, 0x00, 0x00,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xe0, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0x07, 0x30, 0x04, 0xff, 0xff, 0xff, 0xfc, 0xff, 0x1f,
+  0x00, 0x00, 0xff, 0xff, 0xff, 0x01, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xff, 0xff, 0xdf, 0x3f, 0x00, 0x00, 0xf0, 0xff, 0xf8, 0x03,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xff, 0xdf,
+  0xe1, 0xff, 0xcf, 0xff, 0xfe, 0xff, 0xef, 0x9f, 0xf9, 0xff, 0xff, 0xfd,
+  0xc5, 0xe3, 0x9f, 0x59, 0x80, 0xb0, 0xcf, 0xff, 0x03, 0x10, 0xee, 0x87,
+  0xf9, 0xff, 0xff, 0xfd, 0x6d, 0xc3, 0x87, 0x19, 0x02, 0x5e, 0xc0, 0xff,
+  0x3f, 0x00, 0xee, 0xbf, 0xfb, 0xff, 0xff, 0xfd, 0xed, 0xe3, 0xbf, 0x1b,
+  0x01, 0x00, 0xcf, 0xff, 0x00, 0x1e, 0xee, 0x9f, 0xf9, 0xff, 0xff, 0xfd,
+  0xed, 0xe3, 0x9f, 0x19, 0xc0, 0xb0, 0xcf, 0xff, 0x02, 0x00, 0xec, 0xc7,
+  0x3d, 0xd6, 0x18, 0xc7, 0xff, 0xc3, 0xc7, 0x1d, 0x81, 0x00, 0xc0, 0xff,
+  0x00, 0x00, 0xef, 0xdf, 0xfd, 0xff, 0xff, 0xfd, 0xff, 0xe3, 0xdf, 0x1d,
+  0x60, 0x07, 0xcf, 0xff, 0x00, 0x00, 0xef, 0xdf, 0xfd, 0xff, 0xff, 0xfd,
+  0xef, 0xe3, 0xdf, 0x1d, 0x60, 0x40, 0xcf, 0xff, 0x06, 0x00, 0xef, 0xdf,
+  0xfd, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xdf, 0x5d, 0xf0, 0x80, 0xcf, 0xff,
+  0x00, 0xfc, 0xec, 0xff, 0x7f, 0xfc, 0xff, 0xff, 0xfb, 0x2f, 0x7f, 0x80,
+  0x5f, 0xff, 0xc0, 0xff, 0x0c, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff, 0x7f,
+  0xff, 0x07, 0x3f, 0x20, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0xd6, 0xf7,
+  0xff, 0xff, 0xaf, 0xff, 0xff, 0x3b, 0x5f, 0x20, 0xff, 0xf3, 0x00, 0x00,
+  0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xff, 0x03, 0x00, 0x00, 0xff, 0xfe,
+  0xff, 0xff, 0xff, 0x1f, 0xfe, 0xff, 0x03, 0xff, 0xff, 0xfe, 0xff, 0xff,
+  0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0x7f, 0xf9, 0xff, 0x03, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xbf, 0x20,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0x3d, 0x7f, 0x3d, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3d,
+  0xff, 0xff, 0xff, 0xff, 0x3d, 0x7f, 0x3d, 0xff, 0x7f, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0x3d, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x3f, 0xfe, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x9f, 0xff, 0xff, 0xfe, 0xff,
+  0xff, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc7,
+  0xff, 0x01, 0xff, 0xdf, 0x0f, 0x00, 0xff, 0xff, 0x0f, 0x00, 0xff, 0xff,
+  0x0f, 0x00, 0xff, 0xdf, 0x0d, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xcf, 0xff, 0xff, 0x01, 0x80, 0x10, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00,
+  0xff, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0xff, 0xff, 0xff, 0x7f, 0xff, 0x0f,
+  0xff, 0x01, 0xc0, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x1f, 0x00, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0x0f, 0xff, 0xff, 0xff, 0x03, 0xff, 0x03, 0x00, 0x00,
+  0x00, 0x00, 0xff, 0xff, 0xff, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0x7f, 0xfe, 0xff, 0x1f, 0x00, 0xff, 0x03, 0xff, 0x03, 0x80, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xef, 0xff, 0xef, 0x0f, 0xff, 0x03, 0x00, 0x00,
+  0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xbf, 0xff, 0x03, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0x7f, 0x00, 0xff, 0xe3, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xff, 0x01,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde,
+  0x6f, 0x04, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0x1f, 0x00, 0xff, 0xff,
+  0x3f, 0x3f, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x3f, 0xff, 0xaa, 0xff, 0xff,
+  0xff, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0x5f, 0xdc, 0x1f,
+  0xcf, 0x0f, 0xff, 0x1f, 0xdc, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x00, 0x00,
+  0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x84, 0xfc, 0x2f, 0x3e, 0x50, 0xbd, 0xff, 0xf3, 0xe0, 0x43,
+  0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0x03, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x78,
+  0x0c, 0x00, 0xff, 0xff, 0xff, 0xff, 0xbf, 0x20, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0xff, 0xff, 0x7f, 0x00, 0x7f, 0x7f,
+  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0xfe, 0x03,
+  0x3e, 0x1f, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0x7f, 0xe0, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xf7, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0xff, 0xff,
+  0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xff, 0x1f,
+  0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f,
+  0xf0, 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xfc, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf9,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x80, 0xff, 0xbf, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0x2f, 0x00, 0xff, 0x03, 0x00, 0x00, 0xfc, 0xe8, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0x07, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0xff, 0xff,
+  0xff, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf7, 0xff, 0x00, 0x80,
+  0xff, 0x03, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0x7f, 0x00, 0xff, 0x3f, 0xff, 0x03, 0xff, 0xff, 0x7f, 0xfc, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x05, 0x00, 0x00, 0x38, 0xff, 0xff,
+  0x3c, 0x00, 0x7e, 0x7e, 0x7e, 0x00, 0x7f, 0x7f, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xf7, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0xff, 0x03, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0xff, 0xff, 0x7f, 0xf8,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00,
+  0x00, 0x00, 0x7f, 0x00, 0xf8, 0xe0, 0xff, 0xfd, 0x7f, 0x5f, 0xdb, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0x03, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdf, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0x1f, 0x00, 0x00, 0xff, 0x03, 0xfe, 0xff, 0xff, 0x07, 0xfe, 0xff,
+  0xff, 0x07, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0x7f, 0xfc, 0xfc, 0xfc, 0x1c, 0x00, 0x00, 0x00, 0x00, 0xff, 0xef,
+  0xff, 0xff, 0x7f, 0xff, 0xff, 0xb7, 0xff, 0x3f, 0xff, 0x3f, 0x00, 0x00,
+  0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x1f, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
+  0xff, 0xff, 0x00, 0xe0, 0xff, 0xff, 0xff, 0x07, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0x07, 0xff, 0xff, 0xff, 0x3f, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xff,
+  0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0x3f, 0xff, 0x03, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xff, 0xff, 0xff,
+  0xff, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0xff, 0xff, 0x3f, 0x00, 0xff, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xfd, 0xff, 0xff, 0xff, 0xff,
+  0xbf, 0x91, 0xff, 0xff, 0x3f, 0x00, 0xff, 0xff, 0x7f, 0x00, 0xff, 0xff,
+  0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
+  0x37, 0x00, 0xff, 0xff, 0x3f, 0x00, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6f, 0xf0,
+  0xef, 0xfe, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
+  0xff, 0x1f, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0xff, 0xfe,
+  0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0x3f, 0x00, 0xff, 0xff, 0x3f, 0x00, 0xff, 0xff, 0x07, 0x00, 0xff, 0xff,
+  0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0x07, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0x00, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x1f, 0x80, 0x00,
+  0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
+  0x7f, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00,
+  0x00, 0x00, 0xc0, 0xff, 0x00, 0x00, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0x01, 0x00, 0x00, 0xff, 0xff, 0xff, 0x01, 0xff, 0x03, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xc7, 0xff, 0x70, 0x00, 0xff, 0xff, 0xff, 0xff,
+  0x47, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1e, 0x00,
+  0xff, 0x17, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xff,
+  0x9f, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xbd,
+  0xff, 0xbf, 0xff, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01,
+  0xff, 0x03, 0xef, 0x9f, 0xf9, 0xff, 0xff, 0xfd, 0xed, 0xe3, 0x9f, 0x19,
+  0x81, 0xe0, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbb, 0x07, 0xff, 0x83, 0x00, 0x00,
+  0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xb3, 0x00,
+  0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0x3f, 0x7f, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00,
+  0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x11, 0x00,
+  0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0x3f, 0x01, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
+  0xff, 0xe7, 0xff, 0x07, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03,
+  0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xfc,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x1a, 0x00, 0x00, 0x00, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xe7, 0x7f, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0x20, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff,
+  0x7f, 0x7f, 0x01, 0x00, 0xff, 0x03, 0x00, 0x00, 0xfc, 0xff, 0xff, 0xff,
+  0xfc, 0xff, 0xff, 0xfe, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x7f, 0xfb, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xb4, 0xcb, 0x00,
+  0xff, 0x03, 0xbf, 0xfd, 0xff, 0xff, 0xff, 0x7f, 0x7b, 0x01, 0xff, 0x03,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xff, 0xff, 0x7f, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0xff, 0xff, 0xff, 0x7f, 0xff, 0x03,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xff, 0xff, 0xff, 0x3f, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0x00, 0x00, 0x0f, 0x00, 0xff, 0x03, 0xf8, 0xff, 0xff, 0xe0, 0xff, 0xff,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0x80, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0xff, 0xff,
+  0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0xf0, 0x00,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0x07, 0xff, 0x1f, 0xff, 0x01, 0xff, 0x43, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0x64, 0xde, 0xff, 0xeb, 0xef, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0xe7, 0xdf, 0xdf, 0xff, 0xff,
+  0xff, 0x7b, 0x5f, 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xff,
+  0xff, 0xff, 0xfd, 0xff, 0xff, 0xf7, 0xff, 0xff, 0xff, 0xf7, 0xff, 0xff,
+  0xdf, 0xff, 0xff, 0xff, 0xdf, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0x7f,
+  0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xf7, 0xcf,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xf9, 0xdb, 0x07,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x80, 0x3f, 0xff, 0x43,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0x0f, 0xff, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x8f, 0x08,
+  0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xef, 0xff,
+  0xff, 0xff, 0x96, 0xfe, 0xf7, 0x0a, 0x84, 0xea, 0x96, 0xaa, 0x96, 0xf7,
+  0xf7, 0x5e, 0xff, 0xfb, 0xff, 0x0f, 0xee, 0xfb, 0xff, 0x0f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xff, 0xff, 0xff, 0x03, 0xff, 0xff, 0xff, 0x03, 0xff, 0xff, 0xff, 0x03,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x56, 0x01, 0x00, 0x00, 0x39, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20,
+  0x00, 0x00, 0x00, 0xe0, 0xff, 0xff, 0x00, 0xbf, 0x1d, 0x00, 0x00, 0xe7,
+  0x02, 0x00, 0x00, 0x79, 0x00, 0x00, 0x02, 0x24, 0x00, 0x00, 0x01, 0x01,
+  0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02,
+  0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0x01, 0x39, 0xff, 0xff, 0x00, 0x18,
+  0xff, 0xff, 0x01, 0x87, 0xff, 0xff, 0x00, 0xd4, 0xfe, 0xff, 0x00, 0xc3,
+  0x00, 0x00, 0x01, 0xd2, 0x00, 0x00, 0x01, 0xce, 0x00, 0x00, 0x01, 0xcd,
+  0x00, 0x00, 0x01, 0x4f, 0x00, 0x00, 0x01, 0xca, 0x00, 0x00, 0x01, 0xcb,
+  0x00, 0x00, 0x01, 0xcf, 0x00, 0x00, 0x00, 0x61, 0x00, 0x00, 0x01, 0xd3,
+  0x00, 0x00, 0x01, 0xd1, 0x00, 0x00, 0x00, 0xa3, 0x00, 0x00, 0x01, 0xd5,
+  0x00, 0x00, 0x00, 0x82, 0x00, 0x00, 0x01, 0xd6, 0x00, 0x00, 0x01, 0xda,
+  0x00, 0x00, 0x01, 0xd9, 0x00, 0x00, 0x01, 0xdb, 0x00, 0x00, 0x00, 0x38,
+  0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0xb1, 0xff, 0xff, 0x01, 0x9f,
+  0xff, 0xff, 0x01, 0xc8, 0xff, 0xff, 0x02, 0x28, 0x24, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x33,
+  0xff, 0xff, 0x00, 0x26, 0xff, 0xff, 0x01, 0x7e, 0xff, 0xff, 0x01, 0x2b,
+  0x2a, 0x00, 0x01, 0x5d, 0xff, 0xff, 0x01, 0x28, 0x2a, 0x00, 0x00, 0x3f,
+  0x2a, 0x00, 0x01, 0x3d, 0xff, 0xff, 0x01, 0x45, 0x00, 0x00, 0x01, 0x47,
+  0x00, 0x00, 0x00, 0x1f, 0x2a, 0x00, 0x00, 0x1c, 0x2a, 0x00, 0x00, 0x1e,
+  0x2a, 0x00, 0x00, 0x2e, 0xff, 0xff, 0x00, 0x32, 0xff, 0xff, 0x00, 0x36,
+  0xff, 0xff, 0x00, 0x35, 0xff, 0xff, 0x00, 0x4f, 0xa5, 0x00, 0x00, 0x4b,
+  0xa5, 0x00, 0x00, 0x31, 0xff, 0xff, 0x00, 0x28, 0xa5, 0x00, 0x00, 0x44,
+  0xa5, 0x00, 0x00, 0x2f, 0xff, 0xff, 0x00, 0x2d, 0xff, 0xff, 0x00, 0xf7,
+  0x29, 0x00, 0x00, 0x41, 0xa5, 0x00, 0x00, 0xfd, 0x29, 0x00, 0x00, 0x2b,
+  0xff, 0xff, 0x00, 0x2a, 0xff, 0xff, 0x00, 0xe7, 0x29, 0x00, 0x00, 0x43,
+  0xa5, 0x00, 0x00, 0x2a, 0xa5, 0x00, 0x00, 0xbb, 0xff, 0xff, 0x00, 0x27,
+  0xff, 0xff, 0x00, 0xb9, 0xff, 0xff, 0x00, 0x25, 0xff, 0xff, 0x00, 0x15,
+  0xa5, 0x00, 0x00, 0x12, 0xa5, 0x00, 0x02, 0x24, 0x4c, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x01, 0x20, 0x00, 0x00, 0x00, 0xe0, 0xff, 0xff, 0x01, 0x01,
+  0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x54, 0x00, 0x00, 0x01, 0x74,
+  0x00, 0x00, 0x01, 0x26, 0x00, 0x00, 0x01, 0x25, 0x00, 0x00, 0x01, 0x40,
+  0x00, 0x00, 0x01, 0x3f, 0x00, 0x00, 0x00, 0xda, 0xff, 0xff, 0x00, 0xdb,
+  0xff, 0xff, 0x00, 0xe1, 0xff, 0xff, 0x00, 0xc0, 0xff, 0xff, 0x00, 0xc1,
+  0xff, 0xff, 0x01, 0x08, 0x00, 0x00, 0x00, 0xc2, 0xff, 0xff, 0x00, 0xc7,
+  0xff, 0xff, 0x00, 0xd1, 0xff, 0xff, 0x00, 0xca, 0xff, 0xff, 0x00, 0xf8,
+  0xff, 0xff, 0x00, 0xaa, 0xff, 0xff, 0x00, 0xb0, 0xff, 0xff, 0x00, 0x07,
+  0x00, 0x00, 0x00, 0x8c, 0xff, 0xff, 0x01, 0xc4, 0xff, 0xff, 0x00, 0xa0,
+  0xff, 0xff, 0x01, 0xf9, 0xff, 0xff, 0x02, 0x1a, 0x70, 0x00, 0x01, 0x01,
+  0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x01, 0x20, 0x00, 0x00, 0x00, 0xe0,
+  0xff, 0xff, 0x01, 0x50, 0x00, 0x00, 0x01, 0x0f, 0x00, 0x00, 0x00, 0xf1,
+  0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0x30, 0x00, 0x00, 0x00, 0xd0,
+  0xff, 0xff, 0x01, 0x01, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xc0, 0x0b, 0x00, 0x01, 0x60, 0x1c, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x01, 0xd0, 0x97, 0x00, 0x01, 0x08, 0x00, 0x00, 0x00, 0xf8,
+  0xff, 0xff, 0x02, 0x05, 0x8a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x40,
+  0xf4, 0xff, 0x00, 0x9e, 0xe7, 0xff, 0x00, 0xc2, 0x89, 0x00, 0x00, 0xdb,
+  0xe7, 0xff, 0x00, 0x92, 0xe7, 0xff, 0x00, 0x93, 0xe7, 0xff, 0x00, 0x9c,
+  0xe7, 0xff, 0x00, 0x9d, 0xe7, 0xff, 0x00, 0xa4, 0xe7, 0xff, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x38, 0x8a, 0x00, 0x00, 0x04, 0x8a, 0x00, 0x00, 0xe6,
+  0x0e, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xc5, 0xff, 0xff, 0x01, 0x41, 0xe2, 0xff, 0x02, 0x1d,
+  0x8f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x01, 0xf8, 0xff, 0xff, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x56, 0x00, 0x00, 0x01, 0xaa, 0xff, 0xff, 0x00, 0x4a,
+  0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x70,
+  0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x01, 0xb6,
+  0xff, 0xff, 0x01, 0xf7, 0xff, 0xff, 0x00, 0xdb, 0xe3, 0xff, 0x01, 0x9c,
+  0xff, 0xff, 0x01, 0x90, 0xff, 0xff, 0x01, 0x80, 0xff, 0xff, 0x01, 0x82,
+  0xff, 0xff, 0x02, 0x05, 0xac, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x10,
+  0x00, 0x00, 0x00, 0xf0, 0xff, 0xff, 0x01, 0x1c, 0x00, 0x00, 0x01, 0x01,
+  0x00, 0x00, 0x01, 0xa3, 0xe2, 0xff, 0x01, 0x41, 0xdf, 0xff, 0x01, 0xba,
+  0xdf, 0xff, 0x00, 0xe4, 0xff, 0xff, 0x02, 0x0b, 0xb1, 0x00, 0x01, 0x01,
+  0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x01, 0x30, 0x00, 0x00, 0x00, 0xd0,
+  0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0x09, 0xd6, 0xff, 0x01, 0x1a,
+  0xf1, 0xff, 0x01, 0x19, 0xd6, 0xff, 0x00, 0xd5, 0xd5, 0xff, 0x00, 0xd8,
+  0xd5, 0xff, 0x01, 0xe4, 0xd5, 0xff, 0x01, 0x03, 0xd6, 0xff, 0x01, 0xe1,
+  0xd5, 0xff, 0x01, 0xe2, 0xd5, 0xff, 0x01, 0xc1, 0xd5, 0xff, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xa0, 0xe3, 0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
+  0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x02, 0x0c, 0xbc, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x01, 0xbc,
+  0x5a, 0xff, 0x01, 0xa0, 0x03, 0x00, 0x01, 0xfc, 0x75, 0xff, 0x01, 0xd8,
+  0x5a, 0xff, 0x00, 0x30, 0x00, 0x00, 0x01, 0xb1, 0x5a, 0xff, 0x01, 0xb5,
+  0x5a, 0xff, 0x01, 0xbf, 0x5a, 0xff, 0x01, 0xee, 0x5a, 0xff, 0x01, 0xd6,
+  0x5a, 0xff, 0x01, 0xeb, 0x5a, 0xff, 0x01, 0xd0, 0xff, 0xff, 0x01, 0xbd,
+  0x5a, 0xff, 0x01, 0xc8, 0x75, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30,
+  0x68, 0xff, 0x00, 0x60, 0xfc, 0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20,
+  0x00, 0x00, 0x00, 0xe0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0x28,
+  0x00, 0x00, 0x00, 0xd8, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0x40,
+  0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20,
+  0x00, 0x00, 0x00, 0xe0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20,
+  0x00, 0x00, 0x00, 0xe0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0x22,
+  0x00, 0x00, 0x00, 0xde, 0xff, 0xff, 0x30, 0x0c, 0x31, 0x0d, 0x78, 0x0e,
+  0x7f, 0x0f, 0x80, 0x10, 0x81, 0x11, 0x86, 0x12, 0x89, 0x13, 0x8a, 0x13,
+  0x8e, 0x14, 0x8f, 0x15, 0x90, 0x16, 0x93, 0x13, 0x94, 0x17, 0x95, 0x18,
+  0x96, 0x19, 0x97, 0x1a, 0x9a, 0x1b, 0x9c, 0x19, 0x9d, 0x1c, 0x9e, 0x1d,
+  0x9f, 0x1e, 0xa6, 0x1f, 0xa9, 0x1f, 0xae, 0x1f, 0xb1, 0x20, 0xb2, 0x20,
+  0xb7, 0x21, 0xbf, 0x22, 0xc5, 0x23, 0xc8, 0x23, 0xcb, 0x23, 0xdd, 0x24,
+  0xf2, 0x23, 0xf6, 0x25, 0xf7, 0x26, 0x20, 0x2d, 0x3a, 0x2e, 0x3d, 0x2f,
+  0x3e, 0x30, 0x3f, 0x31, 0x40, 0x31, 0x43, 0x32, 0x44, 0x33, 0x45, 0x34,
+  0x50, 0x35, 0x51, 0x36, 0x52, 0x37, 0x53, 0x38, 0x54, 0x39, 0x59, 0x3a,
+  0x5b, 0x3b, 0x5c, 0x3c, 0x61, 0x3d, 0x63, 0x3e, 0x65, 0x3f, 0x66, 0x40,
+  0x68, 0x41, 0x69, 0x42, 0x6a, 0x40, 0x6b, 0x43, 0x6c, 0x44, 0x6f, 0x42,
+  0x71, 0x45, 0x72, 0x46, 0x75, 0x47, 0x7d, 0x48, 0x82, 0x49, 0x87, 0x4a,
+  0x89, 0x4b, 0x8a, 0x4c, 0x8b, 0x4c, 0x8c, 0x4d, 0x92, 0x4e, 0x9d, 0x4f,
+  0x9e, 0x50, 0x45, 0x57, 0x7b, 0x1d, 0x7c, 0x1d, 0x7d, 0x1d, 0x7f, 0x58,
+  0x86, 0x59, 0x88, 0x5a, 0x89, 0x5a, 0x8a, 0x5a, 0x8c, 0x5b, 0x8e, 0x5c,
+  0x8f, 0x5c, 0xac, 0x5d, 0xad, 0x5e, 0xae, 0x5e, 0xaf, 0x5e, 0xc2, 0x5f,
+  0xcc, 0x60, 0xcd, 0x61, 0xce, 0x61, 0xcf, 0x62, 0xd0, 0x63, 0xd1, 0x64,
+  0xd5, 0x65, 0xd6, 0x66, 0xd7, 0x67, 0xf0, 0x68, 0xf1, 0x69, 0xf2, 0x6a,
+  0xf3, 0x6b, 0xf4, 0x6c, 0xf5, 0x6d, 0xf9, 0x6e, 0xfd, 0x2d, 0xfe, 0x2d,
+  0xff, 0x2d, 0x50, 0x69, 0x51, 0x69, 0x52, 0x69, 0x53, 0x69, 0x54, 0x69,
+  0x55, 0x69, 0x56, 0x69, 0x57, 0x69, 0x58, 0x69, 0x59, 0x69, 0x5a, 0x69,
+  0x5b, 0x69, 0x5c, 0x69, 0x5d, 0x69, 0x5e, 0x69, 0x5f, 0x69, 0x82, 0x00,
+  0x83, 0x00, 0x84, 0x00, 0x85, 0x00, 0x86, 0x00, 0x87, 0x00, 0x88, 0x00,
+  0x89, 0x00, 0xc0, 0x75, 0xcf, 0x76, 0x80, 0x89, 0x81, 0x8a, 0x82, 0x8b,
+  0x85, 0x8c, 0x86, 0x8d, 0x70, 0x9d, 0x71, 0x9d, 0x76, 0x9e, 0x77, 0x9e,
+  0x78, 0x9f, 0x79, 0x9f, 0x7a, 0xa0, 0x7b, 0xa0, 0x7c, 0xa1, 0x7d, 0xa1,
+  0xb3, 0xa2, 0xba, 0xa3, 0xbb, 0xa3, 0xbc, 0xa4, 0xbe, 0xa5, 0xc3, 0xa2,
+  0xcc, 0xa4, 0xda, 0xa6, 0xdb, 0xa6, 0xe5, 0x6a, 0xea, 0xa7, 0xeb, 0xa7,
+  0xec, 0x6e, 0xf3, 0xa2, 0xf8, 0xa8, 0xf9, 0xa8, 0xfa, 0xa9, 0xfb, 0xa9,
+  0xfc, 0xa4, 0x26, 0xb0, 0x2a, 0xb1, 0x2b, 0xb2, 0x4e, 0xb3, 0x84, 0x08,
+  0x62, 0xba, 0x63, 0xbb, 0x64, 0xbc, 0x65, 0xbd, 0x66, 0xbe, 0x6d, 0xbf,
+  0x6e, 0xc0, 0x6f, 0xc1, 0x70, 0xc2, 0x7e, 0xc3, 0x7f, 0xc3, 0x7d, 0xcf,
+  0x8d, 0xd0, 0x94, 0xd1, 0xab, 0xd2, 0xac, 0xd3, 0xad, 0xd4, 0xb0, 0xd5,
+  0xb1, 0xd6, 0xb2, 0xd7, 0xc4, 0xd8, 0xc5, 0xd9, 0xc6, 0xda, 0x07, 0x08,
+  0x09, 0x0a, 0x0b, 0x0c, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+  0x06, 0x06, 0x0d, 0x06, 0x06, 0x0e, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+  0x06, 0x06, 0x0f, 0x10, 0x11, 0x12, 0x06, 0x13, 0x06, 0x06, 0x06, 0x06,
+  0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x14, 0x15, 0x06, 0x06, 0x06, 0x06,
+  0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+  0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+  0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+  0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+  0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+  0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+  0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+  0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+  0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+  0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x16, 0x17, 0x06, 0x06,
+  0x06, 0x18, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+  0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+  0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+  0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+  0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+  0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+  0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+  0x06, 0x19, 0x06, 0x06, 0x06, 0x06, 0x1a, 0x06, 0x06, 0x06, 0x06, 0x06,
+  0x06, 0x06, 0x1b, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+  0x06, 0x06, 0x1c, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+  0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+  0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+  0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+  0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+  0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+  0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+  0x06, 0x06, 0x06, 0x06, 0x1d, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+  0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+  0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+  0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+  0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+  0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+  0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+  0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+  0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+  0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+  0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x1e, 0x06, 0x06, 0x06, 0x06,
+  0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+  0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x2b, 0x2b,
+  0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x01, 0x00, 0x54, 0x56, 0x56, 0x56,
+  0x56, 0x56, 0x56, 0x56, 0x56, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x18, 0x00, 0x00, 0x00, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x07,
+  0x2b, 0x2b, 0x5b, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x4a, 0x56,
+  0x56, 0x05, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50,
+  0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x24, 0x50, 0x79, 0x31, 0x50, 0x31,
+  0x50, 0x31, 0x38, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50,
+  0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x4e, 0x31, 0x02, 0x4e, 0x0d, 0x0d,
+  0x4e, 0x03, 0x4e, 0x00, 0x24, 0x6e, 0x00, 0x4e, 0x31, 0x26, 0x6e, 0x51,
+  0x4e, 0x24, 0x50, 0x4e, 0x39, 0x14, 0x81, 0x1b, 0x1d, 0x1d, 0x53, 0x31,
+  0x50, 0x31, 0x50, 0x0d, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x1b, 0x53,
+  0x24, 0x50, 0x31, 0x02, 0x5c, 0x7b, 0x5c, 0x7b, 0x5c, 0x7b, 0x5c, 0x7b,
+  0x5c, 0x7b, 0x14, 0x79, 0x5c, 0x7b, 0x5c, 0x7b, 0x5c, 0x2d, 0x2b, 0x49,
+  0x03, 0x48, 0x03, 0x78, 0x5c, 0x7b, 0x14, 0x00, 0x96, 0x0a, 0x01, 0x2b,
+  0x28, 0x06, 0x06, 0x00, 0x2a, 0x06, 0x2a, 0x2a, 0x2b, 0x07, 0xbb, 0xb5,
+  0x2b, 0x1e, 0x00, 0x2b, 0x07, 0x2b, 0x2b, 0x2b, 0x01, 0x2b, 0x2b, 0x2b,
+  0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,
+  0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,
+  0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x01, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,
+  0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,
+  0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2a, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,
+  0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0xcd, 0x46, 0xcd, 0x2b, 0x00,
+  0x25, 0x2b, 0x07, 0x01, 0x06, 0x01, 0x55, 0x56, 0x56, 0x56, 0x56, 0x56,
+  0x55, 0x56, 0x56, 0x02, 0x24, 0x81, 0x81, 0x81, 0x81, 0x81, 0x15, 0x81,
+  0x81, 0x81, 0x00, 0x00, 0x2b, 0x00, 0xb2, 0xd1, 0xb2, 0xd1, 0xb2, 0xd1,
+  0xb2, 0xd1, 0x00, 0x00, 0xcd, 0xcc, 0x01, 0x00, 0xd7, 0xd7, 0xd7, 0xd7,
+  0xd7, 0x83, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
+  0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0x1c, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50,
+  0x31, 0x50, 0x31, 0x02, 0x00, 0x00, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50,
+  0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50,
+  0x4e, 0x31, 0x50, 0x31, 0x50, 0x4e, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50,
+  0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x02, 0x87, 0xa6,
+  0x87, 0xa6, 0x87, 0xa6, 0x87, 0xa6, 0x87, 0xa6, 0x87, 0xa6, 0x87, 0xa6,
+  0x87, 0xa6, 0x2a, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,
+  0x2b, 0x2b, 0x2b, 0x00, 0x00, 0x00, 0x54, 0x56, 0x56, 0x56, 0x56, 0x56,
+  0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56,
+  0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x0c, 0x00, 0x0c, 0x2a, 0x2b, 0x2b,
+  0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x07,
+  0x2a, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x2b, 0x2b, 0x2b, 0x2b,
+  0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,
+  0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x56, 0x56,
+  0x6c, 0x81, 0x15, 0x00, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,
+  0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,
+  0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,
+  0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x07, 0x6c,
+  0x03, 0x41, 0x2b, 0x2b, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56,
+  0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x2c, 0x56, 0x2b, 0x2b, 0x2b, 0x2b,
+  0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,
+  0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x6c,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x25, 0x06, 0x25,
+  0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25,
+  0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25,
+  0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25,
+  0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x56, 0x7a,
+  0x9e, 0x26, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25,
+  0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25,
+  0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, 0x01, 0x2b, 0x2b,
+  0x4f, 0x56, 0x56, 0x2c, 0x2b, 0x7f, 0x56, 0x56, 0x39, 0x2b, 0x2b, 0x55,
+  0x56, 0x56, 0x2b, 0x2b, 0x4f, 0x56, 0x56, 0x2c, 0x2b, 0x7f, 0x56, 0x56,
+  0x81, 0x37, 0x75, 0x5b, 0x7b, 0x5c, 0x2b, 0x2b, 0x4f, 0x56, 0x56, 0x02,
+  0xac, 0x04, 0x00, 0x00, 0x39, 0x2b, 0x2b, 0x55, 0x56, 0x56, 0x2b, 0x2b,
+  0x4f, 0x56, 0x56, 0x2c, 0x2b, 0x2b, 0x56, 0x56, 0x32, 0x13, 0x81, 0x57,
+  0x00, 0x6f, 0x81, 0x7e, 0xc9, 0xd7, 0x7e, 0x2d, 0x81, 0x81, 0x0e, 0x7e,
+  0x39, 0x7f, 0x6f, 0x57, 0x00, 0x81, 0x81, 0x7e, 0x15, 0x00, 0x7e, 0x03,
+  0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,
+  0x07, 0x2b, 0x24, 0x2b, 0x97, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,
+  0x2b, 0x2b, 0x2a, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x56, 0x56, 0x56, 0x56,
+  0x56, 0x80, 0x81, 0x81, 0x81, 0x81, 0x39, 0xbb, 0x2a, 0x2b, 0x2b, 0x2b,
+  0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,
+  0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,
+  0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,
+  0x2b, 0x01, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
+  0x81, 0x81, 0x81, 0x81, 0x81, 0xc9, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac,
+  0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xd0, 0x0d, 0x00,
+  0x4e, 0x31, 0x02, 0xb4, 0xc1, 0xc1, 0xd7, 0xd7, 0x24, 0x50, 0x31, 0x50,
+  0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50,
+  0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50,
+  0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0xd7, 0xd7, 0x53, 0xc1, 0x47, 0xd4,
+  0xd7, 0xd7, 0xd7, 0x05, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,
+  0x2b, 0x2b, 0x2b, 0x2b, 0x07, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x4e, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50,
+  0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x24, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x2b, 0x2b, 0x2b,
+  0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x79, 0x5c, 0x7b, 0x5c, 0x7b,
+  0x4f, 0x7b, 0x5c, 0x7b, 0x5c, 0x7b, 0x5c, 0x7b, 0x5c, 0x7b, 0x5c, 0x7b,
+  0x5c, 0x7b, 0x5c, 0x7b, 0x5c, 0x7b, 0x5c, 0x7b, 0x5c, 0x2d, 0x2b, 0x2b,
+  0x79, 0x14, 0x5c, 0x7b, 0x5c, 0x2d, 0x79, 0x2a, 0x5c, 0x27, 0x5c, 0x7b,
+  0x5c, 0x7b, 0x5c, 0x7b, 0xa4, 0x00, 0x0a, 0xb4, 0x5c, 0x7b, 0x5c, 0x7b,
+  0x4f, 0x03, 0x2a, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,
+  0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x01, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a,
+  0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,
+  0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,
+  0x2b, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2b,
+  0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x07, 0x00, 0x48, 0x56, 0x56,
+  0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,
+  0x2b, 0x2b, 0x2b, 0x55, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56,
+  0x56, 0x56, 0x56, 0x56, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x24, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,
+  0x07, 0x00, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56,
+  0x56, 0x56, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x2b,
+  0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,
+  0x2b, 0x2b, 0x2b, 0x07, 0x00, 0x00, 0x00, 0x00, 0x56, 0x56, 0x56, 0x56,
+  0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56,
+  0x56, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a,
+  0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x56, 0x56,
+  0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x0e, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,
+  0x2b, 0x2b, 0x2b, 0x2b, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56,
+  0x56, 0x56, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x2b,
+  0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x55, 0x56, 0x56,
+  0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x0e, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x27, 0x51, 0x6f, 0x77,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x00,
+  0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x8e,
+  0x92, 0x97, 0x00, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xb4, 0xc4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xc6, 0xc9, 0x00, 0x00, 0x00, 0xdb, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0x00, 0x00,
+  0x00, 0x00, 0xe1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe7, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xea, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xed, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0a, 0x00,
+  0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0c, 0x00,
+  0x00, 0x00, 0x85, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x01, 0x20,
+  0x00, 0x00, 0x02, 0x20, 0x00, 0x00, 0x03, 0x20, 0x00, 0x00, 0x04, 0x20,
+  0x00, 0x00, 0x05, 0x20, 0x00, 0x00, 0x06, 0x20, 0x00, 0x00, 0x08, 0x20,
+  0x00, 0x00, 0x09, 0x20, 0x00, 0x00, 0x0a, 0x20, 0x00, 0x00, 0x28, 0x20,
+  0x00, 0x00, 0x29, 0x20, 0x00, 0x00, 0x5f, 0x20, 0x00, 0x00, 0x00, 0x30,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x92, 0x05, 0x04, 0x6e, 0x61,
+  0x6d, 0x65, 0x01, 0xc9, 0x04, 0x2c, 0x00, 0x2a, 0x5f, 0x5f, 0x69, 0x6d,
+  0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x5f, 0x77, 0x61, 0x73, 0x69, 0x5f,
+  0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x5f, 0x70, 0x72, 0x65,
+  0x76, 0x69, 0x65, 0x77, 0x31, 0x5f, 0x61, 0x72, 0x67, 0x73, 0x5f, 0x67,
+  0x65, 0x74, 0x01, 0x30, 0x5f, 0x5f, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74,
+  0x65, 0x64, 0x5f, 0x77, 0x61, 0x73, 0x69, 0x5f, 0x73, 0x6e, 0x61, 0x70,
+  0x73, 0x68, 0x6f, 0x74, 0x5f, 0x70, 0x72, 0x65, 0x76, 0x69, 0x65, 0x77,
+  0x31, 0x5f, 0x61, 0x72, 0x67, 0x73, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x73,
+  0x5f, 0x67, 0x65, 0x74, 0x02, 0x2b, 0x5f, 0x5f, 0x69, 0x6d, 0x70, 0x6f,
+  0x72, 0x74, 0x65, 0x64, 0x5f, 0x77, 0x61, 0x73, 0x69, 0x5f, 0x73, 0x6e,
+  0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x5f, 0x70, 0x72, 0x65, 0x76, 0x69,
+  0x65, 0x77, 0x31, 0x5f, 0x70, 0x72, 0x6f, 0x63, 0x5f, 0x65, 0x78, 0x69,
+  0x74, 0x03, 0x11, 0x5f, 0x5f, 0x77, 0x61, 0x73, 0x6d, 0x5f, 0x63, 0x61,
+  0x6c, 0x6c, 0x5f, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x04, 0x13, 0x75, 0x6e,
+  0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x5f, 0x77, 0x65, 0x61, 0x6b,
+  0x3a, 0x6d, 0x61, 0x69, 0x6e, 0x05, 0x12, 0x5f, 0x5f, 0x77, 0x61, 0x73,
+  0x6d, 0x5f, 0x69, 0x6e, 0x69, 0x74, 0x5f, 0x6d, 0x65, 0x6d, 0x6f, 0x72,
+  0x79, 0x06, 0x06, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x07, 0x0a, 0x72,
+  0x65, 0x73, 0x65, 0x74, 0x5f, 0x68, 0x65, 0x61, 0x70, 0x08, 0x06, 0x6d,
+  0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x09, 0x04, 0x66, 0x72, 0x65, 0x65, 0x0a,
+  0x06, 0x63, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x0b, 0x07, 0x72, 0x65, 0x61,
+  0x6c, 0x6c, 0x6f, 0x63, 0x0c, 0x05, 0x5f, 0x45, 0x78, 0x69, 0x74, 0x0d,
+  0x0b, 0x5f, 0x5f, 0x6d, 0x61, 0x69, 0x6e, 0x5f, 0x76, 0x6f, 0x69, 0x64,
+  0x0e, 0x0f, 0x5f, 0x5f, 0x77, 0x61, 0x73, 0x69, 0x5f, 0x61, 0x72, 0x67,
+  0x73, 0x5f, 0x67, 0x65, 0x74, 0x0f, 0x15, 0x5f, 0x5f, 0x77, 0x61, 0x73,
+  0x69, 0x5f, 0x61, 0x72, 0x67, 0x73, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x73,
+  0x5f, 0x67, 0x65, 0x74, 0x10, 0x10, 0x5f, 0x5f, 0x77, 0x61, 0x73, 0x69,
+  0x5f, 0x70, 0x72, 0x6f, 0x63, 0x5f, 0x65, 0x78, 0x69, 0x74, 0x11, 0x05,
+  0x64, 0x75, 0x6d, 0x6d, 0x79, 0x12, 0x11, 0x5f, 0x5f, 0x77, 0x61, 0x73,
+  0x6d, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x5f, 0x64, 0x74, 0x6f, 0x72, 0x73,
+  0x13, 0x06, 0x6d, 0x65, 0x6d, 0x63, 0x70, 0x79, 0x14, 0x06, 0x6d, 0x65,
+  0x6d, 0x73, 0x65, 0x74, 0x15, 0x06, 0x73, 0x74, 0x72, 0x6c, 0x65, 0x6e,
+  0x16, 0x08, 0x69, 0x73, 0x77, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x17, 0x06,
+  0x6d, 0x65, 0x6d, 0x63, 0x6d, 0x70, 0x18, 0x06, 0x6d, 0x65, 0x6d, 0x63,
+  0x68, 0x72, 0x19, 0x06, 0x73, 0x74, 0x72, 0x63, 0x6d, 0x70, 0x1a, 0x08,
+  0x74, 0x6f, 0x77, 0x6c, 0x6f, 0x77, 0x65, 0x72, 0x1b, 0x07, 0x63, 0x61,
+  0x73, 0x65, 0x6d, 0x61, 0x70, 0x1c, 0x08, 0x74, 0x6f, 0x77, 0x75, 0x70,
+  0x70, 0x65, 0x72, 0x1d, 0x07, 0x73, 0x74, 0x72, 0x6e, 0x63, 0x6d, 0x70,
+  0x1e, 0x08, 0x69, 0x73, 0x77, 0x75, 0x70, 0x70, 0x65, 0x72, 0x1f, 0x07,
+  0x6d, 0x65, 0x6d, 0x6d, 0x6f, 0x76, 0x65, 0x20, 0x08, 0x69, 0x73, 0x77,
+  0x6c, 0x6f, 0x77, 0x65, 0x72, 0x21, 0x07, 0x69, 0x73, 0x62, 0x6c, 0x61,
+  0x6e, 0x6b, 0x22, 0x08, 0x69, 0x73, 0x77, 0x62, 0x6c, 0x61, 0x6e, 0x6b,
+  0x23, 0x08, 0x69, 0x73, 0x77, 0x64, 0x69, 0x67, 0x69, 0x74, 0x24, 0x07,
+  0x73, 0x74, 0x72, 0x6e, 0x63, 0x61, 0x74, 0x25, 0x09, 0x5f, 0x5f, 0x73,
+  0x74, 0x70, 0x6e, 0x63, 0x70, 0x79, 0x26, 0x07, 0x73, 0x74, 0x72, 0x6e,
+  0x63, 0x70, 0x79, 0x27, 0x09, 0x69, 0x73, 0x77, 0x78, 0x64, 0x69, 0x67,
+  0x69, 0x74, 0x28, 0x06, 0x77, 0x63, 0x73, 0x6c, 0x65, 0x6e, 0x29, 0x06,
+  0x77, 0x63, 0x73, 0x63, 0x68, 0x72, 0x2a, 0x08, 0x69, 0x73, 0x77, 0x73,
+  0x70, 0x61, 0x63, 0x65, 0x2b, 0x08, 0x69, 0x73, 0x77, 0x61, 0x6c, 0x6e,
+  0x75, 0x6d, 0x07, 0x33, 0x02, 0x00, 0x0f, 0x5f, 0x5f, 0x73, 0x74, 0x61,
+  0x63, 0x6b, 0x5f, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x01, 0x1f,
+  0x47, 0x4f, 0x54, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x69, 0x6e, 0x74,
+  0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x5f, 0x5f, 0x6d, 0x65, 0x6d, 0x6f,
+  0x72, 0x79, 0x5f, 0x62, 0x61, 0x73, 0x65, 0x09, 0x0a, 0x01, 0x00, 0x07,
+  0x2e, 0x72, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x00, 0x76, 0x09, 0x70, 0x72,
+  0x6f, 0x64, 0x75, 0x63, 0x65, 0x72, 0x73, 0x01, 0x0c, 0x70, 0x72, 0x6f,
+  0x63, 0x65, 0x73, 0x73, 0x65, 0x64, 0x2d, 0x62, 0x79, 0x01, 0x05, 0x63,
+  0x6c, 0x61, 0x6e, 0x67, 0x56, 0x31, 0x37, 0x2e, 0x30, 0x2e, 0x36, 0x20,
+  0x28, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x67, 0x69, 0x74,
+  0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6c, 0x6c, 0x76, 0x6d,
+  0x2f, 0x6c, 0x6c, 0x76, 0x6d, 0x2d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63,
+  0x74, 0x20, 0x36, 0x30, 0x30, 0x39, 0x37, 0x30, 0x38, 0x62, 0x34, 0x33,
+  0x36, 0x37, 0x31, 0x37, 0x31, 0x63, 0x63, 0x64, 0x62, 0x66, 0x34, 0x62,
+  0x35, 0x39, 0x30, 0x35, 0x63, 0x62, 0x36, 0x61, 0x38, 0x30, 0x33, 0x37,
+  0x35, 0x33, 0x66, 0x65, 0x31, 0x38, 0x29, 0x00, 0x39, 0x0f, 0x74, 0x61,
+  0x72, 0x67, 0x65, 0x74, 0x5f, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65,
+  0x73, 0x03, 0x2b, 0x0b, 0x62, 0x75, 0x6c, 0x6b, 0x2d, 0x6d, 0x65, 0x6d,
+  0x6f, 0x72, 0x79, 0x2b, 0x0f, 0x6d, 0x75, 0x74, 0x61, 0x62, 0x6c, 0x65,
+  0x2d, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x73, 0x2b, 0x08, 0x73, 0x69,
+  0x67, 0x6e, 0x2d, 0x65, 0x78, 0x74
+};
+unsigned int STDLIB_WASM_LEN = 15582;
diff --git a/vendor/tree-sitter/lib/src/wasm_store.c b/vendor/tree-sitter/lib/src/wasm_store.c
new file mode 100644
--- /dev/null
+++ b/vendor/tree-sitter/lib/src/wasm_store.c
@@ -0,0 +1,1847 @@
+#include "tree_sitter/api.h"
+#include "./parser.h"
+#include <stdint.h>
+
+#ifdef TREE_SITTER_FEATURE_WASM
+
+#include "./alloc.h"
+#include "./array.h"
+#include "./atomic.h"
+#include "./language.h"
+#include "./lexer.h"
+#include "./wasm/wasm-stdlib.h"
+#include "./wasm_store.h"
+
+#include <string.h>
+#include <wasm.h>
+#include <wasmtime.h>
+
+#define array_len(a) (sizeof(a) / sizeof(a[0]))
+
+// The following symbols from the C and C++ standard libraries are available
+// for external scanners to use.
+const char *STDLIB_SYMBOLS[] = {
+  #include "./stdlib-symbols.txt"
+};
+
+// The contents of the `dylink.0` custom section of a wasm module,
+// as specified by the current WebAssembly dynamic linking ABI proposal.
+typedef struct {
+  uint32_t memory_size;
+  uint32_t memory_align;
+  uint32_t table_size;
+  uint32_t table_align;
+} WasmDylinkInfo;
+
+// WasmLanguageId - A pointer used to identify a language. This language id is
+// reference-counted, so that its ownership can be shared between the language
+// itself and the instances of the language that are held in wasm stores.
+typedef struct {
+  volatile uint32_t ref_count;
+  volatile uint32_t is_language_deleted;
+} WasmLanguageId;
+
+// LanguageWasmModule - Additional data associated with a wasm-backed
+// `TSLanguage`. This data is read-only and does not reference a particular
+// wasm store, so it can be shared by all users of a `TSLanguage`. A pointer to
+// this is stored on the language itself.
+typedef struct {
+  volatile uint32_t ref_count;
+  WasmLanguageId *language_id;
+  wasmtime_module_t *module;
+  const char *name;
+  char *symbol_name_buffer;
+  char *field_name_buffer;
+  WasmDylinkInfo dylink_info;
+} LanguageWasmModule;
+
+// LanguageWasmInstance - Additional data associated with an instantiation of
+// a `TSLanguage` in a particular wasm store. The wasm store holds one of
+// these structs for each language that it has instantiated.
+typedef struct {
+  WasmLanguageId *language_id;
+  wasmtime_instance_t instance;
+  int32_t external_states_address;
+  int32_t lex_main_fn_index;
+  int32_t lex_keyword_fn_index;
+  int32_t scanner_create_fn_index;
+  int32_t scanner_destroy_fn_index;
+  int32_t scanner_serialize_fn_index;
+  int32_t scanner_deserialize_fn_index;
+  int32_t scanner_scan_fn_index;
+} LanguageWasmInstance;
+
+typedef struct {
+  uint32_t reset_heap;
+  uint32_t proc_exit;
+  uint32_t abort;
+  uint32_t assert_fail;
+  uint32_t notify_memory_growth;
+  uint32_t debug_message;
+  uint32_t at_exit;
+  uint32_t args_get;
+  uint32_t args_sizes_get;
+} BuiltinFunctionIndices;
+
+// TSWasmStore - A struct that allows a given `Parser` to use wasm-backed
+// languages. This struct is mutable, and can only be used by one parser at a
+// time.
+struct TSWasmStore {
+  wasm_engine_t *engine;
+  wasmtime_store_t *store;
+  wasmtime_table_t function_table;
+  wasmtime_memory_t memory;
+  TSLexer *current_lexer;
+  LanguageWasmInstance *current_instance;
+  Array(LanguageWasmInstance) language_instances;
+  uint32_t current_memory_offset;
+  uint32_t current_function_table_offset;
+  uint32_t *stdlib_fn_indices;
+  BuiltinFunctionIndices builtin_fn_indices;
+  wasmtime_global_t stack_pointer_global;
+  wasm_globaltype_t *const_i32_type;
+  bool has_error;
+  uint32_t lexer_address;
+};
+
+typedef Array(char) StringData;
+
+// LanguageInWasmMemory - The memory layout of a `TSLanguage` when compiled to
+// wasm32. This is used to copy static language data out of the wasm memory.
+typedef struct {
+  uint32_t version;
+  uint32_t symbol_count;
+  uint32_t alias_count;
+  uint32_t token_count;
+  uint32_t external_token_count;
+  uint32_t state_count;
+  uint32_t large_state_count;
+  uint32_t production_id_count;
+  uint32_t field_count;
+  uint16_t max_alias_sequence_length;
+  int32_t parse_table;
+  int32_t small_parse_table;
+  int32_t small_parse_table_map;
+  int32_t parse_actions;
+  int32_t symbol_names;
+  int32_t field_names;
+  int32_t field_map_slices;
+  int32_t field_map_entries;
+  int32_t symbol_metadata;
+  int32_t public_symbol_map;
+  int32_t alias_map;
+  int32_t alias_sequences;
+  int32_t lex_modes;
+  int32_t lex_fn;
+  int32_t keyword_lex_fn;
+  TSSymbol keyword_capture_token;
+  struct {
+    int32_t states;
+    int32_t symbol_map;
+    int32_t create;
+    int32_t destroy;
+    int32_t scan;
+    int32_t serialize;
+    int32_t deserialize;
+  } external_scanner;
+  int32_t primary_state_ids;
+} LanguageInWasmMemory;
+
+// LexerInWasmMemory - The memory layout of a `TSLexer` when compiled to wasm32.
+// This is used to copy mutable lexing state in and out of the wasm memory.
+typedef struct {
+  int32_t lookahead;
+  TSSymbol result_symbol;
+  int32_t advance;
+  int32_t mark_end;
+  int32_t get_column;
+  int32_t is_at_included_range_start;
+  int32_t eof;
+} LexerInWasmMemory;
+
+static volatile uint32_t NEXT_LANGUAGE_ID;
+
+// Linear memory layout:
+// [ <-- stack | stdlib statics | lexer | language statics --> | serialization_buffer | heap --> ]
+#define MAX_MEMORY_SIZE (128 * 1024 * 1024 / MEMORY_PAGE_SIZE)
+
+/************************
+ * WasmDylinkMemoryInfo
+ ***********************/
+
+static uint8_t read_u8(const uint8_t **p, const uint8_t *end) {
+  return *(*p)++;
+}
+
+static inline uint64_t read_uleb128(const uint8_t **p, const uint8_t *end) {
+  uint64_t value = 0;
+  unsigned shift = 0;
+  do {
+    if (*p == end)  return UINT64_MAX;
+    value += (uint64_t)(**p & 0x7f) << shift;
+    shift += 7;
+  } while (*((*p)++) >= 128);
+  return value;
+}
+
+static bool wasm_dylink_info__parse(
+  const uint8_t *bytes,
+  size_t length,
+  WasmDylinkInfo *info
+) {
+  const uint8_t WASM_MAGIC_NUMBER[4] = {0, 'a', 's', 'm'};
+  const uint8_t WASM_VERSION[4] = {1, 0, 0, 0};
+  const uint8_t WASM_CUSTOM_SECTION = 0x0;
+  const uint8_t WASM_DYLINK_MEM_INFO = 0x1;
+
+  const uint8_t *p = bytes;
+  const uint8_t *end = bytes + length;
+
+  if (length < 8) return false;
+  if (memcmp(p, WASM_MAGIC_NUMBER, 4) != 0) return false;
+  p += 4;
+  if (memcmp(p, WASM_VERSION, 4) != 0) return false;
+  p += 4;
+
+  while (p < end) {
+    uint8_t section_id = read_u8(&p, end);
+    uint32_t section_length = read_uleb128(&p, end);
+    const uint8_t *section_end = p + section_length;
+    if (section_end > end) return false;
+
+    if (section_id == WASM_CUSTOM_SECTION) {
+      uint32_t name_length = read_uleb128(&p, section_end);
+      const uint8_t *name_end = p + name_length;
+      if (name_end > section_end) return false;
+
+      if (name_length == 8 && memcmp(p, "dylink.0", 8) == 0) {
+        p = name_end;
+        while (p < section_end) {
+          uint8_t subsection_type = read_u8(&p, section_end);
+          uint32_t subsection_size = read_uleb128(&p, section_end);
+          const uint8_t *subsection_end = p + subsection_size;
+          if (subsection_end > section_end) return false;
+          if (subsection_type == WASM_DYLINK_MEM_INFO) {
+            info->memory_size = read_uleb128(&p, subsection_end);
+            info->memory_align = read_uleb128(&p, subsection_end);
+            info->table_size = read_uleb128(&p, subsection_end);
+            info->table_align = read_uleb128(&p, subsection_end);
+            return true;
+          }
+          p = subsection_end;
+        }
+      }
+    }
+    p = section_end;
+  }
+  return false;
+}
+
+/*******************************************
+ * Native callbacks exposed to wasm modules
+ *******************************************/
+
+ static wasm_trap_t *callback__abort(
+  void *env,
+  wasmtime_caller_t* caller,
+  wasmtime_val_raw_t *args_and_results,
+  size_t args_and_results_len
+) {
+  return wasmtime_trap_new("wasm module called abort", 24);
+}
+
+static wasm_trap_t *callback__debug_message(
+  void *env,
+  wasmtime_caller_t* caller,
+  wasmtime_val_raw_t *args_and_results,
+  size_t args_and_results_len
+) {
+  wasmtime_context_t *context = wasmtime_caller_context(caller);
+  TSWasmStore *store = env;
+  ts_assert(args_and_results_len == 2);
+  uint32_t string_address = args_and_results[0].i32;
+  uint32_t value = args_and_results[1].i32;
+  uint8_t *memory = wasmtime_memory_data(context, &store->memory);
+  printf("DEBUG: %s %u\n", &memory[string_address], value);
+  return NULL;
+}
+
+static wasm_trap_t *callback__noop(
+  void *env,
+  wasmtime_caller_t* caller,
+  wasmtime_val_raw_t *args_and_results,
+  size_t args_and_results_len
+) {
+  return NULL;
+}
+
+static wasm_trap_t *callback__lexer_advance(
+  void *env,
+  wasmtime_caller_t* caller,
+  wasmtime_val_raw_t *args_and_results,
+  size_t args_and_results_len
+) {
+  wasmtime_context_t *context = wasmtime_caller_context(caller);
+  ts_assert(args_and_results_len == 2);
+
+  TSWasmStore *store = env;
+  TSLexer *lexer = store->current_lexer;
+  bool skip = args_and_results[1].i32;
+  lexer->advance(lexer, skip);
+
+  uint8_t *memory = wasmtime_memory_data(context, &store->memory);
+  memcpy(&memory[store->lexer_address], &lexer->lookahead, sizeof(lexer->lookahead));
+  return NULL;
+}
+
+static wasm_trap_t *callback__lexer_mark_end(
+  void *env,
+  wasmtime_caller_t* caller,
+  wasmtime_val_raw_t *args_and_results,
+  size_t args_and_results_len
+) {
+  TSWasmStore *store = env;
+  TSLexer *lexer = store->current_lexer;
+  lexer->mark_end(lexer);
+  return NULL;
+}
+
+static wasm_trap_t *callback__lexer_get_column(
+  void *env,
+  wasmtime_caller_t* caller,
+  wasmtime_val_raw_t *args_and_results,
+  size_t args_and_results_len
+) {
+  TSWasmStore *store = env;
+  TSLexer *lexer = store->current_lexer;
+  uint32_t result = lexer->get_column(lexer);
+  args_and_results[0].i32 = result;
+  return NULL;
+}
+
+static wasm_trap_t *callback__lexer_is_at_included_range_start(
+  void *env,
+  wasmtime_caller_t* caller,
+  wasmtime_val_raw_t *args_and_results,
+  size_t args_and_results_len
+) {
+  TSWasmStore *store = env;
+  TSLexer *lexer = store->current_lexer;
+  bool result = lexer->is_at_included_range_start(lexer);
+  args_and_results[0].i32 = result;
+  return NULL;
+}
+
+static wasm_trap_t *callback__lexer_eof(
+  void *env,
+  wasmtime_caller_t* caller,
+  wasmtime_val_raw_t *args_and_results,
+  size_t args_and_results_len
+) {
+  TSWasmStore *store = env;
+  TSLexer *lexer = store->current_lexer;
+  bool result = lexer->eof(lexer);
+  args_and_results[0].i32 = result;
+  return NULL;
+}
+
+typedef struct {
+  uint32_t *storage_location;
+  wasmtime_func_unchecked_callback_t callback;
+  wasm_functype_t *type;
+} FunctionDefinition;
+
+static void *copy(const void *data, size_t size) {
+  void *result = ts_malloc(size);
+  memcpy(result, data, size);
+  return result;
+}
+
+static void *copy_unsized_static_array(
+  const uint8_t *data,
+  int32_t start_address,
+  const int32_t all_addresses[],
+  size_t address_count
+) {
+  int32_t end_address = 0;
+  for (unsigned i = 0; i < address_count; i++) {
+    if (all_addresses[i] > start_address) {
+      if (!end_address || all_addresses[i] < end_address) {
+        end_address = all_addresses[i];
+      }
+    }
+  }
+
+  if (!end_address) return NULL;
+  size_t size = end_address - start_address;
+  void *result = ts_malloc(size);
+  memcpy(result, &data[start_address], size);
+  return result;
+}
+
+static void *copy_strings(
+  const uint8_t *data,
+  int32_t array_address,
+  size_t count,
+  StringData *string_data
+) {
+  const char **result = ts_malloc(count * sizeof(char *));
+  for (unsigned i = 0; i < count; i++) {
+    int32_t address;
+    memcpy(&address, &data[array_address + i * sizeof(address)], sizeof(address));
+    if (address == 0) {
+      result[i] = (const char *)-1;
+    } else {
+      const uint8_t *string = &data[address];
+      uint32_t len = strlen((const char *)string);
+      result[i] = (const char *)(uintptr_t)string_data->size;
+      array_extend(string_data, len + 1, string);
+    }
+  }
+  for (unsigned i = 0; i < count; i++) {
+    if (result[i] == (const char *)-1) {
+      result[i] = NULL;
+    } else {
+      result[i] = string_data->contents + (uintptr_t)result[i];
+    }
+  }
+  return result;
+}
+
+static bool name_eq(const wasm_name_t *name, const char *string) {
+  return strncmp(string, name->data, name->size) == 0;
+}
+
+static inline wasm_functype_t* wasm_functype_new_4_0(
+  wasm_valtype_t* p1,
+  wasm_valtype_t* p2,
+  wasm_valtype_t* p3,
+  wasm_valtype_t* p4
+) {
+  wasm_valtype_t* ps[4] = {p1, p2, p3, p4};
+  wasm_valtype_vec_t params, results;
+  wasm_valtype_vec_new(&params, 4, ps);
+  wasm_valtype_vec_new_empty(&results);
+  return wasm_functype_new(&params, &results);
+}
+
+#define format(output, ...) \
+  do { \
+    size_t message_length = snprintf((char *)NULL, 0, __VA_ARGS__); \
+    *output = ts_malloc(message_length + 1); \
+    snprintf(*output, message_length + 1, __VA_ARGS__); \
+  } while (0)
+
+WasmLanguageId *language_id_new(void) {
+  WasmLanguageId *self = ts_malloc(sizeof(WasmLanguageId));
+  self->is_language_deleted = false;
+  self->ref_count = 1;
+  return self;
+}
+
+WasmLanguageId *language_id_clone(WasmLanguageId *self) {
+  atomic_inc(&self->ref_count);
+  return self;
+}
+
+void language_id_delete(WasmLanguageId *self) {
+  if (atomic_dec(&self->ref_count) == 0) {
+    ts_free(self);
+  }
+}
+
+static wasmtime_extern_t get_builtin_extern(
+  wasmtime_table_t *table,
+  unsigned index
+) {
+  return (wasmtime_extern_t) {
+    .kind = WASMTIME_EXTERN_FUNC,
+    .of.func = (wasmtime_func_t) {
+      .store_id = table->store_id,
+      .__private = index
+    }
+  };
+}
+
+static bool ts_wasm_store__provide_builtin_import(
+  TSWasmStore *self,
+  const wasm_name_t *import_name,
+  wasmtime_extern_t *import
+) {
+  wasmtime_error_t *error = NULL;
+  wasmtime_context_t *context = wasmtime_store_context(self->store);
+
+  // Dynamic linking parameters
+  if (name_eq(import_name, "__memory_base")) {
+    wasmtime_val_t value = WASM_I32_VAL(self->current_memory_offset);
+    wasmtime_global_t global;
+    error = wasmtime_global_new(context, self->const_i32_type, &value, &global);
+    ts_assert(!error);
+    *import = (wasmtime_extern_t) {.kind = WASMTIME_EXTERN_GLOBAL, .of.global = global};
+  } else if (name_eq(import_name, "__table_base")) {
+    wasmtime_val_t value = WASM_I32_VAL(self->current_function_table_offset);
+    wasmtime_global_t global;
+    error = wasmtime_global_new(context, self->const_i32_type, &value, &global);
+    ts_assert(!error);
+    *import = (wasmtime_extern_t) {.kind = WASMTIME_EXTERN_GLOBAL, .of.global = global};
+  } else if (name_eq(import_name, "__stack_pointer")) {
+    *import = (wasmtime_extern_t) {.kind = WASMTIME_EXTERN_GLOBAL, .of.global = self->stack_pointer_global};
+  } else if (name_eq(import_name, "__indirect_function_table")) {
+    *import = (wasmtime_extern_t) {.kind = WASMTIME_EXTERN_TABLE, .of.table = self->function_table};
+  } else if (name_eq(import_name, "memory")) {
+    *import = (wasmtime_extern_t) {.kind = WASMTIME_EXTERN_MEMORY, .of.memory = self->memory};
+  }
+
+  // Builtin functions
+  else if (name_eq(import_name, "__assert_fail")) {
+    *import = get_builtin_extern(&self->function_table, self->builtin_fn_indices.assert_fail);
+  } else if (name_eq(import_name, "__cxa_atexit")) {
+    *import = get_builtin_extern(&self->function_table, self->builtin_fn_indices.at_exit);
+  } else if (name_eq(import_name, "args_get")) {
+    *import = get_builtin_extern(&self->function_table, self->builtin_fn_indices.args_get);
+  } else if (name_eq(import_name, "args_sizes_get")) {
+    *import = get_builtin_extern(&self->function_table, self->builtin_fn_indices.args_sizes_get);
+  } else if (name_eq(import_name, "abort")) {
+    *import = get_builtin_extern(&self->function_table, self->builtin_fn_indices.abort);
+  } else if (name_eq(import_name, "proc_exit")) {
+    *import = get_builtin_extern(&self->function_table, self->builtin_fn_indices.proc_exit);
+  } else if (name_eq(import_name, "emscripten_notify_memory_growth")) {
+    *import = get_builtin_extern(&self->function_table, self->builtin_fn_indices.notify_memory_growth);
+  } else if (name_eq(import_name, "tree_sitter_debug_message")) {
+    *import = get_builtin_extern(&self->function_table, self->builtin_fn_indices.debug_message);
+  } else {
+    return false;
+  }
+
+  return true;
+}
+
+static bool ts_wasm_store__call_module_initializer(
+  TSWasmStore *self,
+  const wasm_name_t *export_name,
+  wasmtime_extern_t *export,
+  wasm_trap_t **trap
+) {
+  if (
+    name_eq(export_name, "_initialize") ||
+    name_eq(export_name, "__wasm_apply_data_relocs") ||
+    name_eq(export_name, "__wasm_call_ctors")
+  ) {
+    wasmtime_context_t *context = wasmtime_store_context(self->store);
+    wasmtime_func_t initialization_func = export->of.func;
+    wasmtime_error_t *error = wasmtime_func_call(context, &initialization_func, NULL, 0, NULL, 0, trap);
+    ts_assert(!error);
+    return true;
+  } else {
+    return false;
+  }
+}
+
+TSWasmStore *ts_wasm_store_new(TSWasmEngine *engine, TSWasmError *wasm_error) {
+  TSWasmStore *self = ts_calloc(1, sizeof(TSWasmStore));
+  wasmtime_store_t *store = wasmtime_store_new(engine, self, NULL);
+  wasmtime_context_t *context = wasmtime_store_context(store);
+  wasmtime_error_t *error = NULL;
+  wasm_trap_t *trap = NULL;
+  wasm_message_t message = WASM_EMPTY_VEC;
+  wasm_exporttype_vec_t export_types = WASM_EMPTY_VEC;
+  wasmtime_extern_t *imports = NULL;
+  wasmtime_module_t *stdlib_module = NULL;
+  wasm_memorytype_t *memory_type = NULL;
+  wasm_tabletype_t *table_type = NULL;
+
+  // Define functions called by scanners via function pointers on the lexer.
+  LexerInWasmMemory lexer = {
+    .lookahead = 0,
+    .result_symbol = 0,
+  };
+  FunctionDefinition lexer_definitions[] = {
+    {
+      (uint32_t *)&lexer.advance,
+      callback__lexer_advance,
+      wasm_functype_new_2_0(wasm_valtype_new_i32(), wasm_valtype_new_i32())
+    },
+    {
+      (uint32_t *)&lexer.mark_end,
+      callback__lexer_mark_end,
+      wasm_functype_new_1_0(wasm_valtype_new_i32())
+    },
+    {
+      (uint32_t *)&lexer.get_column,
+      callback__lexer_get_column,
+      wasm_functype_new_1_1(wasm_valtype_new_i32(), wasm_valtype_new_i32())
+    },
+    {
+      (uint32_t *)&lexer.is_at_included_range_start,
+      callback__lexer_is_at_included_range_start,
+      wasm_functype_new_1_1(wasm_valtype_new_i32(), wasm_valtype_new_i32())
+    },
+    {
+      (uint32_t *)&lexer.eof,
+      callback__lexer_eof,
+      wasm_functype_new_1_1(wasm_valtype_new_i32(), wasm_valtype_new_i32())
+    },
+  };
+
+  // Define builtin functions that can be imported by scanners.
+  BuiltinFunctionIndices builtin_fn_indices;
+  FunctionDefinition builtin_definitions[] = {
+    {
+      &builtin_fn_indices.proc_exit,
+      callback__abort,
+      wasm_functype_new_1_0(wasm_valtype_new_i32())
+    },
+    {
+      &builtin_fn_indices.abort,
+      callback__abort,
+      wasm_functype_new_0_0()
+    },
+    {
+      &builtin_fn_indices.assert_fail,
+      callback__abort,
+      wasm_functype_new_4_0(wasm_valtype_new_i32(), wasm_valtype_new_i32(), wasm_valtype_new_i32(), wasm_valtype_new_i32())
+    },
+    {
+      &builtin_fn_indices.notify_memory_growth,
+      callback__noop,
+      wasm_functype_new_1_0(wasm_valtype_new_i32())
+    },
+    {
+      &builtin_fn_indices.debug_message,
+      callback__debug_message,
+      wasm_functype_new_2_0(wasm_valtype_new_i32(), wasm_valtype_new_i32())
+    },
+    {
+      &builtin_fn_indices.at_exit,
+      callback__noop,
+      wasm_functype_new_3_1(wasm_valtype_new_i32(), wasm_valtype_new_i32(), wasm_valtype_new_i32(), wasm_valtype_new_i32())
+    },
+    {
+      &builtin_fn_indices.args_get,
+      callback__noop,
+      wasm_functype_new_2_1(wasm_valtype_new_i32(), wasm_valtype_new_i32(), wasm_valtype_new_i32())
+    },
+    {
+      &builtin_fn_indices.args_sizes_get,
+      callback__noop,
+      wasm_functype_new_2_1(wasm_valtype_new_i32(), wasm_valtype_new_i32(), wasm_valtype_new_i32())
+    },
+  };
+
+  // Create all of the wasm functions.
+  unsigned builtin_definitions_len = array_len(builtin_definitions);
+  unsigned lexer_definitions_len = array_len(lexer_definitions);
+  for (unsigned i = 0; i < builtin_definitions_len; i++) {
+    FunctionDefinition *definition = &builtin_definitions[i];
+    wasmtime_func_t func;
+    wasmtime_func_new_unchecked(context, definition->type, definition->callback, self, NULL, &func);
+    *definition->storage_location = func.__private;
+    wasm_functype_delete(definition->type);
+  }
+  for (unsigned i = 0; i < lexer_definitions_len; i++) {
+    FunctionDefinition *definition = &lexer_definitions[i];
+    wasmtime_func_t func;
+    wasmtime_func_new_unchecked(context, definition->type, definition->callback, self, NULL, &func);
+    *definition->storage_location = func.__private;
+    wasm_functype_delete(definition->type);
+  }
+
+  // Compile the stdlib module.
+  error = wasmtime_module_new(engine, STDLIB_WASM, STDLIB_WASM_LEN, &stdlib_module);
+  if (error) {
+    wasmtime_error_message(error, &message);
+    wasm_error->kind = TSWasmErrorKindCompile;
+    format(
+      &wasm_error->message,
+      "failed to compile wasm stdlib: %.*s",
+      (int)message.size, message.data
+    );
+    goto error;
+  }
+
+  // Retrieve the stdlib module's imports.
+  wasm_importtype_vec_t import_types = WASM_EMPTY_VEC;
+  wasmtime_module_imports(stdlib_module, &import_types);
+
+  // Find the initial number of memory pages needed by the stdlib.
+  const wasm_memorytype_t *stdlib_memory_type;
+  for (unsigned i = 0; i < import_types.size; i++) {
+    wasm_importtype_t *import_type = import_types.data[i];
+    const wasm_name_t *import_name = wasm_importtype_name(import_type);
+    if (name_eq(import_name, "memory")) {
+      const wasm_externtype_t *type = wasm_importtype_type(import_type);
+      stdlib_memory_type = wasm_externtype_as_memorytype_const(type);
+    }
+  }
+  if (!stdlib_memory_type) {
+    wasm_error->kind = TSWasmErrorKindCompile;
+    format(
+      &wasm_error->message,
+      "wasm stdlib is missing the 'memory' import"
+    );
+    goto error;
+  }
+
+  // Initialize store's memory
+  uint64_t initial_memory_pages = wasmtime_memorytype_minimum(stdlib_memory_type);
+  wasm_limits_t memory_limits = {.min = initial_memory_pages, .max = MAX_MEMORY_SIZE};
+  memory_type = wasm_memorytype_new(&memory_limits);
+  wasmtime_memory_t memory;
+  error = wasmtime_memory_new(context, memory_type, &memory);
+  if (error) {
+    wasmtime_error_message(error, &message);
+    wasm_error->kind = TSWasmErrorKindAllocate;
+    format(
+      &wasm_error->message,
+      "failed to allocate wasm memory: %.*s",
+      (int)message.size, message.data
+    );
+    goto error;
+  }
+  wasm_memorytype_delete(memory_type);
+  memory_type = NULL;
+
+  // Initialize store's function table
+  wasm_limits_t table_limits = {.min = 1, .max = wasm_limits_max_default};
+  table_type = wasm_tabletype_new(wasm_valtype_new(WASM_FUNCREF), &table_limits);
+  wasmtime_val_t initializer = {.kind = WASMTIME_FUNCREF};
+  wasmtime_table_t function_table;
+  error = wasmtime_table_new(context, table_type, &initializer, &function_table);
+  if (error) {
+    wasmtime_error_message(error, &message);
+    wasm_error->kind = TSWasmErrorKindAllocate;
+    format(
+      &wasm_error->message,
+      "failed to allocate wasm table: %.*s",
+      (int)message.size, message.data
+    );
+    goto error;
+  }
+  wasm_tabletype_delete(table_type);
+  table_type = NULL;
+
+  unsigned stdlib_symbols_len = array_len(STDLIB_SYMBOLS);
+
+  // Define globals for the stack and heap start addresses.
+  wasm_globaltype_t *const_i32_type = wasm_globaltype_new(wasm_valtype_new_i32(), WASM_CONST);
+  wasm_globaltype_t *var_i32_type = wasm_globaltype_new(wasm_valtype_new_i32(), WASM_VAR);
+
+  wasmtime_val_t stack_pointer_value = WASM_I32_VAL(0);
+  wasmtime_global_t stack_pointer_global;
+  error = wasmtime_global_new(context, var_i32_type, &stack_pointer_value, &stack_pointer_global);
+  ts_assert(!error);
+
+  *self = (TSWasmStore) {
+    .engine = wasmtime_engine_clone(engine),
+    .store = store,
+    .memory = memory,
+    .function_table = function_table,
+    .language_instances = array_new(),
+    .stdlib_fn_indices = ts_calloc(stdlib_symbols_len, sizeof(uint32_t)),
+    .builtin_fn_indices = builtin_fn_indices,
+    .stack_pointer_global = stack_pointer_global,
+    .current_memory_offset = 0,
+    .current_function_table_offset = 0,
+    .const_i32_type = const_i32_type,
+  };
+
+  // Set up the imports for the stdlib module.
+  imports = ts_calloc(import_types.size, sizeof(wasmtime_extern_t));
+  for (unsigned i = 0; i < import_types.size; i++) {
+    wasm_importtype_t *type = import_types.data[i];
+    const wasm_name_t *import_name = wasm_importtype_name(type);
+    if (!ts_wasm_store__provide_builtin_import(self, import_name, &imports[i])) {
+      wasm_error->kind = TSWasmErrorKindInstantiate;
+      format(
+        &wasm_error->message,
+        "unexpected import in wasm stdlib: %.*s\n",
+        (int)import_name->size, import_name->data
+      );
+      goto error;
+    }
+  }
+
+  // Instantiate the stdlib module.
+  wasmtime_instance_t instance;
+  error = wasmtime_instance_new(context, stdlib_module, imports, import_types.size, &instance, &trap);
+  ts_free(imports);
+  imports = NULL;
+  if (error) {
+    wasmtime_error_message(error, &message);
+    wasm_error->kind = TSWasmErrorKindInstantiate;
+    format(
+      &wasm_error->message,
+      "failed to instantiate wasm stdlib module: %.*s",
+      (int)message.size, message.data
+    );
+    goto error;
+  }
+  if (trap) {
+    wasm_trap_message(trap, &message);
+    wasm_error->kind = TSWasmErrorKindInstantiate;
+    format(
+      &wasm_error->message,
+      "trapped when instantiating wasm stdlib module: %.*s",
+      (int)message.size, message.data
+    );
+    goto error;
+  }
+  wasm_importtype_vec_delete(&import_types);
+
+  // Process the stdlib module's exports.
+  for (unsigned i = 0; i < stdlib_symbols_len; i++) {
+    self->stdlib_fn_indices[i] = UINT32_MAX;
+  }
+  wasmtime_module_exports(stdlib_module, &export_types);
+  for (unsigned i = 0; i < export_types.size; i++) {
+    wasm_exporttype_t *export_type = export_types.data[i];
+    const wasm_name_t *name = wasm_exporttype_name(export_type);
+
+    char *export_name;
+    size_t name_len;
+    wasmtime_extern_t export = {.kind = WASM_EXTERN_GLOBAL};
+    bool exists = wasmtime_instance_export_nth(context, &instance, i, &export_name, &name_len, &export);
+    ts_assert(exists);
+
+    if (export.kind == WASMTIME_EXTERN_GLOBAL) {
+      if (name_eq(name, "__stack_pointer")) {
+        self->stack_pointer_global = export.of.global;
+      }
+    }
+
+    if (export.kind == WASMTIME_EXTERN_FUNC) {
+      if (ts_wasm_store__call_module_initializer(self, name, &export, &trap)) {
+        if (trap) {
+          wasm_trap_message(trap, &message);
+          wasm_error->kind = TSWasmErrorKindInstantiate;
+          format(
+            &wasm_error->message,
+            "trap when calling stdlib relocation function: %.*s\n",
+            (int)message.size, message.data
+          );
+          goto error;
+        }
+        continue;
+      }
+
+      if (name_eq(name, "reset_heap")) {
+        self->builtin_fn_indices.reset_heap = export.of.func.__private;
+        continue;
+      }
+
+      for (unsigned j = 0; j < stdlib_symbols_len; j++) {
+        if (name_eq(name, STDLIB_SYMBOLS[j])) {
+          self->stdlib_fn_indices[j] = export.of.func.__private;
+          break;
+        }
+      }
+    }
+  }
+
+  if (self->builtin_fn_indices.reset_heap == UINT32_MAX) {
+    wasm_error->kind = TSWasmErrorKindInstantiate;
+    format(
+      &wasm_error->message,
+      "missing malloc reset function in wasm stdlib"
+    );
+    goto error;
+  }
+
+  for (unsigned i = 0; i < stdlib_symbols_len; i++) {
+    if (self->stdlib_fn_indices[i] == UINT32_MAX) {
+      wasm_error->kind = TSWasmErrorKindInstantiate;
+      format(
+        &wasm_error->message,
+        "missing exported symbol in wasm stdlib: %s",
+        STDLIB_SYMBOLS[i]
+      );
+      goto error;
+    }
+  }
+
+  wasm_exporttype_vec_delete(&export_types);
+  wasmtime_module_delete(stdlib_module);
+
+  // Add all of the lexer callback functions to the function table. Store their function table
+  // indices on the in-memory lexer.
+  uint32_t table_index;
+  error = wasmtime_table_grow(context, &function_table, lexer_definitions_len, &initializer, &table_index);
+  if (error) {
+    wasmtime_error_message(error, &message);
+    wasm_error->kind = TSWasmErrorKindAllocate;
+    format(
+      &wasm_error->message,
+      "failed to grow wasm table to initial size: %.*s",
+      (int)message.size, message.data
+    );
+    goto error;
+  }
+  for (unsigned i = 0; i < lexer_definitions_len; i++) {
+    FunctionDefinition *definition = &lexer_definitions[i];
+    wasmtime_func_t func = {function_table.store_id, *definition->storage_location};
+    wasmtime_val_t func_val = {.kind = WASMTIME_FUNCREF, .of.funcref = func};
+    error = wasmtime_table_set(context, &function_table, table_index, &func_val);
+    ts_assert(!error);
+    *(int32_t *)(definition->storage_location) = table_index;
+    table_index++;
+  }
+
+  self->current_function_table_offset = table_index;
+  self->lexer_address = initial_memory_pages * MEMORY_PAGE_SIZE;
+  self->current_memory_offset = self->lexer_address + sizeof(LexerInWasmMemory);
+
+  // Grow the memory enough to hold the builtin lexer and serialization buffer.
+  uint32_t new_pages_needed = (self->current_memory_offset - self->lexer_address - 1) / MEMORY_PAGE_SIZE + 1;
+  uint64_t prev_memory_size;
+  wasmtime_memory_grow(context, &memory, new_pages_needed, &prev_memory_size);
+
+  uint8_t *memory_data = wasmtime_memory_data(context, &memory);
+  memcpy(&memory_data[self->lexer_address], &lexer, sizeof(lexer));
+  return self;
+
+error:
+  ts_free(self);
+  if (stdlib_module) wasmtime_module_delete(stdlib_module);
+  if (store) wasmtime_store_delete(store);
+  if (import_types.size) wasm_importtype_vec_delete(&import_types);
+  if (memory_type) wasm_memorytype_delete(memory_type);
+  if (table_type) wasm_tabletype_delete(table_type);
+  if (trap) wasm_trap_delete(trap);
+  if (error) wasmtime_error_delete(error);
+  if (message.size) wasm_byte_vec_delete(&message);
+  if (export_types.size) wasm_exporttype_vec_delete(&export_types);
+  if (imports) ts_free(imports);
+  return NULL;
+}
+
+void ts_wasm_store_delete(TSWasmStore *self) {
+  if (!self) return;
+  ts_free(self->stdlib_fn_indices);
+  wasm_globaltype_delete(self->const_i32_type);
+  wasmtime_store_delete(self->store);
+  wasm_engine_delete(self->engine);
+  for (unsigned i = 0; i < self->language_instances.size; i++) {
+    LanguageWasmInstance *instance = &self->language_instances.contents[i];
+    language_id_delete(instance->language_id);
+  }
+  array_delete(&self->language_instances);
+  ts_free(self);
+}
+
+size_t ts_wasm_store_language_count(const TSWasmStore *self) {
+  size_t result = 0;
+  for (unsigned i = 0; i < self->language_instances.size; i++) {
+    const WasmLanguageId *id = self->language_instances.contents[i].language_id;
+    if (!id->is_language_deleted) {
+      result++;
+    }
+  }
+  return result;
+}
+
+static uint32_t ts_wasm_store__heap_address(TSWasmStore *self) {
+  return self->current_memory_offset + TREE_SITTER_SERIALIZATION_BUFFER_SIZE;
+}
+
+static uint32_t ts_wasm_store__serialization_buffer_address(TSWasmStore *self) {
+  return self->current_memory_offset;
+}
+
+static bool ts_wasm_store__instantiate(
+  TSWasmStore *self,
+  wasmtime_module_t *module,
+  const char *language_name,
+  const WasmDylinkInfo *dylink_info,
+  wasmtime_instance_t *result,
+  int32_t *language_address,
+  char **error_message
+) {
+  wasmtime_error_t *error = NULL;
+  wasm_trap_t *trap = NULL;
+  wasm_message_t message = WASM_EMPTY_VEC;
+  char *language_function_name = NULL;
+  wasmtime_extern_t *imports = NULL;
+  wasmtime_context_t *context = wasmtime_store_context(self->store);
+
+  // Grow the function table to make room for the new functions.
+  wasmtime_val_t initializer = {.kind = WASMTIME_FUNCREF};
+  uint32_t prev_table_size;
+  error = wasmtime_table_grow(context, &self->function_table, dylink_info->table_size, &initializer, &prev_table_size);
+  if (error) {
+    format(error_message, "invalid function table size %u", dylink_info->table_size);
+    goto error;
+  }
+
+  // Grow the memory to make room for the new data.
+  uint32_t needed_memory_size = ts_wasm_store__heap_address(self) + dylink_info->memory_size;
+  uint32_t current_memory_size = wasmtime_memory_data_size(context, &self->memory);
+  if (needed_memory_size > current_memory_size) {
+    uint32_t pages_to_grow = (
+      needed_memory_size - current_memory_size + MEMORY_PAGE_SIZE - 1) /
+      MEMORY_PAGE_SIZE;
+    uint64_t prev_memory_size;
+    error = wasmtime_memory_grow(context, &self->memory, pages_to_grow, &prev_memory_size);
+    if (error) {
+      format(error_message, "invalid memory size %u", dylink_info->memory_size);
+      goto error;
+    }
+  }
+
+  // Construct the language function name as string.
+  format(&language_function_name, "tree_sitter_%s", language_name);
+
+  const uint64_t store_id = self->function_table.store_id;
+
+  // Build the imports list for the module.
+  wasm_importtype_vec_t import_types = WASM_EMPTY_VEC;
+  wasmtime_module_imports(module, &import_types);
+  imports = ts_calloc(import_types.size, sizeof(wasmtime_extern_t));
+
+  for (unsigned i = 0; i < import_types.size; i++) {
+    const wasm_importtype_t *import_type = import_types.data[i];
+    const wasm_name_t *import_name = wasm_importtype_name(import_type);
+    if (import_name->size == 0) {
+      format(error_message, "empty import name");
+      goto error;
+    }
+
+    if (ts_wasm_store__provide_builtin_import(self, import_name, &imports[i])) {
+      continue;
+    }
+
+    bool defined_in_stdlib = false;
+    for (unsigned j = 0; j < array_len(STDLIB_SYMBOLS); j++) {
+      if (name_eq(import_name, STDLIB_SYMBOLS[j])) {
+        uint16_t address = self->stdlib_fn_indices[j];
+        imports[i] = (wasmtime_extern_t) {.kind = WASMTIME_EXTERN_FUNC, .of.func = {store_id, address}};
+        defined_in_stdlib = true;
+        break;
+      }
+    }
+
+    if (!defined_in_stdlib) {
+      format(
+        error_message,
+        "invalid import '%.*s'\n",
+        (int)import_name->size, import_name->data
+      );
+      goto error;
+    }
+  }
+
+  wasmtime_instance_t instance;
+  error = wasmtime_instance_new(context, module, imports, import_types.size, &instance, &trap);
+  wasm_importtype_vec_delete(&import_types);
+  ts_free(imports);
+  imports = NULL;
+  if (error) {
+    wasmtime_error_message(error, &message);
+    format(
+      error_message,
+      "error instantiating wasm module: %.*s\n",
+      (int)message.size, message.data
+    );
+    goto error;
+  }
+  if (trap) {
+    wasm_trap_message(trap, &message);
+    format(
+      error_message,
+      "trap when instantiating wasm module: %.*s\n",
+      (int)message.size, message.data
+    );
+    goto error;
+  }
+
+  self->current_memory_offset += dylink_info->memory_size;
+  self->current_function_table_offset += dylink_info->table_size;
+
+  // Process the module's exports.
+  bool found_language = false;
+  wasmtime_extern_t language_extern;
+  wasm_exporttype_vec_t export_types = WASM_EMPTY_VEC;
+  wasmtime_module_exports(module, &export_types);
+  for (unsigned i = 0; i < export_types.size; i++) {
+    wasm_exporttype_t *export_type = export_types.data[i];
+    const wasm_name_t *name = wasm_exporttype_name(export_type);
+
+    size_t name_len;
+    char *export_name;
+    wasmtime_extern_t export = {.kind = WASM_EXTERN_GLOBAL};
+    bool exists = wasmtime_instance_export_nth(context, &instance, i, &export_name, &name_len, &export);
+    ts_assert(exists);
+
+    // If the module exports an initialization or data-relocation function, call it.
+    if (ts_wasm_store__call_module_initializer(self, name, &export, &trap)) {
+      if (trap) {
+        wasm_trap_message(trap, &message);
+        format(
+          error_message,
+          "trap when calling data relocation function: %.*s\n",
+          (int)message.size, message.data
+        );
+        goto error;
+      }
+    }
+
+    // Find the main language function for the module.
+    else if (name_eq(name, language_function_name)) {
+      language_extern = export;
+      found_language = true;
+    }
+  }
+  wasm_exporttype_vec_delete(&export_types);
+
+  if (!found_language) {
+    format(
+      error_message,
+      "module did not contain language function: %s",
+      language_function_name
+    );
+    goto error;
+  }
+
+  // Invoke the language function to get the static address of the language object.
+  wasmtime_func_t language_func = language_extern.of.func;
+  wasmtime_val_t language_address_val;
+  error = wasmtime_func_call(context, &language_func, NULL, 0, &language_address_val, 1, &trap);
+  ts_assert(!error);
+  if (trap) {
+    wasm_trap_message(trap, &message);
+    format(
+      error_message,
+      "trapped when calling language function: %s: %.*s\n",
+      language_function_name, (int)message.size, message.data
+    );
+    goto error;
+  }
+
+  if (language_address_val.kind != WASMTIME_I32) {
+    format(
+      error_message,
+      "language function did not return an integer: %s\n",
+      language_function_name
+    );
+    goto error;
+  }
+
+  ts_free(language_function_name);
+  *result = instance;
+  *language_address = language_address_val.of.i32;
+  return true;
+
+error:
+  if (language_function_name) ts_free(language_function_name);
+  if (message.size) wasm_byte_vec_delete(&message);
+  if (error) wasmtime_error_delete(error);
+  if (trap) wasm_trap_delete(trap);
+  if (imports) ts_free(imports);
+  return false;
+}
+
+static bool ts_wasm_store__sentinel_lex_fn(TSLexer *_lexer, TSStateId state) {
+  return false;
+}
+
+const TSLanguage *ts_wasm_store_load_language(
+  TSWasmStore *self,
+  const char *language_name,
+  const char *wasm,
+  uint32_t wasm_len,
+  TSWasmError *wasm_error
+) {
+  WasmDylinkInfo dylink_info;
+  wasmtime_module_t *module = NULL;
+  wasmtime_error_t *error = NULL;
+  wasm_error->kind = TSWasmErrorKindNone;
+
+  if (!wasm_dylink_info__parse((const unsigned char *)wasm, wasm_len, &dylink_info)) {
+    wasm_error->kind = TSWasmErrorKindParse;
+    format(&wasm_error->message, "failed to parse dylink section of wasm module");
+    goto error;
+  }
+
+  // Compile the wasm code.
+  error = wasmtime_module_new(self->engine, (const uint8_t *)wasm, wasm_len, &module);
+  if (error) {
+    wasm_message_t message;
+    wasmtime_error_message(error, &message);
+    wasm_error->kind = TSWasmErrorKindCompile;
+    format(&wasm_error->message, "error compiling wasm module: %.*s", (int)message.size, message.data);
+    wasm_byte_vec_delete(&message);
+    goto error;
+  }
+
+  // Instantiate the module in this store.
+  wasmtime_instance_t instance;
+  int32_t language_address;
+  if (!ts_wasm_store__instantiate(
+    self,
+    module,
+    language_name,
+    &dylink_info,
+    &instance,
+    &language_address,
+    &wasm_error->message
+  )) {
+    wasm_error->kind = TSWasmErrorKindInstantiate;
+    goto error;
+  }
+
+  // Copy all of the static data out of the language object in wasm memory,
+  // constructing a native language object.
+  LanguageInWasmMemory wasm_language;
+  wasmtime_context_t *context = wasmtime_store_context(self->store);
+  const uint8_t *memory = wasmtime_memory_data(context, &self->memory);
+  memcpy(&wasm_language, &memory[language_address], sizeof(LanguageInWasmMemory));
+
+  if (wasm_language.version < LANGUAGE_VERSION_USABLE_VIA_WASM) {
+      wasm_error->kind = TSWasmErrorKindInstantiate;
+      format(&wasm_error->message, "language version %u is too old for wasm", wasm_language.version);
+      goto error;
+  }
+
+  int32_t addresses[] = {
+    wasm_language.alias_map,
+    wasm_language.alias_sequences,
+    wasm_language.field_map_entries,
+    wasm_language.field_map_slices,
+    wasm_language.field_names,
+    wasm_language.keyword_lex_fn,
+    wasm_language.lex_fn,
+    wasm_language.lex_modes,
+    wasm_language.parse_actions,
+    wasm_language.parse_table,
+    wasm_language.primary_state_ids,
+    wasm_language.primary_state_ids,
+    wasm_language.public_symbol_map,
+    wasm_language.small_parse_table,
+    wasm_language.small_parse_table_map,
+    wasm_language.symbol_metadata,
+    wasm_language.symbol_metadata,
+    wasm_language.symbol_names,
+    wasm_language.external_token_count > 0 ? wasm_language.external_scanner.states : 0,
+    wasm_language.external_token_count > 0 ? wasm_language.external_scanner.symbol_map : 0,
+    wasm_language.external_token_count > 0 ? wasm_language.external_scanner.create : 0,
+    wasm_language.external_token_count > 0 ? wasm_language.external_scanner.destroy : 0,
+    wasm_language.external_token_count > 0 ? wasm_language.external_scanner.scan : 0,
+    wasm_language.external_token_count > 0 ? wasm_language.external_scanner.serialize : 0,
+    wasm_language.external_token_count > 0 ? wasm_language.external_scanner.deserialize : 0,
+    language_address,
+    self->current_memory_offset,
+  };
+  uint32_t address_count = array_len(addresses);
+
+  TSLanguage *language = ts_calloc(1, sizeof(TSLanguage));
+  StringData symbol_name_buffer = array_new();
+  StringData field_name_buffer = array_new();
+
+  *language = (TSLanguage) {
+    .version = wasm_language.version,
+    .symbol_count = wasm_language.symbol_count,
+    .alias_count = wasm_language.alias_count,
+    .token_count = wasm_language.token_count,
+    .external_token_count = wasm_language.external_token_count,
+    .state_count = wasm_language.state_count,
+    .large_state_count = wasm_language.large_state_count,
+    .production_id_count = wasm_language.production_id_count,
+    .field_count = wasm_language.field_count,
+    .max_alias_sequence_length = wasm_language.max_alias_sequence_length,
+    .keyword_capture_token = wasm_language.keyword_capture_token,
+    .parse_table = copy(
+      &memory[wasm_language.parse_table],
+      wasm_language.large_state_count * wasm_language.symbol_count * sizeof(uint16_t)
+    ),
+    .parse_actions = copy_unsized_static_array(
+      memory,
+      wasm_language.parse_actions,
+      addresses,
+      address_count
+    ),
+    .symbol_names = copy_strings(
+      memory,
+      wasm_language.symbol_names,
+      wasm_language.symbol_count + wasm_language.alias_count,
+      &symbol_name_buffer
+    ),
+    .symbol_metadata = copy(
+      &memory[wasm_language.symbol_metadata],
+      (wasm_language.symbol_count + wasm_language.alias_count) * sizeof(TSSymbolMetadata)
+    ),
+    .public_symbol_map = copy(
+      &memory[wasm_language.public_symbol_map],
+      (wasm_language.symbol_count + wasm_language.alias_count) * sizeof(TSSymbol)
+    ),
+    .lex_modes = copy(
+      &memory[wasm_language.lex_modes],
+      wasm_language.state_count * sizeof(TSLexMode)
+    ),
+  };
+
+  if (language->field_count > 0 && language->production_id_count > 0) {
+    language->field_map_slices = copy(
+      &memory[wasm_language.field_map_slices],
+      wasm_language.production_id_count * sizeof(TSFieldMapSlice)
+    );
+
+    // Determine the number of field map entries by finding the greatest index
+    // in any of the slices.
+    uint32_t field_map_entry_count = 0;
+    for (uint32_t i = 0; i < wasm_language.production_id_count; i++) {
+      TSFieldMapSlice slice = language->field_map_slices[i];
+      uint32_t slice_end = slice.index + slice.length;
+      if (slice_end > field_map_entry_count) {
+        field_map_entry_count = slice_end;
+      }
+    }
+
+    language->field_map_entries = copy(
+      &memory[wasm_language.field_map_entries],
+      field_map_entry_count * sizeof(TSFieldMapEntry)
+    );
+    language->field_names = copy_strings(
+      memory,
+      wasm_language.field_names,
+      wasm_language.field_count + 1,
+      &field_name_buffer
+    );
+  }
+
+  if (language->max_alias_sequence_length > 0 && language->production_id_count > 0) {
+    // The alias map contains symbols, alias counts, and aliases, terminated by a null symbol.
+    int32_t alias_map_size = 0;
+    for (;;) {
+      TSSymbol symbol;
+      memcpy(&symbol, &memory[wasm_language.alias_map + alias_map_size], sizeof(symbol));
+      alias_map_size += sizeof(TSSymbol);
+      if (symbol == 0) break;
+      uint16_t value_count;
+      memcpy(&value_count, &memory[wasm_language.alias_map + alias_map_size], sizeof(value_count));
+      alias_map_size += value_count * sizeof(TSSymbol);
+    }
+    language->alias_map = copy(
+      &memory[wasm_language.alias_map],
+      alias_map_size * sizeof(TSSymbol)
+    );
+    language->alias_sequences = copy(
+      &memory[wasm_language.alias_sequences],
+      wasm_language.production_id_count * wasm_language.max_alias_sequence_length * sizeof(TSSymbol)
+    );
+  }
+
+  if (language->state_count > language->large_state_count) {
+    uint32_t small_state_count = wasm_language.state_count - wasm_language.large_state_count;
+    language->small_parse_table_map = copy(
+      &memory[wasm_language.small_parse_table_map],
+      small_state_count * sizeof(uint32_t)
+    );
+    language->small_parse_table = copy_unsized_static_array(
+      memory,
+      wasm_language.small_parse_table,
+      addresses,
+      address_count
+    );
+  }
+
+  if (language->version >= LANGUAGE_VERSION_WITH_PRIMARY_STATES) {
+    language->primary_state_ids = copy(
+      &memory[wasm_language.primary_state_ids],
+      wasm_language.state_count * sizeof(TSStateId)
+    );
+  }
+
+  if (language->external_token_count > 0) {
+    language->external_scanner.symbol_map = copy(
+      &memory[wasm_language.external_scanner.symbol_map],
+      wasm_language.external_token_count * sizeof(TSSymbol)
+    );
+    language->external_scanner.states = (void *)(uintptr_t)wasm_language.external_scanner.states;
+  }
+
+  unsigned name_len = strlen(language_name);
+  char *name = ts_malloc(name_len + 1);
+  memcpy(name, language_name, name_len);
+  name[name_len] = '\0';
+
+  LanguageWasmModule *language_module = ts_malloc(sizeof(LanguageWasmModule));
+  *language_module = (LanguageWasmModule) {
+    .language_id = language_id_new(),
+    .module = module,
+    .name = name,
+    .symbol_name_buffer = symbol_name_buffer.contents,
+    .field_name_buffer = field_name_buffer.contents,
+    .dylink_info = dylink_info,
+    .ref_count = 1,
+  };
+
+  // The lex functions are not used for wasm languages. Use those two fields
+  // to mark this language as WASM-based and to store the language's
+  // WASM-specific data.
+  language->lex_fn = ts_wasm_store__sentinel_lex_fn;
+  language->keyword_lex_fn = (bool (*)(TSLexer *, TSStateId))language_module;
+
+  // Clear out any instances of languages that have been deleted.
+  for (unsigned i = 0; i < self->language_instances.size; i++) {
+    WasmLanguageId *id = self->language_instances.contents[i].language_id;
+    if (id->is_language_deleted) {
+      language_id_delete(id);
+      array_erase(&self->language_instances, i);
+      i--;
+    }
+  }
+
+  // Store this store's instance of this language module.
+  array_push(&self->language_instances, ((LanguageWasmInstance) {
+    .language_id = language_id_clone(language_module->language_id),
+    .instance = instance,
+    .external_states_address = wasm_language.external_scanner.states,
+    .lex_main_fn_index = wasm_language.lex_fn,
+    .lex_keyword_fn_index = wasm_language.keyword_lex_fn,
+    .scanner_create_fn_index = wasm_language.external_scanner.create,
+    .scanner_destroy_fn_index = wasm_language.external_scanner.destroy,
+    .scanner_serialize_fn_index = wasm_language.external_scanner.serialize,
+    .scanner_deserialize_fn_index = wasm_language.external_scanner.deserialize,
+    .scanner_scan_fn_index = wasm_language.external_scanner.scan,
+  }));
+
+  return language;
+
+error:
+  if (module) wasmtime_module_delete(module);
+  return NULL;
+}
+
+bool ts_wasm_store_add_language(
+  TSWasmStore *self,
+  const TSLanguage *language,
+  uint32_t *index
+) {
+  wasmtime_context_t *context = wasmtime_store_context(self->store);
+  const LanguageWasmModule *language_module = (void *)language->keyword_lex_fn;
+
+  // Search for this store's instance of the language module. Also clear out any
+  // instances of languages that have been deleted.
+  bool exists = false;
+  for (unsigned i = 0; i < self->language_instances.size; i++) {
+    WasmLanguageId *id = self->language_instances.contents[i].language_id;
+    if (id->is_language_deleted) {
+      language_id_delete(id);
+      array_erase(&self->language_instances, i);
+      i--;
+    } else if (id == language_module->language_id) {
+      exists = true;
+      *index = i;
+    }
+  }
+
+  // If the language module has not been instantiated in this store, then add
+  // it to this store.
+  if (!exists) {
+    *index = self->language_instances.size;
+    char *message;
+    wasmtime_instance_t instance;
+    int32_t language_address;
+    if (!ts_wasm_store__instantiate(
+      self,
+      language_module->module,
+      language_module->name,
+      &language_module->dylink_info,
+      &instance,
+      &language_address,
+      &message
+    )) {
+      ts_free(message);
+      return false;
+    }
+
+    LanguageInWasmMemory wasm_language;
+    const uint8_t *memory = wasmtime_memory_data(context, &self->memory);
+    memcpy(&wasm_language, &memory[language_address], sizeof(LanguageInWasmMemory));
+    array_push(&self->language_instances, ((LanguageWasmInstance) {
+      .language_id = language_id_clone(language_module->language_id),
+      .instance = instance,
+      .external_states_address = wasm_language.external_scanner.states,
+      .lex_main_fn_index = wasm_language.lex_fn,
+      .lex_keyword_fn_index = wasm_language.keyword_lex_fn,
+      .scanner_create_fn_index = wasm_language.external_scanner.create,
+      .scanner_destroy_fn_index = wasm_language.external_scanner.destroy,
+      .scanner_serialize_fn_index = wasm_language.external_scanner.serialize,
+      .scanner_deserialize_fn_index = wasm_language.external_scanner.deserialize,
+      .scanner_scan_fn_index = wasm_language.external_scanner.scan,
+    }));
+  }
+
+  return true;
+}
+
+void ts_wasm_store_reset_heap(TSWasmStore *self) {
+  wasmtime_context_t *context = wasmtime_store_context(self->store);
+  wasmtime_func_t func = {
+    self->function_table.store_id,
+    self->builtin_fn_indices.reset_heap
+  };
+  wasm_trap_t *trap = NULL;
+  wasmtime_val_t args[1] = {
+    {.of.i32 = ts_wasm_store__heap_address(self), .kind = WASMTIME_I32},
+  };
+
+  wasmtime_error_t *error = wasmtime_func_call(context, &func, args, 1, NULL, 0, &trap);
+  ts_assert(!error);
+  ts_assert(!trap);
+}
+
+bool ts_wasm_store_start(TSWasmStore *self, TSLexer *lexer, const TSLanguage *language) {
+  uint32_t instance_index;
+  if (!ts_wasm_store_add_language(self, language, &instance_index)) return false;
+  self->current_lexer = lexer;
+  self->current_instance = &self->language_instances.contents[instance_index];
+  self->has_error = false;
+  ts_wasm_store_reset_heap(self);
+  return true;
+}
+
+void ts_wasm_store_reset(TSWasmStore *self) {
+  self->current_lexer = NULL;
+  self->current_instance = NULL;
+  self->has_error = false;
+  ts_wasm_store_reset_heap(self);
+}
+
+static void ts_wasm_store__call(
+  TSWasmStore *self,
+  int32_t function_index,
+  wasmtime_val_raw_t *args_and_results,
+  size_t args_and_results_len
+) {
+  wasmtime_context_t *context = wasmtime_store_context(self->store);
+  wasmtime_val_t value;
+  bool succeeded = wasmtime_table_get(context, &self->function_table, function_index, &value);
+  ts_assert(succeeded);
+  ts_assert(value.kind == WASMTIME_FUNCREF);
+  wasmtime_func_t func = value.of.funcref;
+
+  wasm_trap_t *trap = NULL;
+  wasmtime_error_t *error = wasmtime_func_call_unchecked(context, &func, args_and_results, args_and_results_len, &trap);
+  if (error) {
+    // wasm_message_t message;
+    // wasmtime_error_message(error, &message);
+    // fprintf(
+    //   stderr,
+    //   "error in wasm module: %.*s\n",
+    //   (int)message.size, message.data
+    // );
+    wasmtime_error_delete(error);
+    self->has_error = true;
+  } else if (trap) {
+    // wasm_message_t message;
+    // wasm_trap_message(trap, &message);
+    // fprintf(
+    //   stderr,
+    //   "trap in wasm module: %.*s\n",
+    //   (int)message.size, message.data
+    // );
+    wasm_trap_delete(trap);
+    self->has_error = true;
+  }
+}
+
+static bool ts_wasm_store__call_lex_function(TSWasmStore *self, unsigned function_index, TSStateId state) {
+  wasmtime_context_t *context = wasmtime_store_context(self->store);
+  uint8_t *memory_data = wasmtime_memory_data(context, &self->memory);
+  memcpy(
+    &memory_data[self->lexer_address],
+    &self->current_lexer->lookahead,
+    sizeof(self->current_lexer->lookahead)
+  );
+
+  wasmtime_val_raw_t args[2] = {
+    {.i32 = self->lexer_address},
+    {.i32 = state},
+  };
+  ts_wasm_store__call(self, function_index, args, 2);
+  if (self->has_error) return false;
+  bool result = args[0].i32;
+
+  memcpy(
+    &self->current_lexer->lookahead,
+    &memory_data[self->lexer_address],
+    sizeof(self->current_lexer->lookahead) + sizeof(self->current_lexer->result_symbol)
+  );
+  return result;
+}
+
+bool ts_wasm_store_call_lex_main(TSWasmStore *self, TSStateId state) {
+  return ts_wasm_store__call_lex_function(
+    self,
+    self->current_instance->lex_main_fn_index,
+    state
+  );
+}
+
+bool ts_wasm_store_call_lex_keyword(TSWasmStore *self, TSStateId state) {
+  return ts_wasm_store__call_lex_function(
+    self,
+    self->current_instance->lex_keyword_fn_index,
+    state
+  );
+}
+
+uint32_t ts_wasm_store_call_scanner_create(TSWasmStore *self) {
+  wasmtime_val_raw_t args[1] = {{.i32 = 0}};
+  ts_wasm_store__call(self, self->current_instance->scanner_create_fn_index, args, 1);
+  if (self->has_error) return 0;
+  return args[0].i32;
+}
+
+void ts_wasm_store_call_scanner_destroy(TSWasmStore *self, uint32_t scanner_address) {
+  if (self->current_instance) {
+    wasmtime_val_raw_t args[1] = {{.i32 = scanner_address}};
+    ts_wasm_store__call(self, self->current_instance->scanner_destroy_fn_index, args, 1);
+  }
+}
+
+bool ts_wasm_store_call_scanner_scan(
+  TSWasmStore *self,
+  uint32_t scanner_address,
+  uint32_t valid_tokens_ix
+) {
+  wasmtime_context_t *context = wasmtime_store_context(self->store);
+  uint8_t *memory_data = wasmtime_memory_data(context, &self->memory);
+
+  memcpy(
+    &memory_data[self->lexer_address],
+    &self->current_lexer->lookahead,
+    sizeof(self->current_lexer->lookahead)
+  );
+
+  uint32_t valid_tokens_address =
+    self->current_instance->external_states_address +
+    (valid_tokens_ix * sizeof(bool));
+  wasmtime_val_raw_t args[3] = {
+    {.i32 = scanner_address},
+    {.i32 = self->lexer_address},
+    {.i32 = valid_tokens_address}
+  };
+  ts_wasm_store__call(self, self->current_instance->scanner_scan_fn_index, args, 3);
+  if (self->has_error) return false;
+
+  memcpy(
+    &self->current_lexer->lookahead,
+    &memory_data[self->lexer_address],
+    sizeof(self->current_lexer->lookahead) + sizeof(self->current_lexer->result_symbol)
+  );
+  return args[0].i32;
+}
+
+uint32_t ts_wasm_store_call_scanner_serialize(
+  TSWasmStore *self,
+  uint32_t scanner_address,
+  char *buffer
+) {
+  wasmtime_context_t *context = wasmtime_store_context(self->store);
+  uint8_t *memory_data = wasmtime_memory_data(context, &self->memory);
+  uint32_t serialization_buffer_address = ts_wasm_store__serialization_buffer_address(self);
+
+  wasmtime_val_raw_t args[2] = {
+    {.i32 = scanner_address},
+    {.i32 = serialization_buffer_address},
+  };
+  ts_wasm_store__call(self, self->current_instance->scanner_serialize_fn_index, args, 2);
+  if (self->has_error) return 0;
+
+  uint32_t length = args[0].i32;
+  if (length > TREE_SITTER_SERIALIZATION_BUFFER_SIZE) {
+      self->has_error = true;
+      return 0;
+  }
+
+  if (length > 0) {
+    memcpy(
+      ((Lexer *)self->current_lexer)->debug_buffer,
+      &memory_data[serialization_buffer_address],
+      length
+    );
+  }
+  return length;
+}
+
+void ts_wasm_store_call_scanner_deserialize(
+  TSWasmStore *self,
+  uint32_t scanner_address,
+  const char *buffer,
+  unsigned length
+) {
+  wasmtime_context_t *context = wasmtime_store_context(self->store);
+  uint8_t *memory_data = wasmtime_memory_data(context, &self->memory);
+  uint32_t serialization_buffer_address = ts_wasm_store__serialization_buffer_address(self);
+
+  if (length > 0) {
+    memcpy(
+      &memory_data[serialization_buffer_address],
+      buffer,
+      length
+    );
+  }
+
+  wasmtime_val_raw_t args[3] = {
+    {.i32 = scanner_address},
+    {.i32 = serialization_buffer_address},
+    {.i32 = length},
+  };
+  ts_wasm_store__call(self, self->current_instance->scanner_deserialize_fn_index, args, 3);
+}
+
+bool ts_wasm_store_has_error(const TSWasmStore *self) {
+  return self->has_error;
+}
+
+bool ts_language_is_wasm(const TSLanguage *self) {
+  return self->lex_fn == ts_wasm_store__sentinel_lex_fn;
+}
+
+static inline LanguageWasmModule *ts_language__wasm_module(const TSLanguage *self) {
+  return (LanguageWasmModule *)self->keyword_lex_fn;
+}
+
+void ts_wasm_language_retain(const TSLanguage *self) {
+  LanguageWasmModule *module = ts_language__wasm_module(self);
+  ts_assert(module->ref_count > 0);
+  atomic_inc(&module->ref_count);
+}
+
+void ts_wasm_language_release(const TSLanguage *self) {
+  LanguageWasmModule *module = ts_language__wasm_module(self);
+  ts_assert(module->ref_count > 0);
+  if (atomic_dec(&module->ref_count) == 0) {
+    // Update the language id to reflect that the language is deleted. This allows any wasm stores
+    // that hold wasm instances for this language to delete those instances.
+    atomic_inc(&module->language_id->is_language_deleted);
+    language_id_delete(module->language_id);
+
+    ts_free((void *)module->field_name_buffer);
+    ts_free((void *)module->symbol_name_buffer);
+    ts_free((void *)module->name);
+    wasmtime_module_delete(module->module);
+    ts_free(module);
+
+    ts_free((void *)self->alias_map);
+    ts_free((void *)self->alias_sequences);
+    ts_free((void *)self->external_scanner.symbol_map);
+    ts_free((void *)self->field_map_entries);
+    ts_free((void *)self->field_map_slices);
+    ts_free((void *)self->field_names);
+    ts_free((void *)self->lex_modes);
+    ts_free((void *)self->parse_actions);
+    ts_free((void *)self->parse_table);
+    ts_free((void *)self->primary_state_ids);
+    ts_free((void *)self->public_symbol_map);
+    ts_free((void *)self->small_parse_table);
+    ts_free((void *)self->small_parse_table_map);
+    ts_free((void *)self->symbol_metadata);
+    ts_free((void *)self->symbol_names);
+    ts_free((void *)self);
+  }
+}
+
+#else
+
+// If the WASM feature is not enabled, define dummy versions of all of the
+// wasm-related functions.
+
+void ts_wasm_store_delete(TSWasmStore *self) {
+  (void)self;
+}
+
+bool ts_wasm_store_start(
+  TSWasmStore *self,
+  TSLexer *lexer,
+  const TSLanguage *language
+) {
+  (void)self;
+  (void)lexer;
+  (void)language;
+  return false;
+}
+
+void ts_wasm_store_reset(TSWasmStore *self) {
+  (void)self;
+}
+
+bool ts_wasm_store_call_lex_main(TSWasmStore *self, TSStateId state) {
+  (void)self;
+  (void)state;
+  return false;
+}
+
+bool ts_wasm_store_call_lex_keyword(TSWasmStore *self, TSStateId state) {
+  (void)self;
+  (void)state;
+  return false;
+}
+
+uint32_t ts_wasm_store_call_scanner_create(TSWasmStore *self) {
+  (void)self;
+  return 0;
+}
+
+void ts_wasm_store_call_scanner_destroy(
+  TSWasmStore *self,
+  uint32_t scanner_address
+) {
+  (void)self;
+  (void)scanner_address;
+}
+
+bool ts_wasm_store_call_scanner_scan(
+  TSWasmStore *self,
+  uint32_t scanner_address,
+  uint32_t valid_tokens_ix
+) {
+  (void)self;
+  (void)scanner_address;
+  (void)valid_tokens_ix;
+  return false;
+}
+
+uint32_t ts_wasm_store_call_scanner_serialize(
+  TSWasmStore *self,
+  uint32_t scanner_address,
+  char *buffer
+) {
+  (void)self;
+  (void)scanner_address;
+  (void)buffer;
+  return 0;
+}
+
+void ts_wasm_store_call_scanner_deserialize(
+  TSWasmStore *self,
+  uint32_t scanner_address,
+  const char *buffer,
+  unsigned length
+) {
+  (void)self;
+  (void)scanner_address;
+  (void)buffer;
+  (void)length;
+}
+
+bool ts_wasm_store_has_error(const TSWasmStore *self) {
+  (void)self;
+  return false;
+}
+
+bool ts_language_is_wasm(const TSLanguage *self) {
+  (void)self;
+  return false;
+}
+
+void ts_wasm_language_retain(const TSLanguage *self) {
+  (void)self;
+}
+
+void ts_wasm_language_release(const TSLanguage *self) {
+  (void)self;
+}
+
+#endif
diff --git a/vendor/tree-sitter/lib/src/wasm_store.h b/vendor/tree-sitter/lib/src/wasm_store.h
new file mode 100644
--- /dev/null
+++ b/vendor/tree-sitter/lib/src/wasm_store.h
@@ -0,0 +1,31 @@
+#ifndef TREE_SITTER_WASM_H_
+#define TREE_SITTER_WASM_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "tree_sitter/api.h"
+#include "./parser.h"
+
+bool ts_wasm_store_start(TSWasmStore *self, TSLexer *lexer, const TSLanguage *language);
+void ts_wasm_store_reset(TSWasmStore *self);
+bool ts_wasm_store_has_error(const TSWasmStore *self);
+
+bool ts_wasm_store_call_lex_main(TSWasmStore *self, TSStateId state);
+bool ts_wasm_store_call_lex_keyword(TSWasmStore *self, TSStateId state);
+
+uint32_t ts_wasm_store_call_scanner_create(TSWasmStore *self);
+void ts_wasm_store_call_scanner_destroy(TSWasmStore *self, uint32_t scanner_address);
+bool ts_wasm_store_call_scanner_scan(TSWasmStore *self, uint32_t scanner_address, uint32_t valid_tokens_ix);
+uint32_t ts_wasm_store_call_scanner_serialize(TSWasmStore *self, uint32_t scanner_address, char *buffer);
+void ts_wasm_store_call_scanner_deserialize(TSWasmStore *self, uint32_t scanner, const char *buffer, unsigned length);
+
+void ts_wasm_language_retain(const TSLanguage *self);
+void ts_wasm_language_release(const TSLanguage *self);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  // TREE_SITTER_WASM_H_
diff --git a/vendor/tree-sitter/lib/tree-sitter.pc.in b/vendor/tree-sitter/lib/tree-sitter.pc.in
new file mode 100644
--- /dev/null
+++ b/vendor/tree-sitter/lib/tree-sitter.pc.in
@@ -0,0 +1,10 @@
+prefix=@CMAKE_INSTALL_PREFIX@
+libdir=${prefix}/@CMAKE_INSTALL_LIBDIR@
+includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@
+
+Name: tree-sitter
+Description: @PROJECT_DESCRIPTION@
+URL: @PROJECT_HOMEPAGE_URL@
+Version: @PROJECT_VERSION@
+Libs: -L${libdir} -ltree-sitter
+Cflags: -I${includedir}
