<commit_before>" The plugin cache.
if !exists('s:plugins')
  let s:plugins = {}
endif

" Recognized special directories are as follows:
"
" autoload/*: Files containing functions made available upon request.
" instant/*: Loaded immediately after plugin installation.
" plugin/*: Loaded during vim load time (after vimrc time).
" ftdetect/*: Files that enable detection for new filetypes.
" ftplugin/*: Files selectively loaded once-per-buffer at ftdetect time.
" indent/*: Files specifying indent rules, once-per-buffer at ftdetect time.
" syntax/*: Files specifying syntax rules, once-per-buffer at ftdetect time.

" Directories in which you should use #Enter:
let s:enterabledirs = ['autoload', 'plugin', 'instant', 'ftplugin']

" Filenames which are not sourced by default (the user must opt-in).
let s:defaultoff = {'plugin': ['mappings']}


" @exception
function! s:AlreadyExists(message, ...) abort
  return maktaba#error#Exception('AlreadyExists', a:message, a:000)
endfunction


" @exception
function! s:CannotEnter(file) abort
  return maktaba#error#Message(
      \ 'CannotEnter',
      \ 'maktaba#plugin#Enter must be called from ' .
      \ 'a file in an autoload/, plugin/, ftplugin/, or instant/ directory. ' .
      \ 'It was called from %s.')
endfunction


" This is The Way to store a plugin location, by convention:
" Fully expanded path with trailing slash at the end.
function! s:Fullpath(location) abort
  " The #Join ensures a trailing slash.
  return maktaba#path#Join([fnamemodify(a:location, ':p'), ''])
endfunction


