code:
'use strict'
const { join } = require('path')
const { test } = require('tap')
const { when } = require('nonsynchronous')
const { chmodSync } = require('fs')
const isFileEsm = require('..')
const {
  ERR_PATH_MUST_BE_STRING,
  ERR_PATH_MUST_BE_ABSOLUTE,
  ERR_PATH_MUST_EXIST,
  ERR_PATH_MUST_HAVE_VALID_EXT
} = isFileEsm.constants

const ERR_BAD_TYPE = 'package.json type "bad" not recognized'
const ERR_PERMISSION_DENIED = /EACCES: permission denied/

const fixtures = join(__dirname, 'fixtures')

test('path must be string (promise)', async ({ rejects }) => {
  await rejects(() => isFileEsm(), Error(ERR_PATH_MUST_BE_STRING))
  await rejects(() => isFileEsm({}), Error(ERR_PATH_MUST_BE_STRING))
})

test('path must be absolute (promise)', async ({ rejects }) => {
  await rejects(() => isFileEsm('../foo.js'), Error(ERR_PATH_MUST_BE_ABSOLUTE))
  await rejects(() => isFileEsm('./bar/foo.mjs'), Error(ERR_PATH_MUST_BE_ABSOLUTE))
})

test('path must have ext (promise)', async ({ rejects }) => {
  await rejects(() => isFileEsm('/bar/foo'), Error(ERR_PATH_MUST_HAVE_VALID_EXT))
})

test('path must have valid ext (promise)', async ({ rejects }) => {
  await rejects(() => isFileEsm('/bar/foo.ext'), Error(ERR_PATH_MUST_HAVE_VALID_EXT))
})

test('path must exist (promise)', async ({ rejects }) => {
  await rejects(() => isFileEsm(join(fixtures, 'bar', 'foo.js')), Error(ERR_PATH_MUST_EXIST))
})

test('type-commonjs-cjs promise', async ({ is }) => {
  const inputPath = join(fixtures, 'type-commonjs-cjs', 'file.cjs')
  const expectedPkgPath = join(fixtures, 'type-commonjs-cjs', 'package.json')
  const { esm, path, type, extType, pkgPath } = await isFileEsm(inputPath)
  is(esm, false)
  is(path, inputPath)
  is(expectedPkgPath, pkgPath)
  is(type, 'commonjs')
  is(extType, 'c')
})

test('type-commonjs-js promise', async ({ is }) => {
  const inputPath = join(fixtures, 'type-commonjs-js', 'file.js')
  const expectedPkgPath = join(fixtures, 'type-commonjs-js', 'package.json')
  const { esm, path, type, extType, pkgPath } = await isFileEsm(inputPath)
  is(esm, false)
  is(path, inputPath)
  is(expectedPkgPath, pkgPath)
  is(type, 'commonjs')
  is(extType, 'j')
})

test('type-commonjs-mjs promise', async ({ is }) => {
  const inputPath = join(fixtures, 'type-commonjs-mjs', 'file.mjs')
  const expectedPkgPath = join(fixtures, 'type-commonjs-mjs', 'package.json')
  const { esm, path, type, extType, pkgPath } = await isFileEsm(inputPath)
  is(esm, true)
  is(path, inputPath)
  is(expectedPkgPath, pkgPath)
  is(type, 'commonjs')
  is(extType, 'm')
})

test('type-module-cjs promise', async ({ is }) => {
  const inputPath = join(fixtures, 'type-module-cjs', 'file.cjs')
  const expectedPkgPath = join(fixtures, 'type-module-cjs', 'package.json')
  const { esm, path, type, extType, pkgPath } = await isFileEsm(inputPath)
  is(esm, false)
  is(path, inputPath)
  is(expectedPkgPath, pkgPath)
  is(type, 'module')
  is(extType, 'c')
})

test('type-module-js promise', async ({ is }) => {
  const inputPath = join(fixtures, 'type-module-js', 'file.js')
  const expectedPkgPath = join(fixtures, 'type-module-js', 'package.json')
  const { esm, path, type, extType, pkgPath } = await isFileEsm(inputPath)
  is(esm, true)
  is(path, inputPath)
  is(expectedPkgPath, pkgPath)
  is(type, 'module')
  is(extType, 'j')
})

test('type-module-mjs promise', async ({ is }) => {
  const inputPath = join(fixtures, 'type-module-mjs', 'file.mjs')
  const expectedPkgPath = join(fixtures, 'type-module-mjs', 'package.json')
  const { esm, path, type, extType, pkgPath } = await isFileEsm(inputPath)
  is(esm, true)
  is(path, inputPath)
  is(expectedPkgPath, pkgPath)
  is(type, 'module')
  is(extType, 'm')
})

test('type-undefined-cjs promise', async ({ is }) => {
  const inputPath = join(fixtures, 'type-undefined-cjs', 'file.cjs')
  const expectedPkgPath = join(fixtures, 'type-undefined-cjs', 'package.json')
  const { esm, path, type, extType, pkgPath } = await isFileEsm(inputPath)
  is(esm, false)
  is(path, inputPath)
  is(expectedPkgPath, pkgPath)
  is(type, undefined)
  is(extType, 'c')
})

test('type-undefined-js promise', async ({ is }) => {
  const inputPath = join(fixtures, 'type-undefined-js', 'file.js')
  const expectedPkgPath = join(fixtures, 'type-undefined-js', 'package.json')
  const { esm, path, type, extType, pkgPath } = await isFileEsm(inputPath)
  is(esm, false)
  is(path, inputPath)
  is(expectedPkgPath, pkgPath)
  is(type, undefined)
  is(extType, 'j')
})

test('type-undefined-mjs promise', async ({ is }) => {
  const inputPath = join(fixtures, 'type-undefined-mjs', 'file.mjs')
  const expectedPkgPath = join(fixtures, 'type-undefined-mjs', 'package.json')
  const { esm, path, type, extType, pkgPath } = await isFileEsm(inputPath)
  is(esm, true)
  is(path, inputPath)
  is(expectedPkgPath, pkgPath)
  is(type, undefined)
  is(extType, 'm')
})

test('type-bad-cjs promise', async ({ is, rejects }) => {
  const inputPath = join(fixtures, 'type-bad-cjs', 'file.cjs')
  const expectedPkgPath = join(fixtures, 'type-bad-cjs', 'package.json')
  let error = null
  await rejects(async () => {
    try {
      await isFileEsm(inputPath)
    } catch (err) {
      error = err
      throw err
    }
  }, ERR_BAD_TYPE)
  const { path, type, extType, pkgPath } = error.meta
  is(path, inputPath)
  is(expectedPkgPath, pkgPath)
  is(type, 'bad')
  is(extType, 'c')
})

test('type-bad-js promise', async ({ is, rejects }) => {
  const inputPath = join(fixtures, 'type-bad-js', 'file.js')
  const expectedPkgPath = join(fixtures, 'type-bad-js', 'package.json')
  let error = null
  await rejects(async () => {
    try {
      await isFileEsm(inputPath)
    } catch (err) {
      error = err
      throw err
    }
  }, ERR_BAD_TYPE)
  const { path, type, extType, pkgPath } = error.meta
  is(path, inputPath)
  is(expectedPkgPath, pkgPath)
  is(type, 'bad')
  is(extType, 'j')
})

test('type-bad-mjs promise', async ({ is, rejects }) => {
  const inputPath = join(fixtures, 'type-bad-mjs', 'file.mjs')
  const expectedPkgPath = join(fixtures, 'type-bad-mjs', 'package.json')
  let error = null
  await rejects(async () => {
    try {
      await isFileEsm(inputPath)
    } catch (err) {
      error = err
      throw err
    }
  }, ERR_BAD_TYPE)
  const { path, type, extType, pkgPath } = error.meta
  is(path, inputPath)
  is(expectedPkgPath, pkgPath)
  is(type, 'bad')
  is(extType, 'm')
})

test('package.json read error propagation (promise)', async ({ rejects, tearDown }) => {
  const inputPath = join(fixtures, 'type-bad-js', 'file.js')
  const expectedPkgPath = join(fixtures, 'type-bad-js', 'package.json')
  tearDown(() => chmodSync(expectedPkgPath, 0o644))
  chmodSync(expectedPkgPath, 0o000)
  await rejects(() => isFileEsm(inputPath), ERR_PERMISSION_DENIED)
})

test('type-commonjs-cjs sync', async ({ is }) => {
  const inputPath = join(fixtures, 'type-commonjs-cjs', 'file.cjs')
  const expectedPkgPath = join(fixtures, 'type-commonjs-cjs', 'package.json')
  const { esm, path, type, extType, pkgPath } = isFileEsm.sync(inputPath)
  is(esm, false)
  is(path, inputPath)
  is(expectedPkgPath, pkgPath)
  is(type, 'commonjs')
  is(extType, 'c')
})

test('type-commonjs-js sync', async ({ is }) => {
  const inputPath = join(fixtures, 'type-commonjs-js', 'file.js')
  const expectedPkgPath = join(fixtures, 'type-commonjs-js', 'package.json')
  const { esm, path, type, extType, pkgPath } = isFileEsm.sync(inputPath)
  is(esm, false)
  is(path, inputPath)
  is(expectedPkgPath, pkgPath)
  is(type, 'commonjs')
  is(extType, 'j')
})

test('type-commonjs-mjs sync', async ({ is }) => {
  const inputPath = join(fixtures, 'type-commonjs-mjs', 'file.mjs')
  const expectedPkgPath = join(fixtures, 'type-commonjs-mjs', 'package.json')
  const { esm, path, type, extType, pkgPath } = isFileEsm.sync(inputPath)
  is(esm, true)
  is(path, inputPath)
  is(expectedPkgPath, pkgPath)
  is(type, 'commonjs')
  is(extType, 'm')
})

test('type-module-cjs sync', async ({ is }) => {
  const inputPath = join(fixtures, 'type-module-cjs', 'file.cjs')
  const expectedPkgPath = join(fixtures, 'type-module-cjs', 'package.json')
  const { esm, path, type, extType, pkgPath } = isFileEsm.sync(inputPath)
  is(esm, false)
  is(path, inputPath)
  is(expectedPkgPath, pkgPath)
  is(type, 'module')
  is(extType, 'c')
})

test('type-module-js sync', async ({ is }) => {
  const inputPath = join(fixtures, 'type-module-js', 'file.js')
  const expectedPkgPath = join(fixtures, 'type-module-js', 'package.json')
  const { esm, path, type, extType, pkgPath } = isFileEsm.sync(inputPath)
  is(esm, true)
  is(path, inputPath)
  is(expectedPkgPath, pkgPath)
  is(type, 'module')
  is(extType, 'j')
})

test('type-module-mjs sync', async ({ is }) => {
  const inputPath = join(fixtures, 'type-module-mjs', 'file.mjs')
  const expectedPkgPath = join(fixtures, 'type-module-mjs', 'package.json')
  const { esm, path, type, extType, pkgPath } = isFileEsm.sync(inputPath)
  is(esm, true)
  is(path, inputPath)
  is(expectedPkgPath, pkgPath)
  is(type, 'module')
  is(extType, 'm')
})

test('type-undefined-cjs sync', async ({ is }) => {
  const inputPath = join(fixtures, 'type-undefined-cjs', 'file.cjs')
  const expectedPkgPath = join(fixtures, 'type-undefined-cjs', 'package.json')
  const { esm, path, type, extType, pkgPath } = isFileEsm.sync(inputPath)
  is(esm, false)
  is(path, inputPath)
  is(expectedPkgPath, pkgPath)
  is(type, undefined)
  is(extType, 'c')
})

test('type-undefined-js sync', async ({ is }) => {
  const inputPath = join(fixtures, 'type-undefined-js', 'file.js')
  const expectedPkgPath = join(fixtures, 'type-undefined-js', 'package.json')
  const { esm, path, type, extType, pkgPath } = isFileEsm.sync(inputPath)
  is(esm, false)
  is(path, inputPath)
  is(expectedPkgPath, pkgPath)
  is(type, undefined)
  is(extType, 'j')
})

test('type-undefined-mjs sync', async ({ is }) => {
  const inputPath = join(fixtures, 'type-undefined-mjs', 'file.mjs')
  const expectedPkgPath = join(fixtures, 'type-undefined-mjs', 'package.json')
  const { esm, path, type, extType, pkgPath } = isFileEsm.sync(inputPath)
  is(esm, true)
  is(path, inputPath)
  is(expectedPkgPath, pkgPath)
  is(type, undefined)
  is(extType, 'm')
})

test('path must be string (sync)', async ({ throws }) => {
  throws(() => isFileEsm.sync(), Error(ERR_PATH_MUST_BE_STRING))
  throws(() => isFileEsm.sync({}), Error(ERR_PATH_MUST_BE_STRING))
})

