<commit_before>'use strict'

require! {
    fs
    path
}

# default options
defaults = {
    extensions: <[ js json ls coffee ]>
    recursive: false
    camelize: true
    filter: null
    map: null
}

# camelize :: string -> string
camelize = (str) ->
    str.replace /[-_]+(.)?/g, (, c) -> (c ? '').to-upper-case!

filter = (method, name) ->
    switch (Object.prototype.toString.call method .slice 8, -1)
    | 'Function' then method name
    | 'RegExp'   then method.test name
    | _          then true

# deepRequire :: object -> string -> object
deepRequire = module.exports = (cwd, opts, root) -->
    # mix defaults with user-options
    options = {}
    for k, v of defaults => options[k] = v
    for k, v of opts     => options[k] = v

    NODE_PATH = process.env.NODE_PATH

    # parseDir :: string -> object
    parseDir = (dir) ->
        modules = {}
        if (dir.slice 0 2) isnt './' and fs.existsSync NODE_PATH
            cwd = NODE_PATH

        absDir = path.join cwd, dir

        fs.readdirSync absDir .forEach (name) ->
            ext     = (name.match /\.(.*)$/i or [])
            relPath = path.join dir, name
            absPath = path.join cwd, relPath
            stat    = fs.statSync absPath

            name := name.replace ext.0, ''
            name := (camelize name) if options.camelize

            if stat.isDirectory!
            and options.recursive
                modules[name] = (parseDir relPath)

            else if stat.isFile!
            and (options.extensions.indexOf ext.1) isnt -1
                return unless (filter options.filter, name)
                name := (options.map name) if options.map
                modules[name] = require absPath
        modules

    parseDir root<commit_msg>fix bug with NODE_PATH lookup, filter with full filename<commit_after>'use strict'

require! {
    fs
    path
}

# const
NODE_PATH = process.env.NODE_PATH

# default options
defaults = {
    extensions: <[ js json ls coffee ]>
    recursive: false
    camelize: true
    filter: null
    map: null
}

# mixin :: object -> object -> object
mixin = (dest, ...sources) ->
    for src in sources
        for key, value of src
            dest[key] = value
    dest

# camelize :: string -> string
camelize = (str) ->
    str.replace /[-_]+(.)?/g, (, c) -> (c ? '').to-upper-case!

# filter :: a -> string -> bool
filter = (method, name) ->
    switch (Object.prototype.toString.call method .slice 8, -1)
    | 'Function' then method name
    | 'RegExp'   then method.test name
    | _          then true

# deepRequire :: object -> string -> object
deepRequire = module.exports = (cwd, opts, str) -->

    # match NODE_PATH
    if (not /^[\.]{1,2}\//.test str) and (fs.existsSync NODE_PATH)
        cwd := NODE_PATH

    # mix defaults with user-options
    options = mixin {}, defaults, opts

    # parse input and return modules
    # parseDir :: string -> object
    str |> function parseDir (dir)
        modules = {}

        absDir = path.join cwd, dir

        fs.readdirSync absDir .forEach (file) ->
            ext     = file.match /\.(.*)$/i or []
            relPath = path.join dir, file
            absPath = path.join cwd, relPath
            stat    = fs.statSync absPath
            name    = file.replace ext.0, ''

            name   := (camelize name) if options.camelize

            if stat.isDirectory!
            and options.recursive
                modules[name] = parseDir relPath

            else if stat.isFile!
            and (options.extensions.indexOf ext.1) isnt -1
                return unless filter options.filter, file
                name := (options.map name) if options.map
                modules[name] = require absPath
        modules
{'fraction_non_alphanumeric': 0.11953899758777807, 'fraction_numerical': 0.00375234521575985, 'mean_word_length': 1.8445121951219512, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 32, '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': '7278057', 'n_tokens_mistral': 1147, 'n_tokens_neox': 1107, 'n_words': 342}