" Applies {settings} to {plugin}. Returns {plugin} for convenience.
" Tries to apply all settings, even if some fail.
" @throws ConfigError if any settings failed to apply.
function! s:ApplySettings(plugin, settings) abort
  let l:errors = []
  for l:setting in a:settings
    try
      call l:setting.Apply(a:plugin)
    catch /ERROR(\(NotFound\|BadValue\|WrongType\)):/
      call add(l:errors, maktaba#error#Split(v:exception)[1])
    endtry
  endfor
  if !empty(l:errors)
    let l:msg = 'Error configuring %s: %s'
    let l:errtxt = join(l:errors)
    throw maktaba#error#Message('ConfigError', l:msg, a:plugin.name, l:errtxt)
  endif
  return a:plugin
endfunction


" Splits a path into a canonical plugin name and a parent directory.
function! s:PluginNameFromDir(dir) abort
  let l:splitpath = maktaba#path#Split(a:dir)
  if len(l:splitpath) == 0
    throw maktaba#error#BadValue('Found empty path.')
  endif
  let l:name = maktaba#plugin#CanonicalName(l:splitpath[-1])
  return l:name
endfunction


" Splits a plugin location and file handle from {path}.
" foo/plugin/bar.vim will yield ['foo', 'plugin', 'bar^'].
" foo/after/plugin/bar.vim will yield ['foo', 'plugin', 'bar$'].
"
" We cannot just use 'bar' and 'after/bar', as there could (conceivably) be
" a file named foo\plugin\after/bar.vim on a windows machine, where the '/' is
" not acting as a path separator. (Yes, I know, I'm paranoid.) What we actually
" want here is an Either type, but we don't have one of those yet.
"
" This is used by maktaba#plugin#Enter, which cares about the TYPE of file
" (autoload/plugin/instant/ftplugin etc.) and does not care about after vs
" non-after files but needs them to have distinct handles.
function! s:SplitEnteredFile(file) abort
  let l:filedir = fnamemodify(a:file, ':h:t')
  if !count(s:enterabledirs, l:filedir)
    throw s:CannotEnter(a:file)
  endif

  let l:handle = fnamemodify(a:file, ':t:r')
  let l:plugindir = fnamemodify(a:file, ':p:h:h')
  if l:plugindir ==# 'after'
    let l:plugindir = fnamemodify(a:file, ':p:h:h:h')
    let l:handle .= '$'
  else
    let l:handle .= '^'
  endif

  return [l:plugindir, l:filedir, l:handle]
endfunction


" Converts file handle to flag handle.
" foo^ is converted to foo, foo$ is converted to after/foo.
function! s:FileHandleToFlagHandle(handle) abort
  if a:handle =~# '\v\$$'
    return 'after/' . a:handle[:-2]
  endif
  return a:handle[:-2]
endfunction


""
" @private
" Used by maktaba#library to help throw good error messages about non-library
" directories.
function! maktaba#plugin#NonlibraryDirs() abort
  return ['plugin', 'instant', 'ftdetect', 'ftplugin', 'indent', 'syntax']
endfunction



""
" This function is used to both control when plugin files are entered, and get
" a handle to the current plugin object. It should be called from the top of
" an autoload/*.vim, plugin/*.vim, ftplugin/*.vim, or instant/*.vim file as
" follows:
" >
"   let [s:plugin, s:enter] = maktaba#plugin#Enter(expand('<sfile>:p'))
"   if !s:enter
"     finish
"   endif
" <
" The result is a tuple containing the plugin object and a boolean specifying
" whether the file should be entered (taking user preferences and whether the
" file has already been sourced into account). If the second value is false, the
" script should finish immediately.
"
" autoload/*.vim files are entered on demand (see |autoload|), this function
" only helps prevent re-entry.
"
" For plugin/*.vim and instant/*.vim files, maktaba ensures that the file is
" only entered once, and then only if the user has not disabled the file via
" the plugin[*] or instant[*] flags.
"
" In ftplugin/*.vim files, maktaba ensures that the file is loaded only once per
" buffer.
"
" Note that maktaba does NOT set the g:loaded_{plugin} variable, as recommended
" in the write-plugin helpfiles. This is because maktaba plugins may span
" multiple files, and there is no clear moment when the plugin is "loaded". If
" you feel you must adhere to this convention, be sure to set the appropriate
" g:loaded_* variable when appropriate.
function! maktaba#plugin#Enter(file) abort
  let [l:plugindir, l:filedir, l:handle] = s:SplitEnteredFile(a:file)
  let l:plugin = maktaba#plugin#GetOrInstall(l:plugindir)
  let l:controller = l:plugin._entered[l:filedir]

  if l:filedir ==# 'ftplugin'
    call extend(l:controller, {l:handle: []}, 'keep')
    if index(l:controller[l:handle], bufnr()) >= 0
      return [l:plugin, 0]
    endif
    call add(l:controller[l:handle], bufnr())
    return [l:plugin, 1]
  endif

  " Leave this block above the next on pain of stack overflow.
  if index(l:controller, l:handle) >= 0
    return [l:plugin, 0]
  endif

  if l:filedir !=# 'autoload'
    " Check the 'plugin' or 'instant' flag dictionaries for word on the this
    " file, using the defaults specified in the s:defaultoff variable.
    let l:flag = l:plugin.Flag(l:filedir)
    let l:flaghandle = s:FileHandleToFlagHandle(l:handle)
    let l:defaultoff = count(get(s:defaultoff, l:filedir, []), l:flaghandle)
    if empty(get(l:flag, l:flaghandle, l:defaultoff ? 0 : 1))
      " Turned off by flag.
      return [l:plugin, 0]
    endif
  endif

  " Note that a file isn't entered when it is sourced: it is entered when this
  " function OKs an enter. (In other words, don't move this line up.)
  call add(l:controller, l:handle)
  return [l:plugin, 1]
endfunction


""
" A list of all installed plugins in alphabetical order.
function! maktaba#plugin#RegisteredPlugins() abort
  return sort(keys(s:plugins))
endfunction


""
" 1 if {plugin} was registered with maktaba#plugin#Register.
" This is more reliable for determining if a Maktaba compatible plugin by
" the name of {plugin} was registered, but can not be used to dependency check
" non-Maktaba plugins.
function! maktaba#plugin#IsRegistered(plugin) abort
  return has_key(s:plugins, maktaba#plugin#CanonicalName(a:plugin))
endfunction


""
" The canonical name of {plugin}.
" This is the name of the plugin directory with all invalid characters replaced
" with underscores. Valid characters include _, [a-z], [A-Z], and [0-9].
" For example, the canonical name of "my-plugin" is "my_plugin".  Certain
" conventions which are common for github vim projects are also recognized.
" Specifically, either a "vim-" prefix and a ".vim" suffix would be
" disregarded: both "vim-unimpaired" and "unimpaired.vim" would become simply
" "unimpaired".
"
" Note that plugins with different names in the filesystem can conflict in
" maktaba. If you've loaded a plugin in the directory "plugins/my-plugin" then
" maktaba can't handle a plugin named "plugins/my_plugin". Make sure your
" plugins have sufficiently different names!
function! maktaba#plugin#CanonicalName(plugin) abort
  let l:plugin = a:plugin
  if maktaba#string#StartsWith(l:plugin, 'vim-')
    let l:plugin = l:plugin[4:]
  endif
  if maktaba#string#EndsWith(l:plugin, '.vim')
    let l:plugin = l:plugin[:-5]
  endif
  return substitute(l:plugin, '[^_a-zA-Z0-9]', '_', 'g')
endfunction


""
" @usage dir [settings]
" Installs the plugin located at {dir}. Installation entails adding the plugin
" to the runtimepath, loading its flags.vim file, and sourcing any files in its
" instant/ directory.
"
" Returns the maktaba plugin object describing the installed plugin.
"
" {dir} should be the full path to the plugin directory. The plugin itself
" should be the last component in the directory path. The plugin name will be
" the name of this directory with all invalid characters converted to
" underscores (see @function(#CanonicalName)).
"
" If the plugin contains a plugin/ directory it will have a special "plugin"
" dictionary flag that controls which plugin files are loaded. For example, if
" the plugin contains plugin/commands.vim, you can use
" >
"   let plugin = maktaba#plugin#Install(path)
"   call plugin.Flag('plugin[commands]', 0)
" <
" to disable it. More generally, "plugin" is a dictionary whose keys control the
" loading of plugin files. A file's key is its filename without the '.vim'
" extension. Set the key to 0 to prevent the file from loading or 1 to allow it
" to load.
"
" Note that setting the key to 1 only ALLOWS the file to load: if load time has
" already passed, enabling the plugin file will not cause it to load. To load
" plugin files late use |Plugin.Load|.
"
" All plugin files are loaded by default EXCEPT the file plugin/mappings.vim,
" which is opt-in. (Set plugin[mappings] to 1 to enable.)
"
" If the plugin contains an instant/ directory it will also have a special
" "instant" flag, which acts similarly to the special "plugin" flag for
" instant/*.vim files. For example, in a plugin with an instant/earlyfile.vim,
" the following DOES NOT WORK:
" >
"   let plugin = maktaba#plugin#Install(path)
"   call plugin.Flag('instant[earlyfile]', 0)
" <
" All instant/*.vim files are sourced during installation. In order to configure
" the "instant" flag, you must pass [settings] to the installation function. If
" given, they must be a list of maktaba settings (see |maktaba#setting#Create|).
" They will be applied after instant/flags.vim is sourced (if present), but
" before any other instant files are sourced. For example:
" >
"   let noearly = maktaba#setting#Parse('instant[earlyfile]=0')
"   let plugin = maktaba#plugin#Install(path, [noearly])
" <
" @throws BadValue if {dir} is empty.
" @throws AlreadyExists if the plugin already exists.
" @throws ConfigError if [settings] cannot be applied to this plugin.
function! maktaba#plugin#Install(dir, ...) abort
  let l:name = s:PluginNameFromDir(a:dir)
  let l:settings = maktaba#ensure#IsList(get(a:, 1, []))
  if has_key(s:plugins, l:name)
    throw s:AlreadyExists('Plugin "%s" already exists.', l:name)
  endif
  return s:CreatePluginObject(l:name, a:dir, l:settings)
endfunction


""
" Gets the plugin object associated with {plugin}. {plugin} may either be the
" name of the plugin directory, or the canonicalized plugin name (with invalid
" characters converted to whitespace.) See @function(#CanonicalName).
" @throws NotFound if the plugin object does not exist.
function! maktaba#plugin#Get(name) abort
  let l:name = maktaba#plugin#CanonicalName(a:name)
  if has_key(s:plugins, l:name)
    return s:plugins[l:name]
  endif
  throw maktaba#error#NotFound('Plugin %s', a:name)
endfunction

<commit_msg>Fix typo "spaces" -> "underscores"<commit_after>" The plugin cache.
if !exists('s:plugins')
  let s:plugins = {}
endif

" Recognized special directories are as follows:
"
" autoload/*: Files containing functions made available upon request.
" instant/*: Loaded immediately after plugin installation.
" plugin/*: Loaded during vim load time (after vimrc time).
" ftdetect/*: Files that enable detection for new filetypes.
" ftplugin/*: Files selectively loaded once-per-buffer at ftdetect time.
" indent/*: Files specifying indent rules, once-per-buffer at ftdetect time.
" syntax/*: Files specifying syntax rules, once-per-buffer at ftdetect time.

" Directories in which you should use #Enter:
let s:enterabledirs = ['autoload', 'plugin', 'instant', 'ftplugin']

" Filenames which are not sourced by default (the user must opt-in).
let s:defaultoff = {'plugin': ['mappings']}


" @exception
function! s:AlreadyExists(message, ...) abort
  return maktaba#error#Exception('AlreadyExists', a:message, a:000)
endfunction


" @exception
function! s:CannotEnter(file) abort
  return maktaba#error#Message(
      \ 'CannotEnter',
      \ 'maktaba#plugin#Enter must be called from ' .
      \ 'a file in an autoload/, plugin/, ftplugin/, or instant/ directory. ' .
      \ 'It was called from %s.')
endfunction


" This is The Way to store a plugin location, by convention:
" Fully expanded path with trailing slash at the end.
function! s:Fullpath(location) abort
  " The #Join ensures a trailing slash.
  return maktaba#path#Join([fnamemodify(a:location, ':p'), ''])
endfunction


" Applies {settings} to {plugin}. Returns {plugin} for convenience.
" Tries to apply all settings, even if some fail.
" @throws ConfigError if any settings failed to apply.
function! s:ApplySettings(plugin, settings) abort
  let l:errors = []
  for l:setting in a:settings
    try
      call l:setting.Apply(a:plugin)
    catch /ERROR(\(NotFound\|BadValue\|WrongType\)):/
      call add(l:errors, maktaba#error#Split(v:exception)[1])
    endtry
  endfor
  if !empty(l:errors)
    let l:msg = 'Error configuring %s: %s'
    let l:errtxt = join(l:errors)
    throw maktaba#error#Message('ConfigError', l:msg, a:plugin.name, l:errtxt)
  endif
  return a:plugin
endfunction


" Splits a path into a canonical plugin name and a parent directory.
function! s:PluginNameFromDir(dir) abort
  let l:splitpath = maktaba#path#Split(a:dir)
  if len(l:splitpath) == 0
    throw maktaba#error#BadValue('Found empty path.')
  endif
  let l:name = maktaba#plugin#CanonicalName(l:splitpath[-1])
  return l:name
endfunction


" Splits a plugin location and file handle from {path}.
" foo/plugin/bar.vim will yield ['foo', 'plugin', 'bar^'].
" foo/after/plugin/bar.vim will yield ['foo', 'plugin', 'bar$'].
"
" We cannot just use 'bar' and 'after/bar', as there could (conceivably) be
" a file named foo\plugin\after/bar.vim on a windows machine, where the '/' is
" not acting as a path separator. (Yes, I know, I'm paranoid.) What we actually
" want here is an Either type, but we don't have one of those yet.
"
" This is used by maktaba#plugin#Enter, which cares about the TYPE of file
" (autoload/plugin/instant/ftplugin etc.) and does not care about after vs
" non-after files but needs them to have distinct handles.
function! s:SplitEnteredFile(file) abort
  let l:filedir = fnamemodify(a:file, ':h:t')
  if !count(s:enterabledirs, l:filedir)
    throw s:CannotEnter(a:file)
  endif

  let l:handle = fnamemodify(a:file, ':t:r')
  let l:plugindir = fnamemodify(a:file, ':p:h:h')
  if l:plugindir ==# 'after'
    let l:plugindir = fnamemodify(a:file, ':p:h:h:h')
    let l:handle .= '$'
  else
    let l:handle .= '^'
  endif

  return [l:plugindir, l:filedir, l:handle]
endfunction


" Converts file handle to flag handle.
" foo^ is converted to foo, foo$ is converted to after/foo.
function! s:FileHandleToFlagHandle(handle) abort
  if a:handle =~# '\v\$$'
    return 'after/' . a:handle[:-2]
  endif
  return a:handle[:-2]
endfunction


""
" @private
" Used by maktaba#library to help throw good error messages about non-library
" directories.
function! maktaba#plugin#NonlibraryDirs() abort
  return ['plugin', 'instant', 'ftdetect', 'ftplugin', 'indent', 'syntax']
endfunction



""
" This function is used to both control when plugin files are entered, and get
" a handle to the current plugin object. It should be called from the top of
" an autoload/*.vim, plugin/*.vim, ftplugin/*.vim, or instant/*.vim file as
" follows:
" >
"   let [s:plugin, s:enter] = maktaba#plugin#Enter(expand('<sfile>:p'))
"   if !s:enter
"     finish
"   endif
" <
" The result is a tuple containing the plugin object and a boolean specifying
" whether the file should be entered (taking user preferences and whether the
" file has already been sourced into account). If the second value is false, the
" script should finish immediately.
"
" autoload/*.vim files are entered on demand (see |autoload|), this function
" only helps prevent re-entry.
"
" For plugin/*.vim and instant/*.vim files, maktaba ensures that the file is
" only entered once, and then only if the user has not disabled the file via
" the plugin[*] or instant[*] flags.
"
" In ftplugin/*.vim files, maktaba ensures that the file is loaded only once per
" buffer.
"
" Note that maktaba does NOT set the g:loaded_{plugin} variable, as recommended
" in the write-plugin helpfiles. This is because maktaba plugins may span
" multiple files, and there is no clear moment when the plugin is "loaded". If
" you feel you must adhere to this convention, be sure to set the appropriate
" g:loaded_* variable when appropriate.
function! maktaba#plugin#Enter(file) abort
  let [l:plugindir, l:filedir, l:handle] = s:SplitEnteredFile(a:file)
  let l:plugin = maktaba#plugin#GetOrInstall(l:plugindir)
  let l:controller = l:plugin._entered[l:filedir]

  if l:filedir ==# 'ftplugin'
    call extend(l:controller, {l:handle: []}, 'keep')
    if index(l:controller[l:handle], bufnr()) >= 0
      return [l:plugin, 0]
    endif
    call add(l:controller[l:handle], bufnr())
    return [l:plugin, 1]
  endif

  " Leave this block above the next on pain of stack overflow.
  if index(l:controller, l:handle) >= 0
    return [l:plugin, 0]
  endif

  if l:filedir !=# 'autoload'
    " Check the 'plugin' or 'instant' flag dictionaries for word on the this
    " file, using the defaults specified in the s:defaultoff variable.
    let l:flag = l:plugin.Flag(l:filedir)
    let l:flaghandle = s:FileHandleToFlagHandle(l:handle)
    let l:defaultoff = count(get(s:defaultoff, l:filedir, []), l:flaghandle)
    if empty(get(l:flag, l:flaghandle, l:defaultoff ? 0 : 1))
      " Turned off by flag.
      return [l:plugin, 0]
    endif
  endif

  " Note that a file isn't entered when it is sourced: it is entered when this
  " function OKs an enter. (In other words, don't move this line up.)
  call add(l:controller, l:handle)
  return [l:plugin, 1]
endfunction


""
" A list of all installed plugins in alphabetical order.
function! maktaba#plugin#RegisteredPlugins() abort
  return sort(keys(s:plugins))
endfunction


""
" 1 if {plugin} was registered with maktaba#plugin#Register.
" This is more reliable for determining if a Maktaba compatible plugin by
" the name of {plugin} was registered, but can not be used to dependency check
" non-Maktaba plugins.
function! maktaba#plugin#IsRegistered(plugin) abort
  return has_key(s:plugins, maktaba#plugin#CanonicalName(a:plugin))
endfunction


""
" The canonical name of {plugin}.
" This is the name of the plugin directory with all invalid characters replaced
" with underscores. Valid characters include _, [a-z], [A-Z], and [0-9].
" For example, the canonical name of "my-plugin" is "my_plugin".  Certain
" conventions which are common for github vim projects are also recognized.
" Specifically, either a "vim-" prefix and a ".vim" suffix would be
" disregarded: both "vim-unimpaired" and "unimpaired.vim" would become simply
" "unimpaired".
"
" Note that plugins with different names in the filesystem can conflict in
" maktaba. If you've loaded a plugin in the directory "plugins/my-plugin" then
" maktaba can't handle a plugin named "plugins/my_plugin". Make sure your
" plugins have sufficiently different names!
function! maktaba#plugin#CanonicalName(plugin) abort
  let l:plugin = a:plugin
  if maktaba#string#StartsWith(l:plugin, 'vim-')
    let l:plugin = l:plugin[4:]
  endif
  if maktaba#string#EndsWith(l:plugin, '.vim')
    let l:plugin = l:plugin[:-5]
  endif
  return substitute(l:plugin, '[^_a-zA-Z0-9]', '_', 'g')
endfunction


""
" @usage dir [settings]
" Installs the plugin located at {dir}. Installation entails adding the plugin
" to the runtimepath, loading its flags.vim file, and sourcing any files in its
" instant/ directory.
"
" Returns the maktaba plugin object describing the installed plugin.
"
" {dir} should be the full path to the plugin directory. The plugin itself
" should be the last component in the directory path. The plugin name will be
" the name of this directory with all invalid characters converted to
" underscores (see @function(#CanonicalName)).
"
" If the plugin contains a plugin/ directory it will have a special "plugin"
" dictionary flag that controls which plugin files are loaded. For example, if
" the plugin contains plugin/commands.vim, you can use
" >
"   let plugin = maktaba#plugin#Install(path)
"   call plugin.Flag('plugin[commands]', 0)
" <
" to disable it. More generally, "plugin" is a dictionary whose keys control the
" loading of plugin files. A file's key is its filename without the '.vim'
" extension. Set the key to 0 to prevent the file from loading or 1 to allow it
" to load.
"
" Note that setting the key to 1 only ALLOWS the file to load: if load time has
" already passed, enabling the plugin file will not cause it to load. To load
" plugin files late use |Plugin.Load|.
"
" All plugin files are loaded by default EXCEPT the file plugin/mappings.vim,
" which is opt-in. (Set plugin[mappings] to 1 to enable.)
"
" If the plugin contains an instant/ directory it will also have a special
" "instant" flag, which acts similarly to the special "plugin" flag for
" instant/*.vim files. For example, in a plugin with an instant/earlyfile.vim,
" the following DOES NOT WORK:
" >
"   let plugin = maktaba#plugin#Install(path)
"   call plugin.Flag('instant[earlyfile]', 0)
" <
" All instant/*.vim files are sourced during installation. In order to configure
" the "instant" flag, you must pass [settings] to the installation function. If
" given, they must be a list of maktaba settings (see |maktaba#setting#Create|).
" They will be applied after instant/flags.vim is sourced (if present), but
" before any other instant files are sourced. For example:
" >
"   let noearly = maktaba#setting#Parse('instant[earlyfile]=0')
"   let plugin = maktaba#plugin#Install(path, [noearly])
" <
" @throws BadValue if {dir} is empty.
" @throws AlreadyExists if the plugin already exists.
" @throws ConfigError if [settings] cannot be applied to this plugin.
function! maktaba#plugin#Install(dir, ...) abort
  let l:name = s:PluginNameFromDir(a:dir)
  let l:settings = maktaba#ensure#IsList(get(a:, 1, []))
  if has_key(s:plugins, l:name)
    throw s:AlreadyExists('Plugin "%s" already exists.', l:name)
  endif
  return s:CreatePluginObject(l:name, a:dir, l:settings)
endfunction


""
" Gets the plugin object associated with {plugin}. {plugin} may either be the
" name of the plugin directory, or the canonicalized plugin name (with invalid
" characters converted to underscores). See @function(#CanonicalName).
" @throws NotFound if the plugin object does not exist.
function! maktaba#plugin#Get(name) abort
  let l:name = maktaba#plugin#CanonicalName(a:name)
  if has_key(s:plugins, l:name)
    return s:plugins[l:name]
  endif
  throw maktaba#error#NotFound('Plugin %s', a:name)
endfunction


{'fraction_non_alphanumeric': 0.11058783954251114, 'fraction_numerical': 0.0026911109242284082, 'mean_word_length': 4.395417422867514, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 18, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4981688', 'n_tokens_mistral': 7707, 'n_tokens_neox': 7287, 'n_words': 2843}