test('path must be absolute (sync)', async ({ throws }) => {
  throws(() => isFileEsm.sync('../foo.js'), Error(ERR_PATH_MUST_BE_ABSOLUTE))
  throws(() => isFileEsm.sync('./bar/foo.mjs'), Error(ERR_PATH_MUST_BE_ABSOLUTE))
})

test('path must have ext (sync)', async ({ throws }) => {
  throws(() => isFileEsm.sync('/bar/foo'), Error(ERR_PATH_MUST_HAVE_VALID_EXT))
})

test('path must have valid ext (sync)', async ({ throws }) => {
  throws(() => isFileEsm.sync('/bar/foo.ext'), Error(ERR_PATH_MUST_HAVE_VALID_EXT))
})

test('path must exist (promise)', async ({ throws }) => {
  throws(() => isFileEsm.sync(join(fixtures, 'bar', 'foo.js')), Error(ERR_PATH_MUST_EXIST))
})

test('type-bad-cjs sync', async ({ is, throws }) => {
  const inputPath = join(fixtures, 'type-bad-cjs', 'file.cjs')
  const expectedPkgPath = join(fixtures, 'type-bad-cjs', 'package.json')
  let error = null
  throws(() => {
    try {
      isFileEsm.sync(inputPath)
    } catch (err) {
      error = err
      throw err
    }
  }, ERR_BAD_TYPE)
  const { path, type, extType, pkgPath } = error.meta
  is(path, inputPath)
  is(expectedPkgPath, pkgPath)
  is(type, 'bad')
  is(extType, 'c')
})

test('type-bad-js sync', async ({ is, throws }) => {
  const inputPath = join(fixtures, 'type-bad-js', 'file.js')
  const expectedPkgPath = join(fixtures, 'type-bad-js', 'package.json')
  let error = null
  throws(() => {
    try {
      isFileEsm.sync(inputPath)
    } catch (err) {
      error = err
      throw err
    }
  }, ERR_BAD_TYPE)
  const { path, type, extType, pkgPath } = error.meta
  is(path, inputPath)
  is(expectedPkgPath, pkgPath)
  is(type, 'bad')
  is(extType, 'j')
})

test('type-bad-mjs sync', async ({ is, throws }) => {
  const inputPath = join(fixtures, 'type-bad-mjs', 'file.mjs')
  const expectedPkgPath = join(fixtures, 'type-bad-mjs', 'package.json')
  let error = null
  throws(() => {
    try {
      isFileEsm.sync(inputPath)
    } catch (err) {
      error = err
      throw err
    }
  }, ERR_BAD_TYPE)
  const { path, type, extType, pkgPath } = error.meta
  is(path, inputPath)
  is(expectedPkgPath, pkgPath)
  is(type, 'bad')
  is(extType, 'm')
})

test('package.json read error propagation (sync)', async ({ throws, tearDown }) => {
  const inputPath = join(fixtures, 'type-bad-js', 'file.js')
  const expectedPkgPath = join(fixtures, 'type-bad-js', 'package.json')
  tearDown(() => chmodSync(expectedPkgPath, 0o644))
  chmodSync(expectedPkgPath, 0o000)
  throws(() => isFileEsm.sync(inputPath), ERR_PERMISSION_DENIED)
})

test('type-commonjs-cjs callback', async ({ is, error }) => {
  const inputPath = join(fixtures, 'type-commonjs-cjs', 'file.cjs')
  const expectedPkgPath = join(fixtures, 'type-commonjs-cjs', 'package.json')
  const until = when()
  isFileEsm(inputPath, (err, { esm, path, type, extType, pkgPath }) => {
    error(err)
    is(esm, false)
    is(path, inputPath)
    is(expectedPkgPath, pkgPath)
    is(type, 'commonjs')
    is(extType, 'c')
    until()
  })
  await until.done()
})

test('type-commonjs-js callback', async ({ is, error }) => {
  const inputPath = join(fixtures, 'type-commonjs-js', 'file.js')
  const expectedPkgPath = join(fixtures, 'type-commonjs-js', 'package.json')
  const until = when()
  isFileEsm(inputPath, (err, { esm, path, type, extType, pkgPath }) => {
    error(err)
    is(esm, false)
    is(path, inputPath)
    is(expectedPkgPath, pkgPath)
    is(type, 'commonjs')
    is(extType, 'j')
    until()
  })
  await until.done()
})

test('type-commonjs-mjs callback', async ({ is, error }) => {
  const inputPath = join(fixtures, 'type-commonjs-mjs', 'file.mjs')
  const expectedPkgPath = join(fixtures, 'type-commonjs-mjs', 'package.json')
  const until = when()
  isFileEsm(inputPath, (err, { esm, path, type, extType, pkgPath }) => {
    error(err)
    is(esm, true)
    is(path, inputPath)
    is(expectedPkgPath, pkgPath)
    is(type, 'commonjs')
    is(extType, 'm')
    until()
  })
  await until.done()
})

test('type-module-cjs callback', async ({ is, error }) => {
  const inputPath = join(fixtures, 'type-module-cjs', 'file.cjs')
  const expectedPkgPath = join(fixtures, 'type-module-cjs', 'package.json')
  const until = when()
  isFileEsm(inputPath, (err, { esm, path, type, extType, pkgPath }) => {
    error(err)
    is(esm, false)
    is(path, inputPath)
    is(expectedPkgPath, pkgPath)
    is(type, 'module')
    is(extType, 'c')
    until()
  })
  await until.done()
})

test('type-module-js callback', async ({ is, error }) => {
  const inputPath = join(fixtures, 'type-module-js', 'file.js')
  const expectedPkgPath = join(fixtures, 'type-module-js', 'package.json')
  const until = when()
  isFileEsm(inputPath, (err, { esm, path, type, extType, pkgPath }) => {
    error(err)
    is(esm, true)
    is(path, inputPath)
    is(expectedPkgPath, pkgPath)
    is(type, 'module')
    is(extType, 'j')
    until()
  })
  await until.done()
})

test('type-module-mjs callback', async ({ is, error }) => {
  const inputPath = join(fixtures, 'type-module-mjs', 'file.mjs')
  const expectedPkgPath = join(fixtures, 'type-module-mjs', 'package.json')
  const until = when()
  isFileEsm(inputPath, (err, { esm, path, type, extType, pkgPath }) => {
    error(err)
    is(esm, true)
    is(path, inputPath)
    is(expectedPkgPath, pkgPath)
    is(type, 'module')
    is(extType, 'm')
    until()
  })
  await until.done()
})

test('type-undefined-cjs callback', async ({ is, error }) => {
  const inputPath = join(fixtures, 'type-undefined-cjs', 'file.cjs')
  const expectedPkgPath = join(fixtures, 'type-undefined-cjs', 'package.json')
  const until = when()
  isFileEsm(inputPath, (err, { esm, path, type, extType, pkgPath }) => {
    error(err)
    is(esm, false)
    is(path, inputPath)
    is(expectedPkgPath, pkgPath)
    is(type, undefined)
    is(extType, 'c')
    until()
  })
  await until.done()
})

test('type-undefined-js callback', async ({ is, error }) => {
  const inputPath = join(fixtures, 'type-undefined-js', 'file.js')
  const expectedPkgPath = join(fixtures, 'type-undefined-js', 'package.json')
  const until = when()
  isFileEsm(inputPath, (err, { esm, path, type, extType, pkgPath }) => {
    error(err)
    is(esm, false)
    is(path, inputPath)
    is(expectedPkgPath, pkgPath)
    is(type, undefined)
    is(extType, 'j')
    until()
  })
  await until.done()
})

test('type-undefined-mjs callback', async ({ is, error }) => {
  const inputPath = join(fixtures, 'type-undefined-mjs', 'file.mjs')
  const expectedPkgPath = join(fixtures, 'type-undefined-mjs', 'package.json')
  const until = when()
  isFileEsm(inputPath, (err, { esm, path, type, extType, pkgPath }) => {
    error(err)
    is(esm, true)
    is(path, inputPath)
    is(expectedPkgPath, pkgPath)
    is(type, undefined)
    is(extType, 'm')
    until()
  })
  await until.done()
})

test('path must be string (callback)', async ({ match }) => {
  const until1 = when()
  isFileEsm(undefined, (err) => {
    match(err, Error(ERR_PATH_MUST_BE_STRING))
    until1()
  })
  const until2 = when()
  isFileEsm({}, (err) => {
    match(err, Error(ERR_PATH_MUST_BE_STRING))
    until2()
  })
  await Promise.all([until1.done(), until2.done()])
})

test('path must be absolute (callback)', async ({ match }) => {
  const until1 = when()
  isFileEsm('../foo.js', (err) => {
    match(err, Error(ERR_PATH_MUST_BE_ABSOLUTE))
    until1()
  })
  const until2 = when()
  isFileEsm('./bar/foo.mjs', (err) => {
    match(err, Error(ERR_PATH_MUST_BE_ABSOLUTE))
    until2()
  })
  await Promise.all([until1.done(), until2.done()])
})

test('path must have ext (callback)', async ({ match }) => {
  const until = when()
  isFileEsm('/bar/foo', (err) => {
    match(err, Error(ERR_PATH_MUST_HAVE_VALID_EXT))
    until()
  })
  await until.done()
})

test('path must have valid ext (callback)', async ({ match }) => {
  const until = when()
  isFileEsm('/bar/foo.ext', (err) => {
    match(err, Error(ERR_PATH_MUST_HAVE_VALID_EXT))
    until()
  })
  await until.done()
})

test('path must exist (callback)', async ({ match }) => {
  const until = when()
  isFileEsm(join(fixtures, 'bar', 'foo.js'), (err) => {
    match(err, Error(ERR_PATH_MUST_EXIST))
    until()
  })
  await until.done()
})

test('type-bad-cjs callback', async ({ is }) => {
  const inputPath = join(fixtures, 'type-bad-cjs', 'file.cjs')
  const expectedPkgPath = join(fixtures, 'type-bad-cjs', 'package.json')
  const until = when()
  isFileEsm(inputPath, (err) => {
    is(err.message, ERR_BAD_TYPE)
    const { path, type, extType, pkgPath } = err.meta
    is(path, inputPath)
    is(expectedPkgPath, pkgPath)
    is(type, 'bad')
    is(extType, 'c')
    until()
  })
  await until.done()
})

test('type-bad-js callback', async ({ is }) => {
  const inputPath = join(fixtures, 'type-bad-js', 'file.js')
  const expectedPkgPath = join(fixtures, 'type-bad-js', 'package.json')
  const until = when()
  isFileEsm(inputPath, (err) => {
    is(err.message, ERR_BAD_TYPE)
    const { path, type, extType, pkgPath } = err.meta
    is(path, inputPath)
    is(expectedPkgPath, pkgPath)
    is(type, 'bad')
    is(extType, 'j')
    until()
  })
  await until.done()
})

test('type-bad-mjs callback', async ({ is }) => {
  const inputPath = join(fixtures, 'type-bad-mjs', 'file.mjs')
  const expectedPkgPath = join(fixtures, 'type-bad-mjs', 'package.json')
  const until = when()
  isFileEsm(inputPath, (err) => {
    is(err.message, ERR_BAD_TYPE)
    const { path, type, extType, pkgPath } = err.meta
    is(path, inputPath)
    is(expectedPkgPath, pkgPath)
    is(type, 'bad')
    is(extType, 'm')
    until()
  })
  await until.done()
})

test('package.json read error propagation (callback)', async ({ match, tearDown }) => {
  const inputPath = join(fixtures, 'type-bad-js', 'file.js')
  const expectedPkgPath = join(fixtures, 'type-bad-js', 'package.json')
  tearDown(() => chmodSync(expectedPkgPath, 0o644))
  chmodSync(expectedPkgPath, 0o000)
  const until = when()
  isFileEsm(inputPath, (err) => {
    match(err, ERR_PERMISSION_DENIED)
    until()
  })
  await until.done()
})


code:
/**
Check if the character represented by a given [Unicode code point](https://en.wikipedia.org/wiki/Code_point) is [fullwidth](https://en.wikipedia.org/wiki/Halfwidth_and_fullwidth_forms).

@param codePoint - The [code point](https://en.wikipedia.org/wiki/Code_point) of a character.

@example
```
import isFullwidthCodePoint from 'is-fullwidth-code-point';

isFullwidthCodePoint('谢'.codePointAt(0));
//=> true

isFullwidthCodePoint('a'.codePointAt(0));
//=> false
```
*/
export default function isFullwidthCodePoint(codePoint: number): boolean;

license: mit


code:
/* eslint-disable yoda */

export default function isFullwidthCodePoint(codePoint) {
	if (!Number.isInteger(codePoint)) {
		return false;
	}

	// Code points are derived from:
	// https://unicode.org/Public/UNIDATA/EastAsianWidth.txt
	return codePoint >= 0x1100 && (
		codePoint <= 0x115F || // Hangul Jamo
		codePoint === 0x2329 || // LEFT-POINTING ANGLE BRACKET
		codePoint === 0x232A || // RIGHT-POINTING ANGLE BRACKET
		// CJK Radicals Supplement .. Enclosed CJK Letters and Months
		(0x2E80 <= codePoint && codePoint <= 0x3247 && codePoint !== 0x303F) ||
		// Enclosed CJK Letters and Months .. CJK Unified Ideographs Extension A
		(0x3250 <= codePoint && codePoint <= 0x4DBF) ||
		// CJK Unified Ideographs .. Yi Radicals
		(0x4E00 <= codePoint && codePoint <= 0xA4C6) ||
		// Hangul Jamo Extended-A
		(0xA960 <= codePoint && codePoint <= 0xA97C) ||
		// Hangul Syllables
		(0xAC00 <= codePoint && codePoint <= 0xD7A3) ||
		// CJK Compatibility Ideographs
		(0xF900 <= codePoint && codePoint <= 0xFAFF) ||
		// Vertical Forms
		(0xFE10 <= codePoint && codePoint <= 0xFE19) ||
		// CJK Compatibility Forms .. Small Form Variants
		(0xFE30 <= codePoint && codePoint <= 0xFE6B) ||
		// Halfwidth and Fullwidth Forms
		(0xFF01 <= codePoint && codePoint <= 0xFF60) ||
		(0xFFE0 <= codePoint && codePoint <= 0xFFE6) ||
		// Kana Supplement
		(0x1B000 <= codePoint && codePoint <= 0x1B001) ||
		// Enclosed Ideographic Supplement
		(0x1F200 <= codePoint && codePoint <= 0x1F251) ||
		// CJK Unified Ideographs Extension B .. Tertiary Ideographic Plane
		(0x20000 <= codePoint && codePoint <= 0x3FFFD)
	);
}


is-fullwidth-code-point

description: Check if the character represented by a given Unicode code point is fullwidth

license: MIT

repository: sindresorhus/is-fullwidth-code-point

type: module

test: xo && ava && tsd

keywords: fullwidth full-width full width unicode character string codepoint code point is detect check


code:
# is-fullwidth-code-point

> Check if the character represented by a given [Unicode code point](https://en.wikipedia.org/wiki/Code_point) is [fullwidth](https://en.wikipedia.org/wiki/Halfwidth_and_fullwidth_forms)

## Install

```
$ npm install is-fullwidth-code-point
```

## Usage

```js
import isFullwidthCodePoint from 'is-fullwidth-code-point';

isFullwidthCodePoint('谢'.codePointAt(0));
//=> true

isFullwidthCodePoint('a'.codePointAt(0));
//=> false
```

## API

### isFullwidthCodePoint(codePoint)

#### codePoint

Type: `number`

The [code point](https://en.wikipedia.org/wiki/Code_point) of a character.

---

		Get professional support for this package with a Tidelift subscription

		Tidelift helps make open source sustainable for maintainers while giving companies
assurances about security, maintenance, and licensing for their dependencies.


code:
# is-glob [![NPM version](https://img.shields.io/npm/v/is-glob.svg?style=flat)](https://www.npmjs.com/package/is-glob) [![NPM monthly downloads](https://img.shields.io/npm/dm/is-glob.svg?style=flat)](https://npmjs.org/package/is-glob) [![NPM total downloads](https://img.shields.io/npm/dt/is-glob.svg?style=flat)](https://npmjs.org/package/is-glob) [![Build Status](https://img.shields.io/github/workflow/status/micromatch/is-glob/dev)](https://github.com/micromatch/is-glob/actions)

> Returns `true` if the given string looks like a glob pattern or an extglob pattern. This makes it easy to create code that only uses external modules like node-glob when necessary, resulting in much faster code execution and initialization time, and a better user experience.

Please consider following this project's author, [Jon Schlinkert](https://github.com/jonschlinkert), and consider starring the project to show your :heart: and support.

## Install

Install with [npm](https://www.npmjs.com/):

```sh
$ npm install --save is-glob
```

You might also be interested in [is-valid-glob](https://github.com/jonschlinkert/is-valid-glob) and [has-glob](https://github.com/jonschlinkert/has-glob).

## Usage

```js
var isGlob = require('is-glob');
```

### Default behavior

**True**

Patterns that have glob characters or regex patterns will return `true`:

```js
isGlob('!foo.js');
isGlob('*.js');
isGlob('**/abc.js');
isGlob('abc/*.js');
isGlob('abc/(aaa|bbb).js');
isGlob('abc/[a-z].js');
isGlob('abc/{a,b}.js');
//=> true
```

Extglobs

```js
isGlob('abc/@(a).js');
isGlob('abc/!(a).js');
isGlob('abc/+(a).js');
isGlob('abc/*(a).js');
isGlob('abc/?(a).js');
//=> true
```

**False**

Escaped globs or extglobs return `false`:

```js
isGlob('abc/\\@(a).js');
isGlob('abc/\\!(a).js');
isGlob('abc/\\+(a).js');
isGlob('abc/\\*(a).js');
isGlob('abc/\\?(a).js');
isGlob('\\!foo.js');
isGlob('\\*.js');
isGlob('\\*\\*/abc.js');
isGlob('abc/\\*.js');
isGlob('abc/\\(aaa|bbb).js');
isGlob('abc/\\[a-z].js');
isGlob('abc/\\{a,b}.js');
//=> false
```

Patterns that do not have glob patterns return `false`:

```js
isGlob('abc.js');
isGlob('abc/def/ghi.js');
isGlob('foo.js');
isGlob('abc/@.js');
isGlob('abc/+.js');
isGlob('abc/?.js');
isGlob();
isGlob(null);
//=> false
```

Arrays are also `false` (If you want to check if an array has a glob pattern, use [has-glob](https://github.com/jonschlinkert/has-glob)):

```js
isGlob(['**/*.js']);
isGlob(['foo.js']);
//=> false
```

### Option strict

When `options.strict === false` the behavior is less strict in determining if a pattern is a glob. Meaning that
some patterns that would return `false` may return `true`. This is done so that matching libraries like [micromatch](https://github.com/micromatch/micromatch) have a chance at determining if the pattern is a glob or not.

**True**

Patterns that have glob characters or regex patterns will return `true`:

```js
isGlob('!foo.js', {strict: false});
isGlob('*.js', {strict: false});
isGlob('**/abc.js', {strict: false});
isGlob('abc/*.js', {strict: false});
isGlob('abc/(aaa|bbb).js', {strict: false});
isGlob('abc/[a-z].js', {strict: false});
isGlob('abc/{a,b}.js', {strict: false});
//=> true
```

Extglobs

```js
isGlob('abc/@(a).js', {strict: false});
isGlob('abc/!(a).js', {strict: false});
isGlob('abc/+(a).js', {strict: false});
isGlob('abc/*(a).js', {strict: false});
isGlob('abc/?(a).js', {strict: false});
//=> true
```

**False**

Escaped globs or extglobs return `false`:

```js
isGlob('\\!foo.js', {strict: false});
isGlob('\\*.js', {strict: false});
isGlob('\\*\\*/abc.js', {strict: false});
isGlob('abc/\\*.js', {strict: false});
isGlob('abc/\\(aaa|bbb).js', {strict: false});
isGlob('abc/\\[a-z].js', {strict: false});
isGlob('abc/\\{a,b}.js', {strict: false});
//=> false
```

## About

Contributing

Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](../../issues/new).

Running Tests

Running and reviewing unit tests is a great way to get familiarized with a library and its API. You can install dependencies and run tests with the following command:

```sh
$ npm install && npm test
```

Building docs

_(This project's readme.md is generated by [verb](https://github.com/verbose/verb-generate-readme), please don't edit the readme directly. Any changes to the readme must be made in the [.verb.md](.verb.md) readme template.)_

To generate the readme, run the following command:

```sh
$ npm install -g verbose/verb#dev verb-generate-readme && verb
```

### Related projects

You might also be interested in these projects:

* [assemble](https://www.npmjs.com/package/assemble): Get the rocks out of your socks! Assemble makes you fast at creating web projects… [more](https://github.com/assemble/assemble) | [homepage](https://github.com/assemble/assemble "Get the rocks out of your socks! Assemble makes you fast at creating web projects. Assemble is used by thousands of projects for rapid prototyping, creating themes, scaffolds, boilerplates, e-books, UI components, API documentation, blogs, building websit")
* [base](https://www.npmjs.com/package/base): Framework for rapidly creating high quality, server-side node.js applications, using plugins like building blocks | [homepage](https://github.com/node-base/base "Framework for rapidly creating high quality, server-side node.js applications, using plugins like building blocks")
* [update](https://www.npmjs.com/package/update): Be scalable! Update is a new, open source developer framework and CLI for automating updates… [more](https://github.com/update/update) | [homepage](https://github.com/update/update "Be scalable! Update is a new, open source developer framework and CLI for automating updates of any kind in code projects.")
* [verb](https://www.npmjs.com/package/verb): Documentation generator for GitHub projects. Verb is extremely powerful, easy to use, and is used… [more](https://github.com/verbose/verb) | [homepage](https://github.com/verbose/verb "Documentation generator for GitHub projects. Verb is extremely powerful, easy to use, and is used on hundreds of projects of all sizes to generate everything from API docs to readmes.")

### Contributors

| **Commits** | **Contributor** |
| --- | --- |
| 47 | [jonschlinkert](https://github.com/jonschlinkert) |
| 5  | [doowb](https://github.com/doowb) |
| 1  | [phated](https://github.com/phated) |
| 1  | [danhper](https://github.com/danhper) |
| 1  | [paulmillr](https://github.com/paulmillr) |

### Author

**Jon Schlinkert**

* [GitHub Profile](https://github.com/jonschlinkert)
* [Twitter Profile](https://twitter.com/jonschlinkert)
* [LinkedIn Profile](https://linkedin.com/in/jonschlinkert)

### License

Copyright © 2019, [Jon Schlinkert](https://github.com/jonschlinkert).
Released under the [MIT License](LICENSE).

***

_This file was generated by [verb-generate-readme](https://github.com/verbose/verb-generate-readme), v0.8.0, on March 27, 2019._


code:
/*!
 * is-glob <https://github.com/jonschlinkert/is-glob>
 *
 * Copyright (c) 2014-2017, Jon Schlinkert.
 * Released under the MIT License.
 */

var isExtglob = require('is-extglob');
var chars = { '{': '}', '(': ')', '[': ']'};
var strictCheck = function(str) {
  if (str[0] === '!') {
    return true;
  }
  var index = 0;
  var pipeIndex = -2;
  var closeSquareIndex = -2;
  var closeCurlyIndex = -2;
  var closeParenIndex = -2;
  var backSlashIndex = -2;
  while (index < str.length) {
    if (str[index] === '*') {
      return true;
    }

    if (str[index + 1] === '?' && /[\].+)]/.test(str[index])) {
      return true;
    }

    if (closeSquareIndex !== -1 && str[index] === '[' && str[index + 1] !== ']') {
      if (closeSquareIndex < index) {
        closeSquareIndex = str.indexOf(']', index);
      }
      if (closeSquareIndex > index) {
        if (backSlashIndex === -1 || backSlashIndex > closeSquareIndex) {
          return true;
        }
        backSlashIndex = str.indexOf('\\', index);
        if (backSlashIndex === -1 || backSlashIndex > closeSquareIndex) {
          return true;
        }
      }
    }

    if (closeCurlyIndex !== -1 && str[index] === '{' && str[index + 1] !== '}') {
      closeCurlyIndex = str.indexOf('}', index);
      if (closeCurlyIndex > index) {
        backSlashIndex = str.indexOf('\\', index);
        if (backSlashIndex === -1 || backSlashIndex > closeCurlyIndex) {
          return true;
        }
      }
    }

    if (closeParenIndex !== -1 && str[index] === '(' && str[index + 1] === '?' && /[:!=]/.test(str[index + 2]) && str[index + 3] !== ')') {
      closeParenIndex = str.indexOf(')', index);
      if (closeParenIndex > index) {
        backSlashIndex = str.indexOf('\\', index);
        if (backSlashIndex === -1 || backSlashIndex > closeParenIndex) {
          return true;
        }
      }
    }

    if (pipeIndex !== -1 && str[index] === '(' && str[index + 1] !== '|') {
      if (pipeIndex < index) {
        pipeIndex = str.indexOf('|', index);
      }
      if (pipeIndex !== -1 && str[pipeIndex + 1] !== ')') {
        closeParenIndex = str.indexOf(')', pipeIndex);
        if (closeParenIndex > pipeIndex) {
          backSlashIndex = str.indexOf('\\', pipeIndex);
          if (backSlashIndex === -1 || backSlashIndex > closeParenIndex) {
            return true;
          }
        }
      }
    }

    if (str[index] === '\\') {
      var open = str[index + 1];
      index += 2;
      var close = chars[open];

      if (close) {
        var n = str.indexOf(close, index);
        if (n !== -1) {
          index = n + 1;
        }
      }

      if (str[index] === '!') {
        return true;
      }
    } else {
      index++;
    }
  }
  return false;
};

var relaxedCheck = function(str) {
  if (str[0] === '!') {
    return true;
  }
  var index = 0;
  while (index < str.length) {
    if (/[*?{}()[\]]/.test(str[index])) {
      return true;
    }

    if (str[index] === '\\') {
      var open = str[index + 1];
      index += 2;
      var close = chars[open];

      if (close) {
        var n = str.indexOf(close, index);
        if (n !== -1) {
          index = n + 1;
        }
      }

      if (str[index] === '!') {
        return true;
      }
    } else {
      index++;
    }
  }
  return false;
};

module.exports = function isGlob(str, options) {
  if (typeof str !== 'string' || str === '') {
    return false;
  }

  if (isExtglob(str)) {
    return true;
  }

  var check = strictCheck;

  // optionally relax check
  if (options && options.strict === false) {
    check = relaxedCheck;
  }

  return check(str);
};


is-glob

description: Returns `true` if the given string looks like a glob pattern or an extglob pattern. This makes it easy to create code that only uses external modules like node-glob when necessary, resulting in much faster code execution and initialization time, and a better user experience.

repository: micromatch/is-glob

test: mocha && node benchmark.js

keywords: bash braces check exec expression extglob glob globbing globstar is match matches pattern regex regular string test

layout: default

list: assemble base update verb

reflinks: assemble bach base composer gulp has-glob is-valid-glob micromatch npm scaffold verb vinyl


code:
/// <reference types="node"/>

declare namespace isInteractive {
	interface Options {
		/**
		The stream to check.

		@default process.stdout
		*/
		readonly stream?: NodeJS.WritableStream;
	}
}

/**
Check if stdout or stderr is [interactive](https://unix.stackexchange.com/a/43389/7678).

It checks that the stream is [TTY](https://jameshfisher.com/2017/12/09/what-is-a-tty/), not a dumb terminal, and not running in a CI.

This can be useful to decide whether to present interactive UI or animations in the terminal.

@example
```
import isInteractive = require('is-interactive');

isInteractive();
//=> true
```
*/
declare function isInteractive(options?: isInteractive.Options): boolean;

export = isInteractive;


code:
'use strict';

module.exports = ({stream = process.stdout} = {}) => {
	return Boolean(
		stream && stream.isTTY &&
		process.env.TERM !== 'dumb' &&
		!('CI' in process.env)
	);
};


is-interactive

description: Check if stdout or stderr is interactive

repository: sindresorhus/is-interactive

keywords: interactive stdout stderr detect is terminal shell tty


code:
# is-interactive [![Build Status](https://travis-ci.com/sindresorhus/is-interactive.svg?branch=master)](https://travis-ci.com/sindresorhus/is-interactive)

> Check if stdout or stderr is [interactive](https://unix.stackexchange.com/a/43389/7678)

It checks that the stream is [TTY](https://jameshfisher.com/2017/12/09/what-is-a-tty/), not a dumb terminal, and not running in a CI.

This can be useful to decide whether to present interactive UI or animations in the terminal.

## Install

```
$ npm install is-interactive
```

## Usage

```js
const isInteractive = require('is-interactive');

isInteractive();
//=> true
```

## API

### isInteractive(options?)

#### options

Type: `object`

##### stream

Type: [`stream.Writable`](https://nodejs.org/api/stream.html#stream_class_stream_writable)<br>
Default: [`process.stdout`](https://nodejs.org/api/process.html#process_process_stdout)

The stream to check.

## FAQ

#### Why are you not using [`ci-info`](https://github.com/watson/ci-info) for the CI check?

It's silly to have to detect individual CIs. They should identify themselves with the `CI` environment variable, and most do just that. A manually maintained list of detections will easily get out of date. And if a package using `ci-info` doesn't update to the latest version all the time, they will not support certain CIs. It also creates unpredictability as you might assume a CI is not supported and then suddenly it gets supported and you didn't account for that. In addition, some of the manual detections are loose and might cause false-positives which could create hard-to-debug bugs.

#### Why does this even exist? It's just a few lines.

It's not about the number of lines, but rather discoverability and documentation. A lot of people wouldn't even know they need this. Feel free to copy-paste the code if you don't want the dependency. You might also want to read [this blog post](https://blog.sindresorhus.com/small-focused-modules-9238d977a92a).


code:
# is-number [![NPM version](https://img.shields.io/npm/v/is-number.svg?style=flat)](https://www.npmjs.com/package/is-number) [![NPM monthly downloads](https://img.shields.io/npm/dm/is-number.svg?style=flat)](https://npmjs.org/package/is-number) [![NPM total downloads](https://img.shields.io/npm/dt/is-number.svg?style=flat)](https://npmjs.org/package/is-number) [![Linux Build Status](https://img.shields.io/travis/jonschlinkert/is-number.svg?style=flat&label=Travis)](https://travis-ci.org/jonschlinkert/is-number)

> Returns true if the value is a finite number.

Please consider following this project's author, [Jon Schlinkert](https://github.com/jonschlinkert), and consider starring the project to show your :heart: and support.

## Install

Install with [npm](https://www.npmjs.com/):

```sh
$ npm install --save is-number
```

## Why is this needed?

In JavaScript, it's not always as straightforward as it should be to reliably check if a value is a number. It's common for devs to use `+`, `-`, or `Number()` to cast a string value to a number (for example, when values are returned from user input, regex matches, parsers, etc). But there are many non-intuitive edge cases that yield unexpected results:

```js
console.log(+[]); //=> 0
console.log(+''); //=> 0
console.log(+'   '); //=> 0
console.log(typeof NaN); //=> 'number'
```

This library offers a performant way to smooth out edge cases like these.

## Usage

```js
const isNumber = require('is-number');
```

See the [tests](./test.js) for more examples.

### true

```js
isNumber(5e3);               // true
isNumber(0xff);              // true
isNumber(-1.1);              // true
isNumber(0);                 // true
isNumber(1);                 // true
isNumber(1.1);               // true
isNumber(10);                // true
isNumber(10.10);             // true
isNumber(100);               // true
isNumber('-1.1');            // true
isNumber('0');               // true
isNumber('012');             // true
isNumber('0xff');            // true
isNumber('1');               // true
isNumber('1.1');             // true
isNumber('10');              // true
isNumber('10.10');           // true
isNumber('100');             // true
isNumber('5e3');             // true
isNumber(parseInt('012'));   // true
isNumber(parseFloat('012')); // true
```

### False

Everything else is false, as you would expect:

```js
isNumber(Infinity);          // false
isNumber(NaN);               // false
isNumber(null);              // false
isNumber(undefined);         // false
isNumber('');                // false
isNumber('   ');             // false
isNumber('foo');             // false
isNumber([1]);               // false
isNumber([]);                // false
isNumber(function () {});    // false
isNumber({});                // false
```

## Release history

### 7.0.0

* Refactor. Now uses `.isFinite` if it exists.
* Performance is about the same as v6.0 when the value is a string or number. But it's now 3x-4x faster when the value is not a string or number.

### 6.0.0

* Optimizations, thanks to @benaadams.

### 5.0.0

**Breaking changes**

* removed support for `instanceof Number` and `instanceof String`

## Benchmarks

As with all benchmarks, take these with a grain of salt. See the [benchmarks](./benchmark/index.js) for more detail.

```
# all
v7.0 x 413,222 ops/sec ±2.02% (86 runs sampled)
v6.0 x 111,061 ops/sec ±1.29% (85 runs sampled)
parseFloat x 317,596 ops/sec ±1.36% (86 runs sampled)
fastest is 'v7.0'

# string
v7.0 x 3,054,496 ops/sec ±1.05% (89 runs sampled)
v6.0 x 2,957,781 ops/sec ±0.98% (88 runs sampled)
parseFloat x 3,071,060 ops/sec ±1.13% (88 runs sampled)
fastest is 'parseFloat,v7.0'

# number
v7.0 x 3,146,895 ops/sec ±0.89% (89 runs sampled)
v6.0 x 3,214,038 ops/sec ±1.07% (89 runs sampled)
parseFloat x 3,077,588 ops/sec ±1.07% (87 runs sampled)
fastest is 'v6.0'
```

## About

Contributing

Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](../../issues/new).

Running Tests

Running and reviewing unit tests is a great way to get familiarized with a library and its API. You can install dependencies and run tests with the following command:

```sh
$ npm install && npm test
```

Building docs

_(This project's readme.md is generated by [verb](https://github.com/verbose/verb-generate-readme), please don't edit the readme directly. Any changes to the readme must be made in the [.verb.md](.verb.md) readme template.)_

To generate the readme, run the following command:

```sh
$ npm install -g verbose/verb#dev verb-generate-readme && verb
```

### Related projects

You might also be interested in these projects:

* [is-plain-object](https://www.npmjs.com/package/is-plain-object): Returns true if an object was created by the `Object` constructor. | [homepage](https://github.com/jonschlinkert/is-plain-object "Returns true if an object was created by the `Object` constructor.")
* [is-primitive](https://www.npmjs.com/package/is-primitive): Returns `true` if the value is a primitive.  | [homepage](https://github.com/jonschlinkert/is-primitive "Returns `true` if the value is a primitive. ")
* [isobject](https://www.npmjs.com/package/isobject): Returns true if the value is an object and not an array or null. | [homepage](https://github.com/jonschlinkert/isobject "Returns true if the value is an object and not an array or null.")
* [kind-of](https://www.npmjs.com/package/kind-of): Get the native type of a value. | [homepage](https://github.com/jonschlinkert/kind-of "Get the native type of a value.")

### Contributors

| **Commits** | **Contributor** |
| --- | --- |
| 49 | [jonschlinkert](https://github.com/jonschlinkert) |
| 5 | [charlike-old](https://github.com/charlike-old) |
| 1 | [benaadams](https://github.com/benaadams) |
| 1 | [realityking](https://github.com/realityking) |

### Author

**Jon Schlinkert**

* [LinkedIn Profile](https://linkedin.com/in/jonschlinkert)
* [GitHub Profile](https://github.com/jonschlinkert)
* [Twitter Profile](https://twitter.com/jonschlinkert)

### License

Copyright © 2018, [Jon Schlinkert](https://github.com/jonschlinkert).
Released under the [MIT License](LICENSE).

***

_This file was generated by [verb-generate-readme](https://github.com/verbose/verb-generate-readme), v0.6.0, on June 15, 2018._


code:
/*!
 * is-number <https://github.com/jonschlinkert/is-number>
 *
 * Copyright (c) 2014-present, Jon Schlinkert.
 * Released under the MIT License.
 */

'use strict';

module.exports = function(num) {
  if (typeof num === 'number') {
    return num - num === 0;
  }
  if (typeof num === 'string' && num.trim() !== '') {
    return Number.isFinite ? Number.isFinite(+num) : isFinite(+num);
  }
  return false;
};


is-number

description: Returns true if a number or string value is a finite number. Useful for regex matches, parsing, user input, etc.

repository: jonschlinkert/is-number

test: mocha

keywords: cast check coerce coercion finite integer is isnan is-nan is-num is-number isnumber isfinite istype kind math nan num number numeric parseFloat parseInt test type typeof value

list: is-plain-object is-primitive isobject kind-of


code:
/**
Check if a path is inside another path.

Note that relative paths are resolved against `process.cwd()` to make them absolute.

_Important:_ This package is meant for use with path manipulation. It does not check if the paths exist nor does it resolve symlinks. You should not use this as a security mechanism to guard against access to certain places on the file system.

@example
```
import isPathInside = require('is-path-inside');

isPathInside('a/b/c', 'a/b');
//=> true

isPathInside('a/b/c', 'x/y');
//=> false

isPathInside('a/b/c', 'a/b/c');
//=> false

isPathInside('/Users/sindresorhus/dev/unicorn', '/Users/sindresorhus');
//=> true
```
*/
declare function isPathInside(childPath: string, parentPath: string): boolean;

export = isPathInside;


code:
'use strict';
const path = require('path');

module.exports = (childPath, parentPath) => {
	const relation = path.relative(parentPath, childPath);
	return Boolean(
		relation &&
		relation !== '..' &&
		!relation.startsWith(`..${path.sep}`) &&
		relation !== path.resolve(childPath)
	);
};


is-path-inside

description: Check if a path is inside another path

repository: sindresorhus/is-path-inside

keywords: path inside folder directory dir file resolve


code:
# is-path-inside

> Check if a path is inside another path

## Install

```
$ npm install is-path-inside
```

## Usage

```js
const isPathInside = require('is-path-inside');

isPathInside('a/b/c', 'a/b');
//=> true

isPathInside('a/b/c', 'x/y');
//=> false

isPathInside('a/b/c', 'a/b/c');
//=> false

isPathInside('/Users/sindresorhus/dev/unicorn', '/Users/sindresorhus');
//=> true
```

## API

### isPathInside(childPath, parentPath)

Note that relative paths are resolved against `process.cwd()` to make them absolute.

**Important:** This package is meant for use with path manipulation. It does not check if the paths exist nor does it resolve symlinks. You should not use this as a security mechanism to guard against access to certain places on the file system.

#### childPath

Type: `string`

The path that should be inside `parentPath`.

#### parentPath

Type: `string`

The path that should contain `childPath`.

---

		Get professional support for this package with a Tidelift subscription

		Tidelift helps make open source sustainable for maintainers while giving companies
assurances about security, maintenance, and licensing for their dependencies.


code:
/**
Check if a value is a plain object.

An object is plain if it's created by either `{}`, `new Object()`, or `Object.create(null)`.

@example
```
import isPlainObject = require('is-plain-obj');

isPlainObject({foo: 'bar'});
//=> true

isPlainObject(new Object());
//=> true

isPlainObject(Object.create(null));
//=> true

isPlainObject([1, 2, 3]);
//=> false

class Unicorn {}
isPlainObject(new Unicorn());
//=> false
```
*/
declare function isPlainObject<Value = unknown>(value: unknown): value is Record<string | number | symbol, Value>;

export = isPlainObject;


code:
'use strict';

module.exports = value => {
	if (Object.prototype.toString.call(value) !== '[object Object]') {
		return false;
	}

	const prototype = Object.getPrototypeOf(value);
	return prototype === null || prototype === Object.prototype;
};


is-plain-obj

description: Check if a value is a plain object

repository: sindresorhus/is-plain-obj

keywords: object is check test type plain vanilla pure simple


code:
# is-plain-obj [![Build Status](https://travis-ci.com/sindresorhus/is-plain-obj.svg?branch=master)](https://travis-ci.com/github/sindresorhus/is-plain-obj)

> Check if a value is a plain object

An object is plain if it's created by either `{}`, `new Object()`, or `Object.create(null)`.

## Install

```
$ npm install is-plain-obj
```

## Usage

```js
const isPlainObject = require('is-plain-obj');

isPlainObject({foo: 'bar'});
//=> true

isPlainObject(new Object());
//=> true

isPlainObject(Object.create(null));
//=> true

isPlainObject([1, 2, 3]);
//=> false

class Unicorn {}
isPlainObject(new Unicorn());
//=> false
```

## Related

- [is-obj](https://github.com/sindresorhus/is-obj) - Check if a value is an object
- [is](https://github.com/sindresorhus/is) - Type check values

---

		Get professional support for this package with a Tidelift subscription

		Tidelift helps make open source sustainable for maintainers while giving companies
assurances about security, maintenance, and licensing for their dependencies.


code:
# is-plain-object [![NPM version](https://img.shields.io/npm/v/is-plain-object.svg?style=flat)](https://www.npmjs.com/package/is-plain-object) [![NPM monthly downloads](https://img.shields.io/npm/dm/is-plain-object.svg?style=flat)](https://npmjs.org/package/is-plain-object) [![NPM total downloads](https://img.shields.io/npm/dt/is-plain-object.svg?style=flat)](https://npmjs.org/package/is-plain-object) [![Linux Build Status](https://img.shields.io/travis/jonschlinkert/is-plain-object.svg?style=flat&label=Travis)](https://travis-ci.org/jonschlinkert/is-plain-object)

> Returns true if an object was created by the `Object` constructor.

## Install

Install with [npm](https://www.npmjs.com/):

```sh
$ npm install --save is-plain-object
```

Use [isobject](https://github.com/jonschlinkert/isobject) if you only want to check if the value is an object and not an array or null.

## Usage

```js
var isPlainObject = require('is-plain-object');
```

**true** when created by the `Object` constructor.

```js
isPlainObject(Object.create({}));
//=> true
isPlainObject(Object.create(Object.prototype));
//=> true
isPlainObject({foo: 'bar'});
//=> true
isPlainObject({});
//=> true
```

**false** when not created by the `Object` constructor.

```js
isPlainObject(1);
//=> false
isPlainObject(['foo', 'bar']);
//=> false
isPlainObject([]);
//=> false
isPlainObject(new Foo);
//=> false
isPlainObject(null);
//=> false
isPlainObject(Object.create(null));
//=> false
```

## About

### Related projects

* [is-number](https://www.npmjs.com/package/is-number): Returns true if the value is a number. comprehensive tests. | [homepage](https://github.com/jonschlinkert/is-number "Returns true if the value is a number. comprehensive tests.")
* [isobject](https://www.npmjs.com/package/isobject): Returns true if the value is an object and not an array or null. | [homepage](https://github.com/jonschlinkert/isobject "Returns true if the value is an object and not an array or null.")
* [kind-of](https://www.npmjs.com/package/kind-of): Get the native type of a value. | [homepage](https://github.com/jonschlinkert/kind-of "Get the native type of a value.")

### Contributing

Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](../../issues/new).

### Contributors

| **Commits** | **Contributor** |
| --- | --- |
| 17 | [jonschlinkert](https://github.com/jonschlinkert) |
| 6 | [stevenvachon](https://github.com/stevenvachon) |
| 3 | [onokumus](https://github.com/onokumus) |
| 1 | [wtgtybhertgeghgtwtg](https://github.com/wtgtybhertgeghgtwtg) |

### Building docs

_(This project's readme.md is generated by [verb](https://github.com/verbose/verb-generate-readme), please don't edit the readme directly. Any changes to the readme must be made in the [.verb.md](.verb.md) readme template.)_

To generate the readme, run the following command:

```sh
$ npm install -g verbose/verb#dev verb-generate-readme && verb
```

### Running tests

Running and reviewing unit tests is a great way to get familiarized with a library and its API. You can install dependencies and run tests with the following command:

```sh
$ npm install && npm test
```

### Author

**Jon Schlinkert**

* [github/jonschlinkert](https://github.com/jonschlinkert)
* [twitter/jonschlinkert](https://twitter.com/jonschlinkert)

### License

Copyright © 2017, [Jon Schlinkert](https://github.com/jonschlinkert).
Released under the [MIT License](LICENSE).

***

_This file was generated by [verb-generate-readme](https://github.com/verbose/verb-generate-readme), v0.6.0, on July 11, 2017._


code:
export = isPlainObject;

declare function isPlainObject(o: any): boolean;

declare namespace isPlainObject {}


code:
/*!
 * is-plain-object <https://github.com/jonschlinkert/is-plain-object>
 *
 * Copyright (c) 2014-2017, Jon Schlinkert.
 * Released under the MIT License.
 */

'use strict';

var isObject = require('isobject');

function isObjectObject(o) {
  return isObject(o) === true
    && Object.prototype.toString.call(o) === '[object Object]';
}

module.exports = function isPlainObject(o) {
  var ctor,prot;

  if (isObjectObject(o) === false) return false;

  // If has modified constructor
  ctor = o.constructor;
  if (typeof ctor !== 'function') return false;

  // If has modified prototype
  prot = ctor.prototype;
  if (isObjectObject(prot) === false) return false;

  // If constructor does not have an Object-specific method
  if (prot.hasOwnProperty('isPrototypeOf') === false) {
    return false;
  }

  // Most likely a plain Object
  return true;
};


is-plain-object

description: Returns true if an object was created by the `Object` constructor.

repository: jonschlinkert/is-plain-object

browserify: browserify index.js --standalone isPlainObject | uglifyjs --compress --mangle -o browser/is-plain-object.js

test_browser: mocha-phantomjs test/browser.html

test_node: mocha

test: npm run test_node && npm run browserify && npm run test_browser

keywords: check is is-object isobject javascript kind kind-of object plain type typeof value

list: is-number isobject kind-of


code:
'use strict';

var isStream = module.exports = function (stream) {
	return stream !== null && typeof stream === 'object' && typeof stream.pipe === 'function';
};

isStream.writable = function (stream) {
	return isStream(stream) && stream.writable !== false && typeof stream._write === 'function' && typeof stream._writableState === 'object';
};

isStream.readable = function (stream) {
	return isStream(stream) && stream.readable !== false && typeof stream._read === 'function' && typeof stream._readableState === 'object';
};

isStream.duplex = function (stream) {
	return isStream.writable(stream) && isStream.readable(stream);
};

isStream.transform = function (stream) {
	return isStream.duplex(stream) && typeof stream._transform === 'function' && typeof stream._transformState === 'object';
};


is-stream

description: Check if something is a Node.js stream

repository: sindresorhus/is-stream

test: xo && ava

keywords: stream type streams writable readable duplex transform check detect is


code:
# is-stream [![Build Status](https://travis-ci.org/sindresorhus/is-stream.svg?branch=master)](https://travis-ci.org/sindresorhus/is-stream)

> Check if something is a [Node.js stream](https://nodejs.org/api/stream.html)

## Install

```
$ npm install --save is-stream
```

## Usage

```js
const fs = require('fs');
const isStream = require('is-stream');

isStream(fs.createReadStream('unicorn.png'));
//=> true

isStream({});
//=> false
```

## API

### isStream(stream)

#### isStream.writable(stream)

#### isStream.readable(stream)

#### isStream.duplex(stream)

#### isStream.transform(stream)

## License

MIT © [Sindre Sorhus](https://sindresorhus.com)


code:
/**
Detect whether the terminal supports Unicode.

@example
```
import isUnicodeSupported = require('is-unicode-supported');

isUnicodeSupported();
//=> true
```
*/
declare function isUnicodeSupported(): boolean;

export = isUnicodeSupported;


code:
'use strict';

module.exports = () => {
	if (process.platform !== 'win32') {
		return true;
	}

	return Boolean(process.env.CI) ||
		Boolean(process.env.WT_SESSION) || // Windows Terminal
		process.env.TERM_PROGRAM === 'vscode' ||
		process.env.TERM === 'xterm-256color' ||
		process.env.TERM === 'alacritty';
};


is-unicode-supported

description: Detect whether the terminal supports Unicode

repository: sindresorhus/is-unicode-supported

keywords: terminal unicode detect utf8 console shell support supports supported check detection


code:
# is-unicode-supported

> Detect whether the terminal supports Unicode

This can be useful to decide whether to use Unicode characters or fallback ASCII characters in command-line output.

Note that the check is quite naive. It just assumes all non-Windows terminals support Unicode and hard-codes which Windows terminals that do support Unicode. However, I have been using this logic in some popular packages for years without problems.

## Install

```
$ npm install is-unicode-supported
```

## Usage

```js
const isUnicodeSupported = require('is-unicode-supported');

isUnicodeSupported();
//=> true
```

## API

### isUnicodeSupported()

Returns a `boolean` for whether the terminal supports Unicode.

## Related

- [is-interactive](https://github.com/sindresorhus/is-interactive) - Check if stdout or stderr is interactive
- [supports-color](https://github.com/chalk/supports-color) - Detect whether a terminal supports color
- [figures](https://github.com/sindresorhus/figures) - Unicode symbols with Windows fallbacks
- [log-symbols](https://github.com/sindresorhus/log-symbols) - Colored symbols for various log levels


code:
/**
Check if the process is running inside [Windows Subsystem for Linux](https://msdn.microsoft.com/commandline/wsl/about) (Bash on Windows).

@example
```
import isWsl = require('is-wsl');

// When running inside Windows Subsystem for Linux
console.log(isWsl);
//=> true
```
*/
declare const isWsl: boolean;

export = isWsl;


code:
'use strict';
const os = require('os');
const fs = require('fs');
const isDocker = require('is-docker');

const isWsl = () => {
	if (process.platform !== 'linux') {
		return false;
	}

	if (os.release().toLowerCase().includes('microsoft')) {
		if (isDocker()) {
			return false;
		}

		return true;
	}

	try {
		return fs.readFileSync('/proc/version', 'utf8').toLowerCase().includes('microsoft') ?
			!isDocker() : false;
	} catch (_) {
		return false;
	}
};

if (process.env.__IS_WSL_TEST__) {
	module.exports = isWsl;
} else {
	module.exports = isWsl();
}


is-wsl

description: Check if the process is running inside Windows Subsystem for Linux (Bash on Windows)

repository: sindresorhus/is-wsl

keywords: check wsl windows subsystem linux detect bash process console terminal is


code:
# is-wsl [![Build Status](https://travis-ci.org/sindresorhus/is-wsl.svg?branch=master)](https://travis-ci.org/sindresorhus/is-wsl)

> Check if the process is running inside [Windows Subsystem for Linux](https://msdn.microsoft.com/commandline/wsl/about) (Bash on Windows)

Can be useful if you need to work around unimplemented or buggy features in WSL. Supports both WSL 1 and WSL 2.

## Install

```
$ npm install is-wsl
```

## Usage

```js
const isWsl = require('is-wsl');

// When running inside Windows Subsystem for Linux
console.log(isWsl);
//=> true
```

---

		Get professional support for this package with a Tidelift subscription

		Tidelift helps make open source sustainable for maintainers while giving companies
assurances about security, maintenance, and licensing for their dependencies.


code:
language: node_js
node_js:
  - "0.8"
  - "0.10"


code:
test:
	@node_modules/.bin/tape test.js

.PHONY: test


code:
# isarray

`Array#isArray` for older browsers.

[![build status](https://secure.travis-ci.org/juliangruber/isarray.svg)](http://travis-ci.org/juliangruber/isarray)
[![downloads](https://img.shields.io/npm/dm/isarray.svg)](https://www.npmjs.org/package/isarray)

[![browser support](https://ci.testling.com/juliangruber/isarray.png)
](https://ci.testling.com/juliangruber/isarray)

## Usage

```js
var isArray = require('isarray');

console.log(isArray([])); // => true
console.log(isArray({})); // => false
```

## Installation

With [npm](http://npmjs.org) do

```bash
$ npm install isarray
```

Then bundle for the browser with
[browserify](https://github.com/substack/browserify).

With [component](http://component.io) do

```bash
$ component install juliangruber/isarray
```

## License

(MIT)

Copyright (c) 2013 Julian Gruber <julian@juliangruber.com>

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.


isarray

description: Array#isArray for older browsers

repository: juliangruber/isarray

keywords: browser isarray array


code:
var toString = {}.toString;

module.exports = Array.isArray || function (arr) {
  return toString.call(arr) == '[object Array]';
};


description: Array#isArray for older browsers

type: git

test: tape test.js


code:
var isArray = require('./');
var test = require('tape');

test('is array', function(t){
  t.ok(isArray([]));
  t.notOk(isArray({}));
  t.notOk(isArray(null));
  t.notOk(isArray(false));

  var obj = {};
  obj[0] = true;
  t.notOk(isArray(obj));

  var arr = [];
  arr.foo = 'bar';
  t.ok(isArray(arr));

  t.end();
});


code:
# isexe

Minimal module to check if a file is executable, and a normal file.

Uses `fs.stat` and tests against the `PATHEXT` environment variable on
Windows.

## USAGE

```javascript
var isexe = require('isexe')
isexe('some-file-name', function (err, isExe) {
  if (err) {
    console.error('probably file does not exist or something', err)
  } else if (isExe) {
    console.error('this thing can be run')
  } else {
    console.error('cannot be run')
  }
})

// same thing but synchronous, throws errors
var isExe = isexe.sync('some-file-name')

// treat errors as just "not executable"
isexe('maybe-missing-file', { ignoreErrors: true }, callback)
var isExe = isexe.sync('maybe-missing-file', { ignoreErrors: true })
```

## API

### `isexe(path, [options], [callback])`

Check if the path is executable.  If no callback provided, and a
global `Promise` object is available, then a Promise will be returned.

Will raise whatever errors may be raised by `fs.stat`, unless
`options.ignoreErrors` is set to true.

### `isexe.sync(path, [options])`

Same as `isexe` but returns the value and throws any errors raised.

### Options

* `ignoreErrors` Treat all errors as "no, this is not executable", but
  don't raise them.
* `uid` Number to use as the user id
* `gid` Number to use as the group id
* `pathExt` List of path extensions to use instead of `PATHEXT`
  environment variable on Windows.


code:
var fs = require('fs')
var core
if (process.platform === 'win32' || global.TESTING_WINDOWS) {
  core = require('./windows.js')
} else {
  core = require('./mode.js')
}

module.exports = isexe
isexe.sync = sync

function isexe (path, options, cb) {
  if (typeof options === 'function') {
    cb = options
    options = {}
  }

  if (!cb) {
    if (typeof Promise !== 'function') {
      throw new TypeError('callback not provided')
    }

    return new Promise(function (resolve, reject) {
      isexe(path, options || {}, function (er, is) {
        if (er) {
          reject(er)
        } else {
          resolve(is)
        }
      })
    })
  }

  core(path, options || {}, function (er, is) {
    // ignore EACCES because that just means we aren't allowed to run it
    if (er) {
      if (er.code === 'EACCES' || options && options.ignoreErrors) {
        er = null
        is = false
      }
    }
    cb(er, is)
  })
}

function sync (path, options) {
  // my kingdom for a filtered catch
  try {
    return core.sync(path, options || {})
  } catch (er) {
    if (options && options.ignoreErrors || er.code === 'EACCES') {
      return false
    } else {
      throw er
    }
  }
}


code:
module.exports = isexe
isexe.sync = sync

var fs = require('fs')

function isexe (path, options, cb) {
  fs.stat(path, function (er, stat) {
    cb(er, er ? false : checkStat(stat, options))
  })
}

function sync (path, options) {
  return checkStat(fs.statSync(path), options)
}

function checkStat (stat, options) {
  return stat.isFile() && checkMode(stat, options)
}

function checkMode (stat, options) {
  var mod = stat.mode
  var uid = stat.uid
  var gid = stat.gid

  var myUid = options.uid !== undefined ?
    options.uid : process.getuid && process.getuid()
  var myGid = options.gid !== undefined ?
    options.gid : process.getgid && process.getgid()

  var u = parseInt('100', 8)
  var g = parseInt('010', 8)
  var o = parseInt('001', 8)
  var ug = u | g

  var ret = (mod & o) ||
    (mod & g) && gid === myGid ||
    (mod & u) && uid === myUid ||
    (mod & ug) && myUid === 0

  return ret
}


isexe

description: Minimal module to check if a file is executable.

test: test

test: tap test/*.js --100

preversion: npm test

postversion: npm publish

postpublish: git push origin --all; git push origin --tags

author: Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me/)

license: ISC


code:
var t = require('tap')
var fs = require('fs')
var path = require('path')
var fixture = path.resolve(__dirname, 'fixtures')
var meow = fixture + '/meow.cat'
var mine = fixture + '/mine.cat'
var ours = fixture + '/ours.cat'
var fail = fixture + '/fail.false'
var noent = fixture + '/enoent.exe'
var mkdirp = require('mkdirp')
var rimraf = require('rimraf')

var isWindows = process.platform === 'win32'
var hasAccess = typeof fs.access === 'function'
var winSkip = isWindows && 'windows'
var accessSkip = !hasAccess && 'no fs.access function'
var hasPromise = typeof Promise === 'function'
var promiseSkip = !hasPromise && 'no global Promise'

function reset () {
  delete require.cache[require.resolve('../')]
  return require('../')
}

t.test('setup fixtures', function (t) {
  rimraf.sync(fixture)
  mkdirp.sync(fixture)
  fs.writeFileSync(meow, '#!/usr/bin/env cat\nmeow\n')
  fs.chmodSync(meow, parseInt('0755', 8))
  fs.writeFileSync(fail, '#!/usr/bin/env false\n')
  fs.chmodSync(fail, parseInt('0644', 8))
  fs.writeFileSync(mine, '#!/usr/bin/env cat\nmine\n')
  fs.chmodSync(mine, parseInt('0744', 8))
  fs.writeFileSync(ours, '#!/usr/bin/env cat\nours\n')
  fs.chmodSync(ours, parseInt('0754', 8))
  t.end()
})

t.test('promise', { skip: promiseSkip }, function (t) {
  var isexe = reset()
  t.test('meow async', function (t) {
    isexe(meow).then(function (is) {
      t.ok(is)
      t.end()
    })
  })
  t.test('fail async', function (t) {
    isexe(fail).then(function (is) {
      t.notOk(is)
      t.end()
    })
  })
  t.test('noent async', function (t) {
    isexe(noent).catch(function (er) {
      t.ok(er)
      t.end()
    })
  })
  t.test('noent ignore async', function (t) {
    isexe(noent, { ignoreErrors: true }).then(function (is) {
      t.notOk(is)
      t.end()
    })
  })
  t.end()
})

t.test('no promise', function (t) {
  global.Promise = null
  var isexe = reset()
  t.throws('try to meow a promise', function () {
    isexe(meow)
  })
  t.end()
})

t.test('access', { skip: accessSkip || winSkip }, function (t) {
  runTest(t)
})

t.test('mode', { skip: winSkip }, function (t) {
  delete fs.access
  delete fs.accessSync
  var isexe = reset()
  t.ok(isexe.sync(ours, { uid: 0, gid: 0 }))
  t.ok(isexe.sync(mine, { uid: 0, gid: 0 }))
  runTest(t)
})

t.test('windows', function (t) {
  global.TESTING_WINDOWS = true
  var pathExt = '.EXE;.CAT;.CMD;.COM'
  t.test('pathExt option', function (t) {
    runTest(t, { pathExt: '.EXE;.CAT;.CMD;.COM' })
  })
  t.test('pathExt env', function (t) {
    process.env.PATHEXT = pathExt
    runTest(t)
  })
  t.test('no pathExt', function (t) {
    // with a pathExt of '', any filename is fine.
    // so the "fail" one would still pass.
    runTest(t, { pathExt: '', skipFail: true })
  })
  t.test('pathext with empty entry', function (t) {
    // with a pathExt of '', any filename is fine.
    // so the "fail" one would still pass.
    runTest(t, { pathExt: ';' + pathExt, skipFail: true })
  })
  t.end()
})

t.test('cleanup', function (t) {
  rimraf.sync(fixture)
  t.end()
})

function runTest (t, options) {
  var isexe = reset()

  var optionsIgnore = Object.create(options || {})
  optionsIgnore.ignoreErrors = true

  if (!options || !options.skipFail) {
    t.notOk(isexe.sync(fail, options))
  }
  t.notOk(isexe.sync(noent, optionsIgnore))
  if (!options) {
    t.ok(isexe.sync(meow))
  } else {
    t.ok(isexe.sync(meow, options))
  }

  t.ok(isexe.sync(mine, options))
  t.ok(isexe.sync(ours, options))
  t.throws(function () {
    isexe.sync(noent, options)
  })

  t.test('meow async', function (t) {
    if (!options) {
      isexe(meow, function (er, is) {
        if (er) {
          throw er
        }
        t.ok(is)
        t.end()
      })
    } else {
      isexe(meow, options, function (er, is) {
        if (er) {
          throw er
        }
        t.ok(is)
        t.end()
      })
    }
  })

  t.test('mine async', function (t) {
    isexe(mine, options, function (er, is) {
      if (er) {
        throw er
      }
      t.ok(is)
      t.end()
    })
  })

  t.test('ours async', function (t) {
    isexe(ours, options, function (er, is) {
      if (er) {
        throw er
      }
      t.ok(is)
      t.end()
    })
  })

  if (!options || !options.skipFail) {
    t.test('fail async', function (t) {
      isexe(fail, options, function (er, is) {
        if (er) {
          throw er
        }
        t.notOk(is)
        t.end()
      })
    })
  }

  t.test('noent async', function (t) {
    isexe(noent, options, function (er, is) {
      t.ok(er)
      t.notOk(is)
      t.end()
    })
  })

  t.test('noent ignore async', function (t) {
    isexe(noent, optionsIgnore, function (er, is) {
      if (er) {
        throw er
      }
      t.notOk(is)
      t.end()
    })
  })

  t.test('directory is not executable', function (t) {
    isexe(__dirname, options, function (er, is) {
      if (er) {
        throw er
      }
      t.notOk(is)
      t.end()
    })
  })

  t.end()
}


code:
module.exports = isexe
isexe.sync = sync

var fs = require('fs')

function checkPathExt (path, options) {
  var pathext = options.pathExt !== undefined ?
    options.pathExt : process.env.PATHEXT

  if (!pathext) {
    return true
  }

  pathext = pathext.split(';')
  if (pathext.indexOf('') !== -1) {
    return true
  }
  for (var i = 0; i < pathext.length; i++) {
    var p = pathext[i].toLowerCase()
    if (p && path.substr(-p.length).toLowerCase() === p) {
      return true
    }
  }
  return false
}

function checkStat (stat, path, options) {
  if (!stat.isSymbolicLink() && !stat.isFile()) {
    return false
  }
  return checkPathExt(path, options)
}

function isexe (path, options, cb) {
  fs.stat(path, function (er, stat) {
    cb(er, er ? false : checkStat(stat, path, options))
  })
}

function sync (path, options) {
  return checkStat(fs.statSync(path), path, options)
}


code:
# isobject [![NPM version](https://img.shields.io/npm/v/isobject.svg?style=flat)](https://www.npmjs.com/package/isobject) [![NPM monthly downloads](https://img.shields.io/npm/dm/isobject.svg?style=flat)](https://npmjs.org/package/isobject)  [![NPM total downloads](https://img.shields.io/npm/dt/isobject.svg?style=flat)](https://npmjs.org/package/isobject) [![Linux Build Status](https://img.shields.io/travis/jonschlinkert/isobject.svg?style=flat&label=Travis)](https://travis-ci.org/jonschlinkert/isobject)

> Returns true if the value is an object and not an array or null.

## Install

Install with [npm](https://www.npmjs.com/):

```sh
$ npm install --save isobject
```

Install with [yarn](https://yarnpkg.com):

```sh
$ yarn add isobject
```

Use [is-plain-object](https://github.com/jonschlinkert/is-plain-object) if you want only objects that are created by the `Object` constructor.

## Install

Install with [npm](https://www.npmjs.com/):

```sh
$ npm install isobject
```
Install with [bower](https://bower.io/)

```sh
$ bower install isobject
```

## Usage

```js
var isObject = require('isobject');
```

**True**

All of the following return `true`:

```js
isObject({});
isObject(Object.create({}));
isObject(Object.create(Object.prototype));
isObject(Object.create(null));
isObject({});
isObject(new Foo);
isObject(/foo/);
```

**False**

All of the following return `false`:

```js
isObject();
isObject(function () {});
isObject(1);
isObject([]);
isObject(undefined);
isObject(null);
```

## About

### Related projects

* [extend-shallow](https://www.npmjs.com/package/extend-shallow): Extend an object with the properties of additional objects. node.js/javascript util. | [homepage](https://github.com/jonschlinkert/extend-shallow "Extend an object with the properties of additional objects. node.js/javascript util.")
* [is-plain-object](https://www.npmjs.com/package/is-plain-object): Returns true if an object was created by the `Object` constructor. | [homepage](https://github.com/jonschlinkert/is-plain-object "Returns true if an object was created by the `Object` constructor.")
* [kind-of](https://www.npmjs.com/package/kind-of): Get the native type of a value. | [homepage](https://github.com/jonschlinkert/kind-of "Get the native type of a value.")
* [merge-deep](https://www.npmjs.com/package/merge-deep): Recursively merge values in a javascript object. | [homepage](https://github.com/jonschlinkert/merge-deep "Recursively merge values in a javascript object.")

### Contributing

Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](../../issues/new).

### Contributors

| **Commits** | **Contributor** |
| --- | --- |
| 29 | [jonschlinkert](https://github.com/jonschlinkert) |
| 4  | [doowb](https://github.com/doowb) |
| 1  | [magnudae](https://github.com/magnudae) |
| 1  | [LeSuisse](https://github.com/LeSuisse) |
| 1  | [tmcw](https://github.com/tmcw) |

### Building docs

_(This project's readme.md is generated by [verb](https://github.com/verbose/verb-generate-readme), please don't edit the readme directly. Any changes to the readme must be made in the [.verb.md](.verb.md) readme template.)_

To generate the readme, run the following command:

```sh
$ npm install -g verbose/verb#dev verb-generate-readme && verb
```

### Running tests

Running and reviewing unit tests is a great way to get familiarized with a library and its API. You can install dependencies and run tests with the following command:

```sh
$ npm install && npm test
```

### Author

**Jon Schlinkert**

* [github/jonschlinkert](https://github.com/jonschlinkert)
* [twitter/jonschlinkert](https://twitter.com/jonschlinkert)

### License

Copyright © 2017, [Jon Schlinkert](https://github.com/jonschlinkert).
Released under the [MIT License](LICENSE).

***

_This file was generated by [verb-generate-readme](https://github.com/verbose/verb-generate-readme), v0.6.0, on June 30, 2017._


code:
export = isObject;

declare function isObject(val: any): boolean;

declare namespace isObject {}


code:
/*!
 * isobject <https://github.com/jonschlinkert/isobject>
 *
 * Copyright (c) 2014-2017, Jon Schlinkert.
 * Released under the MIT License.
 */

'use strict';

module.exports = function isObject(val) {
  return val != null && typeof val === 'object' && Array.isArray(val) === false;
};


isobject

description: Returns true if the value is an object and not an array or null.

repository: jonschlinkert/isobject

keywords: check is is-object isobject kind kind-of kindof native object type typeof value

list: extend-shallow is-plain-object kind-of merge-deep


code:
# JavaScript Stringify

[![NPM version][npm-image]][npm-url]
[![NPM downloads][downloads-image]][downloads-url]
[![Build status][build-image]][build-url]
[![Build coverage][coverage-image]][coverage-url]

> Stringify is to `eval` as `JSON.stringify` is to `JSON.parse`.

## Installation

```
npm install javascript-stringify --save
```

## Usage

```javascript
import { stringify } from "javascript-stringify";
```

The API is similar `JSON.stringify`:

- `value` The value to convert to a string
- `replacer` A function that alters the behavior of the stringification process
- `space` A string or number that's used to insert white space into the output for readability purposes
- `options`
  - **maxDepth** _(number, default: 100)_ The maximum depth of values to stringify
  - **maxValues** _(number, default: 100000)_ The maximum number of values to stringify
  - **references** _(boolean, default: false)_ Restore circular/repeated references in the object (uses IIFE)
  - **skipUndefinedProperties** _(boolean, default: false)_ Omits `undefined` properties instead of restoring as `undefined`

### Examples

```javascript
stringify({}); // "{}"
stringify(true); // "true"
stringify("foo"); // "'foo'"

stringify({ x: 5, y: 6 }); // "{x:5,y:6}"
stringify([1, 2, 3, "string"]); // "[1,2,3,'string']"

stringify({ a: { b: { c: 1 } } }, null, null, { maxDepth: 2 }); // "{a:{b:{}}}"

/**
 * Invalid key names are automatically stringified.
 */
stringify({ "some-key": 10 }); // "{'some-key':10}"

/**
 * Some object types and values can remain identical.
 */
stringify([/.+/gi, new Number(10), new Date()]); // "[/.+/gi,new Number(10),new Date(1406623295732)]"

/**
 * Unknown or circular references are removed.
 */
var obj = { x: 10 };
obj.circular = obj;

stringify(obj); // "{x:10}"
stringify(obj, null, null, { references: true }); // "(function(){var x={x:10};x.circular=x;return x;}())"

/**
 * Specify indentation - just like `JSON.stringify`.
 */
stringify({ a: 2 }, null, " "); // "{\n a: 2\n}"
stringify({ uno: 1, dos: 2 }, null, "\t"); // "{\n\tuno: 1,\n\tdos: 2\n}"

/**
 * Add custom replacer behaviour - like double quoted strings.
 */
stringify(["test", "string"], function (value, indent, stringify) {
  if (typeof value === "string") {
    return '"' + value.replace(/"/g, '\\"') + '"';
  }

  return stringify(value);
});
//=> '["test","string"]'
```

## Formatting

You can use your own code formatter on the result of `javascript-stringify`. Here is an example using [eslint](https://www.npmjs.com/package/eslint):

```javascript
const { CLIEngine } = require("eslint");
const { stringify } = require("javascript-stringify");

const { APP_ROOT_PATH, ESLINTRC_FILE_PATH } = require("./constants");

const ESLINT_CLI = new CLIEngine({
  fix: true,
  cwd: APP_ROOT_PATH,
  configFile: ESLINTRC_FILE_PATH,
});

module.exports = (objectToStringify) => {
  return ESLINT_CLI.executeOnText(stringify(objectToStringify)).results[0]
    .output;
};
```

## License

MIT

[npm-image]: https://img.shields.io/npm/v/javascript-stringify
[npm-url]: https://npmjs.org/package/javascript-stringify
[downloads-image]: https://img.shields.io/npm/dm/javascript-stringify
[downloads-url]: https://npmjs.org/package/javascript-stringify
[build-image]: https://img.shields.io/github/workflow/status/blakeembrey/javascript-stringify/CI/main
[build-url]: https://github.com/blakeembrey/javascript-stringify/actions/workflows/ci.yml?query=branch%3Amain
[coverage-image]: https://img.shields.io/codecov/c/gh/blakeembrey/javascript-stringify
[coverage-url]: https://codecov.io/gh/blakeembrey/javascript-stringify


code:
import { ToString } from "./types";
/**
 * Stringify an array of values.
 */
export declare const arrayToString: ToString;


code:
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.arrayToString = void 0;
/**
 * Stringify an array of values.
 */
const arrayToString = (array, space, next) => {
    // Map array values to their stringified values with correct indentation.
    const values = array
        .map(function (value, index) {
        const result = next(value, index);
        if (result === undefined)
            return String(result);
        return space + result.split("\n").join(`\n${space}`);
    })
        .join(space ? ",\n" : ",");
    const eol = space && values ? "\n" : "";
    return `[${eol}${values}${eol}]`;
};
exports.arrayToString = arrayToString;
//# sourceMappingURL=array.js.map


code:
import { Next, ToString } from "./types";
declare const FUNCTION_PREFIXES: {
    Function: string;
    GeneratorFunction: string;
    AsyncFunction: string;
    AsyncGeneratorFunction: string;
};
/**
 * Track function parser usage.
 */
export declare const USED_METHOD_KEY: WeakSet<(...args: unknown[]) => unknown>;
/**
 * Stringify a function.
 */
export declare const functionToString: ToString;
/**
 * Rewrite a stringified function to remove initial indentation.
 */
export declare function dedentFunction(fnString: string): string;
/**
 * Function parser and stringify.
 */
export declare class FunctionParser {
    fn: (...args: unknown[]) => unknown;
    indent: string;
    next: Next;
    key?: string | undefined;
    fnString: string;
    fnType: keyof typeof FUNCTION_PREFIXES;
    keyQuote: string | undefined;
    keyPrefix: string;
    isMethodCandidate: boolean;
    pos: number;
    hadKeyword: boolean;
    constructor(fn: (...args: unknown[]) => unknown, indent: string, next: Next, key?: string | undefined);
    stringify(): string;
    getPrefix(): string;
    tryParse(): string | undefined;
    /**
     * Attempt to parse the function from the current position by first stripping
     * the function's name from the front. This is not a fool-proof method on all
     * JavaScript engines, but yields good results on Node.js 4 (and slightly
     * less good results on Node.js 6 and 8).
     */
    tryStrippingName(): string | undefined;
    /**
     * Attempt to advance the parser past the keywords expected to be at the
     * start of this function's definition. This method sets `this.hadKeyword`
     * based on whether or not a `function` keyword is consumed.
     */
    tryParsePrefixTokens(): boolean;
    /**
     * Advance the parser past one element of JavaScript syntax. This could be a
     * matched pair of delimiters, like braces or parentheses, or an atomic unit
     * like a keyword, variable, or operator. Return a normalized string
     * representation of the element parsed--for example, returns '{}' for a
     * matched pair of braces. Comments and whitespace are skipped.
     *
     * (This isn't a full parser, so the token scanning logic used here is as
     * simple as it can be. As a consequence, some things that are one token in
     * JavaScript, like decimal number literals or most multi-character operators
     * like '&&', are split into more than one token here. However, awareness of
     * some multi-character sequences like '=>' is necessary, so we match the few
     * of them that we care about.)
     */
    consumeSyntax(wordLikeToken?: string): string | undefined;
    consumeSyntaxUntil(startToken: string, endToken: string): string | undefined;
    consumeMatch(re: RegExp): RegExpExecArray | null;
    /**
     * Advance the parser past an arbitrary regular expression. Return `token`,
     * or the match object of the regexp.
     */
    consumeRegExp(re: RegExp, token: string): string | undefined;
    /**
     * Advance the parser past a template string.
     */
    consumeTemplate(): "`" | undefined;
    /**
     * Advance the parser past any whitespace or comments.
     */
    consumeWhitespace(): void;
}
export {};


code:
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.FunctionParser = exports.dedentFunction = exports.functionToString = exports.USED_METHOD_KEY = void 0;
const quote_1 = require("./quote");
/**
 * Used in function stringification.
 */
/* istanbul ignore next */
const METHOD_NAMES_ARE_QUOTED = {
    " "() {
        /* Empty. */
    },
}[" "]
    .toString()
    .charAt(0) === '"';
const FUNCTION_PREFIXES = {
    Function: "function ",
    GeneratorFunction: "function* ",
    AsyncFunction: "async function ",
    AsyncGeneratorFunction: "async function* ",
};
const METHOD_PREFIXES = {
    Function: "",
    GeneratorFunction: "*",
    AsyncFunction: "async ",
    AsyncGeneratorFunction: "async *",
};
const TOKENS_PRECEDING_REGEXPS = new Set(("case delete else in instanceof new return throw typeof void " +
    ", ; : + - ! ~ & | ^ * / % < > ? =").split(" "));
/**
 * Track function parser usage.
 */
exports.USED_METHOD_KEY = new WeakSet();
/**
 * Stringify a function.
 */
const functionToString = (fn, space, next, key) => {
    const name = typeof key === "string" ? key : undefined;
    // Track in function parser for object stringify to avoid duplicate output.
    if (name !== undefined)
        exports.USED_METHOD_KEY.add(fn);
    return new FunctionParser(fn, space, next, name).stringify();
};
exports.functionToString = functionToString;
/**
 * Rewrite a stringified function to remove initial indentation.
 */
function dedentFunction(fnString) {
    let found;
    for (const line of fnString.split("\n").slice(1)) {
        const m = /^[\s\t]+/.exec(line);
        if (!m)
            return fnString; // Early exit without indent.
        const [str] = m;
        if (found === undefined)
            found = str;
        else if (str.length < found.length)
            found = str;
    }
    return found ? fnString.split(`\n${found}`).join("\n") : fnString;
}
exports.dedentFunction = dedentFunction;
/**
 * Function parser and stringify.
 */
class FunctionParser {
    constructor(fn, indent, next, key) {
        this.fn = fn;
        this.indent = indent;
        this.next = next;
        this.key = key;
        this.pos = 0;
        this.hadKeyword = false;
        this.fnString = Function.prototype.toString.call(fn);
        this.fnType = fn.constructor.name;
        this.keyQuote = key === undefined ? "" : quote_1.quoteKey(key, next);
        this.keyPrefix =
            key === undefined ? "" : `${this.keyQuote}:${indent ? " " : ""}`;
        this.isMethodCandidate =
            key === undefined ? false : this.fn.name === "" || this.fn.name === key;
    }
    stringify() {
        const value = this.tryParse();
        // If we can't stringify this function, return a void expression; for
        // bonus help with debugging, include the function as a string literal.
        if (!value) {
            return `${this.keyPrefix}void ${this.next(this.fnString)}`;
        }
        return dedentFunction(value);
    }
    getPrefix() {
        if (this.isMethodCandidate && !this.hadKeyword) {
            return METHOD_PREFIXES[this.fnType] + this.keyQuote;
        }
        return this.keyPrefix + FUNCTION_PREFIXES[this.fnType];
    }
    tryParse() {
        if (this.fnString[this.fnString.length - 1] !== "}") {
            // Must be an arrow function.
            return this.keyPrefix + this.fnString;
        }
        // Attempt to remove function prefix.
        if (this.fn.name) {
            const result = this.tryStrippingName();
            if (result)
                return result;
        }
        // Support class expressions.
        const prevPos = this.pos;
        if (this.consumeSyntax() === "class")
            return this.fnString;
        this.pos = prevPos;
        if (this.tryParsePrefixTokens()) {
            const result = this.tryStrippingName();
            if (result)
                return result;
            let offset = this.pos;
            switch (this.consumeSyntax("WORD_LIKE")) {
                case "WORD_LIKE":
                    if (this.isMethodCandidate && !this.hadKeyword) {
                        offset = this.pos;
                    }
                case "()":
                    if (this.fnString.substr(this.pos, 2) === "=>") {
                        return this.keyPrefix + this.fnString;
                    }
                    this.pos = offset;
                case '"':
                case "'":
                case "[]":
                    return this.getPrefix() + this.fnString.substr(this.pos);
            }
        }
    }
    /**
     * Attempt to parse the function from the current position by first stripping
     * the function's name from the front. This is not a fool-proof method on all
     * JavaScript engines, but yields good results on Node.js 4 (and slightly
     * less good results on Node.js 6 and 8).
     */
    tryStrippingName() {
        if (METHOD_NAMES_ARE_QUOTED) {
            // ... then this approach is unnecessary and yields false positives.
            return;
        }
        let start = this.pos;
        const prefix = this.fnString.substr(this.pos, this.fn.name.length);
        if (prefix === this.fn.name) {
            this.pos += prefix.length;
            if (this.consumeSyntax() === "()" &&
                this.consumeSyntax() === "{}" &&
                this.pos === this.fnString.length) {
                // Don't include the function's name if it will be included in the
                // prefix, or if it's invalid as a name in a function expression.
                if (this.isMethodCandidate || !quote_1.isValidVariableName(prefix)) {
                    start += prefix.length;
                }
                return this.getPrefix() + this.fnString.substr(start);
            }
        }
        this.pos = start;
    }
    /**
     * Attempt to advance the parser past the keywords expected to be at the
     * start of this function's definition. This method sets `this.hadKeyword`
     * based on whether or not a `function` keyword is consumed.
     */
    tryParsePrefixTokens() {
        let posPrev = this.pos;
        this.hadKeyword = false;
        switch (this.fnType) {
            case "AsyncFunction":
                if (this.consumeSyntax() !== "async")
                    return false;
                posPrev = this.pos;
            case "Function":
                if (this.consumeSyntax() === "function") {
                    this.hadKeyword = true;
                }
                else {
                    this.pos = posPrev;
                }
                return true;
            case "AsyncGeneratorFunction":
                if (this.consumeSyntax() !== "async")
                    return false;
            case "GeneratorFunction":
                let token = this.consumeSyntax();
                if (token === "function") {
                    token = this.consumeSyntax();
                    this.hadKeyword = true;
                }
                return token === "*";
        }
    }
    /**
     * Advance the parser past one element of JavaScript syntax. This could be a
     * matched pair of delimiters, like braces or parentheses, or an atomic unit
     * like a keyword, variable, or operator. Return a normalized string
     * representation of the element parsed--for example, returns '{}' for a
     * matched pair of braces. Comments and whitespace are skipped.
     *
     * (This isn't a full parser, so the token scanning logic used here is as
     * simple as it can be. As a consequence, some things that are one token in
     * JavaScript, like decimal number literals or most multi-character operators
     * like '&&', are split into more than one token here. However, awareness of
     * some multi-character sequences like '=>' is necessary, so we match the few
     * of them that we care about.)
     */
    consumeSyntax(wordLikeToken) {
        const m = this.consumeMatch(/^(?:([A-Za-z_0-9$\xA0-\uFFFF]+)|=>|\+\+|\-\-|.)/);
        if (!m)
            return;
        const [token, match] = m;
        this.consumeWhitespace();
        if (match)
            return wordLikeToken || match;
        switch (token) {
            case "(":
                return this.consumeSyntaxUntil("(", ")");
            case "[":
                return this.consumeSyntaxUntil("[", "]");
            case "{":
                return this.consumeSyntaxUntil("{", "}");
            case "`":
                return this.consumeTemplate();
            case '"':
                return this.consumeRegExp(/^(?:[^\\"]|\\.)*"/, '"');
            case "'":
                return this.consumeRegExp(/^(?:[^\\']|\\.)*'/, "'");
        }
        return token;
    }
    consumeSyntaxUntil(startToken, endToken) {
        let isRegExpAllowed = true;
        for (;;) {
            const token = this.consumeSyntax();
            if (token === endToken)
                return startToken + endToken;
            if (!token || token === ")" || token === "]" || token === "}")
                return;
            if (token === "/" &&
                isRegExpAllowed &&
                this.consumeMatch(/^(?:\\.|[^\\\/\n[]|\[(?:\\.|[^\]])*\])+\/[a-z]*/)) {
                isRegExpAllowed = false;
                this.consumeWhitespace();
            }
            else {
                isRegExpAllowed = TOKENS_PRECEDING_REGEXPS.has(token);
            }
        }
    }
    consumeMatch(re) {
        const m = re.exec(this.fnString.substr(this.pos));
        if (m)
            this.pos += m[0].length;
        return m;
    }
    /**
     * Advance the parser past an arbitrary regular expression. Return `token`,
     * or the match object of the regexp.
     */
    consumeRegExp(re, token) {
        const m = re.exec(this.fnString.substr(this.pos));
        if (!m)
            return;
        this.pos += m[0].length;
        this.consumeWhitespace();
        return token;
    }
    /**
     * Advance the parser past a template string.
     */
    consumeTemplate() {
        for (;;) {
            this.consumeMatch(/^(?:[^`$\\]|\\.|\$(?!{))*/);
            if (this.fnString[this.pos] === "`") {
                this.pos++;
                this.consumeWhitespace();
                return "`";
            }
            if (this.fnString.substr(this.pos, 2) === "${") {
                this.pos += 2;
                this.consumeWhitespace();
                if (this.consumeSyntaxUntil("{", "}"))
                    continue;
            }
            return;
        }
    }
    /**
     * Advance the parser past any whitespace or comments.
     */
    consumeWhitespace() {
        this.consumeMatch(/^(?:\s|\/\/.*|\/\*[^]*?\*\/)*/);
    }
}
exports.FunctionParser = FunctionParser;
//# sourceMappingURL=function.js.map


code:
import { ToString } from "./types";
export interface Options {
    maxDepth?: number;
    maxValues?: number;
    references?: boolean;
    skipUndefinedProperties?: boolean;
}
/**
 * Stringify any JavaScript value.
 */
export declare function stringify(value: any, replacer?: ToString | null, indent?: string | number | null, options?: Options): string | undefined;


code:
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.stringify = void 0;
const stringify_1 = require("./stringify");
const quote_1 = require("./quote");
/**
 * Root path node.
 */
const ROOT_SENTINEL = Symbol("root");
/**
 * Stringify any JavaScript value.
 */
function stringify(value, replacer, indent, options = {}) {
    const space = typeof indent === "string" ? indent : " ".repeat(indent || 0);
    const path = [];
    const stack = new Set();
    const tracking = new Map();
    const unpack = new Map();
    let valueCount = 0;
    const { maxDepth = 100, references = false, skipUndefinedProperties = false, maxValues = 100000, } = options;
    // Wrap replacer function to support falling back on supported stringify.
    const valueToString = replacerToString(replacer);
    // Every time you call `next(value)` execute this function.
    const onNext = (value, key) => {
        if (++valueCount > maxValues)
            return;
        if (skipUndefinedProperties && value === undefined)
            return;
        if (path.length > maxDepth)
            return;
        // An undefined key is treated as an out-of-band "value".
        if (key === undefined)
            return valueToString(value, space, onNext, key);
        path.push(key);
        const result = builder(value, key === ROOT_SENTINEL ? undefined : key);
        path.pop();
        return result;
    };
    const builder = references
        ? (value, key) => {
            if (value !== null &&
                (typeof value === "object" ||
                    typeof value === "function" ||
                    typeof value === "symbol")) {
                // Track nodes to restore later.
                if (tracking.has(value)) {
                    unpack.set(path.slice(1), tracking.get(value));
                    // Use `undefined` as temporaray stand-in for referenced nodes
                    return valueToString(undefined, space, onNext, key);
                }
                // Track encountered nodes.
                tracking.set(value, path.slice(1));
            }
            return valueToString(value, space, onNext, key);
        }
        : (value, key) => {
            // Stop on recursion.
            if (stack.has(value))
                return;
            stack.add(value);
            const result = valueToString(value, space, onNext, key);
            stack.delete(value);
            return result;
        };
    const result = onNext(value, ROOT_SENTINEL);
    // Attempt to restore circular references.
    if (unpack.size) {
        const sp = space ? " " : "";
        const eol = space ? "\n" : "";
        let wrapper = `var x${sp}=${sp}${result};${eol}`;
        for (const [key, value] of unpack.entries()) {
            const keyPath = quote_1.stringifyPath(key, onNext);
            const valuePath = quote_1.stringifyPath(value, onNext);
            wrapper += `x${keyPath}${sp}=${sp}x${valuePath};${eol}`;
        }
        return `(function${sp}()${sp}{${eol}${wrapper}return x;${eol}}())`;
    }
    return result;
}
exports.stringify = stringify;
/**
 * Create `toString()` function from replacer.
 */
function replacerToString(replacer) {
    if (!replacer)
        return stringify_1.toString;
    return (value, space, next, key) => {
        return replacer(value, space, (value) => stringify_1.toString(value, space, next, key), key);
    };
}
//# sourceMappingURL=index.js.map