code:
# camelcase

> Convert a dash/dot/underscore/space separated string to camelCase or PascalCase: `foo-bar` → `fooBar`

Correctly handles Unicode strings.

If you use this on untrusted user input, don't forget to limit the length to something reasonable.

## Install

```
$ npm install camelcase
```

*If you need to support Firefox < 78, stay on version 5 as version 6 uses regex features not available in Firefox < 78.*

## Usage

```js
const camelCase = require('camelcase');

camelCase('foo-bar');
//=> 'fooBar'

camelCase('foo_bar');
//=> 'fooBar'

camelCase('Foo-Bar');
//=> 'fooBar'

camelCase('розовый_пушистый_единорог');
//=> 'розовыйПушистыйЕдинорог'

camelCase('Foo-Bar', {pascalCase: true});
//=> 'FooBar'

camelCase('--foo.bar', {pascalCase: false});
//=> 'fooBar'

camelCase('Foo-BAR', {preserveConsecutiveUppercase: true});
//=> 'fooBAR'

camelCase('fooBAR', {pascalCase: true, preserveConsecutiveUppercase: true}));
//=> 'FooBAR'

camelCase('foo bar');
//=> 'fooBar'

console.log(process.argv[3]);
//=> '--foo-bar'
camelCase(process.argv[3]);
//=> 'fooBar'

camelCase(['foo', 'bar']);
//=> 'fooBar'

camelCase(['__foo__', '--bar'], {pascalCase: true});
//=> 'FooBar'

camelCase(['foo', 'BAR'], {pascalCase: true, preserveConsecutiveUppercase: true})
//=> 'FooBAR'

camelCase('lorem-ipsum', {locale: 'en-US'});
//=> 'loremIpsum'
```

## API

### camelCase(input, options?)

#### input

Type: `string | string[]`

String to convert to camel case.

#### options

Type: `object`

##### pascalCase

Type: `boolean`\
Default: `false`

Uppercase the first character: `foo-bar` → `FooBar`

##### preserveConsecutiveUppercase

Type: `boolean`\
Default: `false`

Preserve the consecutive uppercase characters: `foo-BAR` → `FooBAR`.

##### locale

Type: `false | string | string[]`\
Default: The host environment’s current locale.

The locale parameter indicates the locale to be used to convert to upper/lower case according to any locale-specific case mappings. If multiple locales are given in an array, the best available locale is used.

```js
const camelCase = require('camelcase');

camelCase('lorem-ipsum', {locale: 'en-US'});
//=> 'loremIpsum'

camelCase('lorem-ipsum', {locale: 'tr-TR'});
//=> 'loremİpsum'

camelCase('lorem-ipsum', {locale: ['en-US', 'en-GB']});
//=> 'loremIpsum'

camelCase('lorem-ipsum', {locale: ['tr', 'TR', 'tr-TR']});
//=> 'loremİpsum'
```

Setting `locale: false` ignores the platform locale and uses the [Unicode Default Case Conversion](https://unicode-org.github.io/icu/userguide/transforms/casemappings.html#simple-single-character-case-mapping) algorithm:

```js
const camelCase = require('camelcase');

// On a platform with 'tr-TR'

camelCase('lorem-ipsum');
//=> 'loremİpsum'

camelCase('lorem-ipsum', {locale: false});
//=> 'loremIpsum'
```

## camelcase for enterprise

Available as part of the Tidelift Subscription.

The maintainers of camelcase and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source dependencies you use to build your applications. Save time, reduce risk, and improve code health, while paying the maintainers of the exact dependencies you use. [Learn more.](https://tidelift.com/subscription/pkg/npm-camelcase?utm_source=npm-camelcase&utm_medium=referral&utm_campaign=enterprise&utm_term=repo)

## Related

- [decamelize](https://github.com/sindresorhus/decamelize) - The inverse of this module
- [uppercamelcase](https://github.com/SamVerschueren/uppercamelcase) - Like this module, but to PascalCase instead of camelCase
- [titleize](https://github.com/sindresorhus/titleize) - Capitalize every word in string
- [humanize-string](https://github.com/sindresorhus/humanize-string) - Convert a camelized/dasherized/underscored string into a humanized one
- [camelcase-keys](https://github.com/sindresorhus/camelcase-keys) - Convert object keys to camel case


code:
# 3.0.0 - 2018-07-10

- Upgraded: browserslist

# 2.1.0 - 2018-06-06 (never released to npm)

- Upgraded: browserslist, caniuse-lite

# 2.0.0 - 2017-05-03

- Changed: we now use caniuse-lite instead if caniuse-db
  ([#59](https://github.com/Nyalab/caniuse-api/pull/59))

# 1.6.1 - 2017-04-07

- Added: export the feature list
  ([#48](https://github.com/Nyalab/caniuse-api/pull/48))

# 1.5.3 - 2017-02-01

- Removed unused dependency
  ([#54](https://github.com/Nyalab/caniuse-api/pull/54) - @wtgtybhertgeghgtwtg)

# 1.5.2 - 2016-09-05

- Fixed: no more generation `postinstall` hook ``\o/``.
  ([#47](https://github.com/Nyalab/caniuse-api/pull/47) - @alexisvincent)

# 1.5.1 - 2016-08-06

- Fixed: Do not fail when browserslist gives a browser that caniuse-api doesn't
  know about
  ([#45](https://github.com/Nyalab/caniuse-api/pull/45) - @onigoetz)

# 1.5.0 - 2016-06-01

- Added: JSPM support with explicit file extensions ([#40](https://github.com/Nyalab/caniuse-api/issues/40))
- Upgraded: dependecies (lodash.memoize, lodash.uniq, shelljs, babel-tape-runner, tape, tap-spec)
- Upgraded: ask travis to only test node stable
- Upgraded: some tests fixed, some tests added

# 1.4.1 - 2015-10-18

- Fixed: `generator.js` was missing

# 1.4.0 - 2015-10-18

- Upgraded: browserslist 1.x
- Upgraded: shelljs 0.5.x
- Added: output to notify if generation has been made or not
(related to [#25](https://github.com/Nyalab/caniuse-api/issues/25))

# 1.3.2 - 2015-06-23

- Fixed: lodash.uniq dep
([#31](https://github.com/Nyalab/caniuse-api/issues/31))

# 1.3.1 - 2015-03-31

- Fixed: Windows support

# 1.3.0 - 2015-03-30

- Added: better exception messages
- Added: full browserify compatibility (by avoiding dynamic require)

# 1.2.2 - 2015-02-06

- Fixed: postinstall hook for Windows

# 1.2.1 - 2015-02-04

- Changed: Allow in browser usage by avoiding `require.resolve` and using a generated json instead or reading a directory ([#20](https://github.com/Nyalab/caniuse-api/pull/20)]

# 1.2.0 [YANKED]

# 1.1.0 - 2015-02-03

- Fixed: usage of caniuse-db outside the package itself
- Changed: upgrade to browserslist 0.2.x

# 1.0.0 - 2014-12-16

- Added: package is now automatically tested by [Travis-CI](https://travis-ci.org/Nyalab/caniuse-api)

# 0.1.0 - 2014-12-15

- Changed: complete API changes, released as `caniuse-api` package

# 0.0.1 - 2014-12-09

✨Initial release

license: mit


code:
# caniuse-api [![Build Status](https://travis-ci.org/Nyalab/caniuse-api.svg?branch=master)](https://travis-ci.org/Nyalab/caniuse-api) [![Build status](https://ci.appveyor.com/api/projects/status/6j3na522bv3bxfa5/branch/master?svg=true)](https://ci.appveyor.com/project/MoOx/caniuse-api/branch/master)

request the caniuse data to check browsers compatibilities

## Installation

```console
$ yarn add caniuse-api
```

## Usage

```js
const caniuse = require('caniuse-api')

caniuse.getSupport('border-radius')
caniuse.isSupported('border-radius', 'ie 8, ie 9')
caniuse.setBrowserScope('> 5%, last 1 version')
caniuse.getSupport('border-radius')
// ...
```

## API

#### `caniuse.getSupport(feature)`

_ask since which browsers versions a feature is available_

* `y`: Since which browser version the feature is available
* `n`: Up to which browser version the feature is unavailable
* `a`: Up to which browser version the feature is partially supported
* `x`: Up to which browser version the feature is prefixed

```js
caniuse.getSupport('border-radius', true)
/*
{ and_chr: { y: 67 },
  and_ff: { y: 60 },
  and_qq: { y: 1.2 },
  and_uc: { y: 11.8 },
  android: { y: 2.1, x: 2.1 },
  baidu: { y: 7.12 },
  chrome: { y: 4, x: 4 },
  edge: { y: 12 },
  firefox: { a: 2, x: 3.6, y: 3 },
  ie: { n: 8, y: 9 },
  ie_mob: { y: 10 },
  ios_saf: { y: 3.2, x: 3.2 },
  op_mini: {},
  op_mob: { n: 10, y: 11 },
  opera: { n: 10, y: 10.5 },
  safari: { y: 3.1, x: 4 },
  samsung: { y: 4 } }
*/
```

#### `caniuse.isSupported(feature, browsers)`

_ask if a feature is supported by some browsers_

```js
caniuse.isSupported('border-radius', 'ie 8, ie 9') // false
caniuse.isSupported('border-radius', 'ie 9') // true
```

#### `caniuse.find(query)`

_search for a caniuse feature name_

Ex:

```js
caniuse.find('radius') // ['border-radius']
caniuse.find('nothingness') // []
caniuse.find('css3')
/*
[ 'css3-attr',
  'css3-boxsizing',
  'css3-colors',
  'css3-cursors-grab',
  'css3-cursors-newer',
  'css3-cursors',
  'css3-tabsize' ]
*/
```

#### `caniuse.getLatestStableBrowsers()`

_get the current version for each browser_

```js
caniuse.getLatestStableBrowsers()
/*
[ 'and_chr 67',
  'and_ff 60',
  'and_qq 1.2',
  'and_uc 11.8',
  'android 67',
  'baidu 7.12',
  'bb 10',
  'chrome 67',
  'edge 17',
  'firefox 61',
  'ie 11',
  'ie_mob 11',
  'ios_saf 11.3-11.4',
  'op_mini all',
  'op_mob 46',
  'opera 53',
  'safari 11.1',
  'samsung 7.2' ]
*/
```

#### `caniuse.getBrowserScope()`

_returns a list of browsers currently used for the scope of operations_

```js
caniuse.getBrowserScope()
/*
[ 'and_chr',
  'and_ff',
  'and_qq',
  'and_uc',
  'android',
  'baidu',
  'chrome',
  'edge',
  'firefox',
  'ie',
  'ie_mob',
  'ios_saf',
  'op_mini',
  'op_mob',
  'opera',
  'safari',
  'samsung' ]
*/
```

#### `caniuse.setBrowserScope(browserscope)`

_if you do not like the default browser scope, you can set it globally by using this method_

* browserscope should be a 'autoprefixer' formatted string

```js
caniuse.setBrowserScope('> 5%, last 2 versions, Firefox ESR, Opera 12.1')
```

---

## [Changelog](CHANGELOG.md)

## [License](LICENSE)


code:
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.getBrowserScope = exports.setBrowserScope = exports.getLatestStableBrowsers = exports.find = exports.isSupported = exports.getSupport = exports.features = undefined;

var _lodash = require("lodash.memoize");

var _lodash2 = _interopRequireDefault(_lodash);

var _browserslist = require("browserslist");

var _browserslist2 = _interopRequireDefault(_browserslist);

var _caniuseLite = require("caniuse-lite");

var _utils = require("./utils");

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var featuresList = Object.keys(_caniuseLite.features);

var browsers = void 0;
function setBrowserScope(browserList) {
  browsers = (0, _utils.cleanBrowsersList)(browserList);
}

function getBrowserScope() {
  return browsers;
}

var parse = (0, _lodash2.default)(_utils.parseCaniuseData, function (feat, browsers) {
  return feat.title + browsers;
});

function getSupport(query) {
  var feature = void 0;
  try {
    feature = (0, _caniuseLite.feature)(_caniuseLite.features[query]);
  } catch (e) {
    var res = find(query);
    if (res.length === 1) return getSupport(res[0]);
    throw new ReferenceError("Please provide a proper feature name. Cannot find " + query);
  }
  return parse(feature, browsers);
}

function isSupported(feature, browsers) {
  var data = void 0;
  try {
    data = (0, _caniuseLite.feature)(_caniuseLite.features[feature]);
  } catch (e) {
    var res = find(feature);
    if (res.length === 1) {
      data = _caniuseLite.features[res[0]];
    } else {
      throw new ReferenceError("Please provide a proper feature name. Cannot find " + feature);
    }
  }

  return (0, _browserslist2.default)(browsers, { ignoreUnknownVersions: true }).map(function (browser) {
    return browser.split(" ");
  }).every(function (browser) {
    return data.stats[browser[0]] && data.stats[browser[0]][browser[1]] === "y";
  });
}

function find(query) {
  if (typeof query !== "string") {
    throw new TypeError("The `query` parameter should be a string.");
  }

  if (~featuresList.indexOf(query)) {
    // exact match
    return query;
  }

  return featuresList.filter(function (file) {
    return (0, _utils.contains)(file, query);
  });
}

function getLatestStableBrowsers() {
  return (0, _browserslist2.default)("last 1 version");
}

setBrowserScope();

exports.features = featuresList;
exports.getSupport = getSupport;
exports.isSupported = isSupported;
exports.find = find;
exports.getLatestStableBrowsers = getLatestStableBrowsers;
exports.setBrowserScope = setBrowserScope;
exports.getBrowserScope = getBrowserScope;


code:
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.contains = contains;
exports.parseCaniuseData = parseCaniuseData;
exports.cleanBrowsersList = cleanBrowsersList;

var _lodash = require("lodash.uniq");

var _lodash2 = _interopRequireDefault(_lodash);

var _browserslist = require("browserslist");

var _browserslist2 = _interopRequireDefault(_browserslist);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function contains(str, substr) {
  return !!~str.indexOf(substr);
}

function parseCaniuseData(feature, browsers) {
  var support = {};
  var letters;
  var letter;

  browsers.forEach(function (browser) {
    support[browser] = {};
    for (var info in feature.stats[browser]) {
      letters = feature.stats[browser][info].replace(/#\d+/, "").trim().split(" ");
      info = parseFloat(info.split("-")[0]); //if info is a range, take the left
      if (isNaN(info)) continue;
      for (var i = 0; i < letters.length; i++) {
        letter = letters[i];
        if (letter === "d") {
          // skip this letter, we don't support it yet
          continue;
        } else if (letter === "y") {
          // min support asked, need to find the min value
          if (typeof support[browser][letter] === "undefined" || info < support[browser][letter]) {
            support[browser][letter] = info;
          }
        } else {
          // any other support, need to find the max value
          if (typeof support[browser][letter] === "undefined" || info > support[browser][letter]) {
            support[browser][letter] = info;
          }
        }
      }
    }
  });

  return support;
}

function cleanBrowsersList(browserList) {
  return (0, _lodash2.default)((0, _browserslist2.default)(browserList).map(function (browser) {
    return browser.split(" ")[0];
  }));
}


caniuse-api

description: request the caniuse data to check browsers compatibilities

keywords: caniuse browserslist

authors: nyalab MoOx

license: MIT

build: babel src --out-dir dist

lint: jshint src

prepublish: npm run build

test: npm run lint && babel-tape-runner test/*.js | tap-spec

release: npmpub


code:
# caniuse-lite

A smaller version of caniuse-db, with only the essentials!

## Docs
Read full docs **[here](https://github.com/browserslist/caniuse-lite#readme)**.


code:
module.exports = {
  1: 'ls', // WHATWG Living Standard
  2: 'rec', // W3C Recommendation
  3: 'pr', // W3C Proposed Recommendation
  4: 'cr', // W3C Candidate Recommendation
  5: 'wd', // W3C Working Draft
  6: 'other', // Non-W3C, but reputable
  7: 'unoff' // Unofficial, Editor's Draft or W3C "Note"
}


code:
'use strict'

const browsers = require('./browsers').browsers
const versions = require('./browserVersions').browserVersions
const agentsData = require('../../data/agents')

function unpackBrowserVersions(versionsData) {
  return Object.keys(versionsData).reduce((usage, version) => {
    usage[versions[version]] = versionsData[version]
    return usage
  }, {})
}

module.exports.agents = Object.keys(agentsData).reduce((map, key) => {
  let versionsData = agentsData[key]
  map[browsers[key]] = Object.keys(versionsData).reduce((data, entry) => {
    if (entry === 'A') {
      data.usage_global = unpackBrowserVersions(versionsData[entry])
    } else if (entry === 'C') {
      data.versions = versionsData[entry].reduce((list, version) => {
        if (version === '') {
          list.push(null)
        } else {
          list.push(versions[version])
        }
        return list
      }, [])
    } else if (entry === 'D') {
      data.prefix_exceptions = unpackBrowserVersions(versionsData[entry])
    } else if (entry === 'E') {
      data.browser = versionsData[entry]
    } else if (entry === 'F') {
      data.release_date = Object.keys(versionsData[entry]).reduce(
        (map2, key2) => {
          map2[versions[key2]] = versionsData[entry][key2]
          return map2
        },
        {}
      )
    } else {
      // entry is B
      data.prefix = versionsData[entry]
    }
    return data
  }, {})
  return map
}, {})


code:
'use strict'

const statuses = require('../lib/statuses')
const supported = require('../lib/supported')
const browsers = require('./browsers').browsers
const versions = require('./browserVersions').browserVersions

const MATH2LOG = Math.log(2)

function unpackSupport(cipher) {
  // bit flags
  let stats = Object.keys(supported).reduce((list, support) => {
    if (cipher & supported[support]) list.push(support)
    return list
  }, [])

  // notes
  let notes = cipher >> 7
  let notesArray = []
  while (notes) {
    let note = Math.floor(Math.log(notes) / MATH2LOG) + 1
    notesArray.unshift(`#${note}`)
    notes -= Math.pow(2, note - 1)
  }

  return stats.concat(notesArray).join(' ')
}

function unpackFeature(packed) {
  let unpacked = {
    status: statuses[packed.B],
    title: packed.C,
    shown: packed.D
  }
  unpacked.stats = Object.keys(packed.A).reduce((browserStats, key) => {
    let browser = packed.A[key]
    browserStats[browsers[key]] = Object.keys(browser).reduce(
      (stats, support) => {
        let packedVersions = browser[support].split(' ')
        let unpacked2 = unpackSupport(support)
        packedVersions.forEach(v => (stats[versions[v]] = unpacked2))
        return stats
      },
      {}
    )
    return browserStats
  }, {})
  return unpacked
}

module.exports = unpackFeature
module.exports.default = unpackFeature


code:
/*
 * Load this dynamically so that it
 * doesn't appear in the rollup bundle.
 */

module.exports.features = require('../../data/features')


code:
module.exports.agents = require('./agents').agents
module.exports.feature = require('./feature')
module.exports.features = require('./features').features
module.exports.region = require('./region')


code:
'use strict'

const browsers = require('./browsers').browsers

function unpackRegion(packed) {
  return Object.keys(packed).reduce((list, browser) => {
    let data = packed[browser]
    list[browsers[browser]] = Object.keys(data).reduce((memo, key) => {
      let stats = data[key]
      if (key === '_') {
        stats.split(' ').forEach(version => (memo[version] = null))
      } else {
        memo[key] = stats
      }
      return memo
    }, {})
    return list
  }, {})
}

module.exports = unpackRegion
module.exports.default = unpackRegion


caniuse-lite

description: A smaller version of caniuse-db, with only the essentials!

files: data dist

repository: browserslist/caniuse-lite

type: opencollective

type: tidelift

type: github


code:
### Changelog

All notable changes to this project will be documented in this file. Dates are displayed in UTC.

Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).

#### [v2.4.0](https://github.com/Urthen/case-sensitive-paths-webpack-plugin/compare/v2.3.0...v2.4.0)

- Updating versions & tests for development [`1d11967`](https://github.com/Urthen/case-sensitive-paths-webpack-plugin/commit/1d11967cf3d5d984629536ad51e03c9670c573ad)
- Update dependencies, travis targets. [`31491e0`](https://github.com/Urthen/case-sensitive-paths-webpack-plugin/commit/31491e01cf9360d2144ad656df1253e678af1407)
- Run prettier on test index. [`3bf9fa2`](https://github.com/Urthen/case-sensitive-paths-webpack-plugin/commit/3bf9fa22977d6ad61da5db0246d866c5b3e8af39)
- Run prettier across index. [`f12aa57`](https://github.com/Urthen/case-sensitive-paths-webpack-plugin/commit/f12aa577b7e2b932b28aa4e21555cdb12929c352)
- Automatically generate changelog [`dc7765e`](https://github.com/Urthen/case-sensitive-paths-webpack-plugin/commit/dc7765edb1c090a65c60005f790639a13345315a)
- Add test case ensuring deeply nested folder case problems are caught [`198c7e1`](https://github.com/Urthen/case-sensitive-paths-webpack-plugin/commit/198c7e1416f010fc4ee6c439319bbaf5aa960973)
- [#54] Unescape # in paths [`7d05a0a`](https://github.com/Urthen/case-sensitive-paths-webpack-plugin/commit/7d05a0a0945b1ef438da711297c1ab64b674d814)
- Change the pathCache to be a Map. [`737dadd`](https://github.com/Urthen/case-sensitive-paths-webpack-plugin/commit/737dadd4b02e377296c9cd2d7c02703e09bb771a)
- Changelog [`c662bc4`](https://github.com/Urthen/case-sensitive-paths-webpack-plugin/commit/c662bc43a8066f2714be7ea1289570b14821e47b)
- Bump lodash from 4.17.15 to 4.17.19 [`08dec5d`](https://github.com/Urthen/case-sensitive-paths-webpack-plugin/commit/08dec5da716fae307f99336de02fab63b15ae7a2)
- Credit [`30dcfc1`](https://github.com/Urthen/case-sensitive-paths-webpack-plugin/commit/30dcfc1c1ae091b1717ab18c98806a01358f664a)

#### [v2.3.0](https://github.com/Urthen/case-sensitive-paths-webpack-plugin/compare/v2.1.2...v2.3.0)

> 15 January 2020

- Testing updates [`#37`](https://github.com/Urthen/case-sensitive-paths-webpack-plugin/pull/37)
- Use the before emit hook to check if files exist [`#36`](https://github.com/Urthen/case-sensitive-paths-webpack-plugin/pull/36)
- Add configurable logger [`#38`](https://github.com/Urthen/case-sensitive-paths-webpack-plugin/issues/38)
- Linting and dependency updates. [`d4fc994`](https://github.com/Urthen/case-sensitive-paths-webpack-plugin/commit/d4fc99450ae45c2b631a4b949f92d62794ff52cf)
- Update for Node 4 use to prevent major semver bump [`e400f17`](https://github.com/Urthen/case-sensitive-paths-webpack-plugin/commit/e400f177f2414e183f03c271f9683a2006ee3f1e)
- Start using AutoChangelog [`c2b6ca1`](https://github.com/Urthen/case-sensitive-paths-webpack-plugin/commit/c2b6ca1f271dbac1565f27ab4be2a3f2712eea28)
- Update tests to properly account for Webpack 5 changes [`d84f848`](https://github.com/Urthen/case-sensitive-paths-webpack-plugin/commit/d84f848df707d68dc14595df86ff88920ea709ff)
- Remove Node 4 from Travis test as it is flaky. [`329d32d`](https://github.com/Urthen/case-sensitive-paths-webpack-plugin/commit/329d32d9b4614f73fe121743aeee2dedbf14cae9)
- Add Travis support for Webpack 5 and Node 12. [`4e9b361`](https://github.com/Urthen/case-sensitive-paths-webpack-plugin/commit/4e9b36135ef6a5f0b19f41cce45dc5b1a9431b8b)
- Update index.js [`bef726c`](https://github.com/Urthen/case-sensitive-paths-webpack-plugin/commit/bef726cd4686569f3fc7c8b84ea8bd6836c03f8a)
- Fix for #40 [`1c8e615`](https://github.com/Urthen/case-sensitive-paths-webpack-plugin/commit/1c8e615a52eeb180d140102e8c23a07a9ca40c60)

#### [v2.1.2](https://github.com/Urthen/case-sensitive-paths-webpack-plugin/compare/v2.0.0...v2.1.2)

> 6 March 2018

- Add support for webpack 4 [`#31`](https://github.com/Urthen/case-sensitive-paths-webpack-plugin/pull/31)
- Add license scan report and status [`#27`](https://github.com/Urthen/case-sensitive-paths-webpack-plugin/pull/27)
- Merge FOSSA's badge [`be74649`](https://github.com/Urthen/case-sensitive-paths-webpack-plugin/commit/be74649d64c70f8b79efe25c320e737c2ebef07a)
- Release 2.1.0 - No longer return our own error on file not found. [`fb1d636`](https://github.com/Urthen/case-sensitive-paths-webpack-plugin/commit/fb1d63653bdc83edc25aada8b8022a4d12fa330a)
- Testing improvements. [`2abbfce`](https://github.com/Urthen/case-sensitive-paths-webpack-plugin/commit/2abbfce8f963b48ad596f6f46065575216abd6a5)
- Release 2.1.1 - Properly support older versions of node [`aaef33f`](https://github.com/Urthen/case-sensitive-paths-webpack-plugin/commit/aaef33fc265522c223150756f059216c183b679e)
- Add badges. [`d1563c7`](https://github.com/Urthen/case-sensitive-paths-webpack-plugin/commit/d1563c769ccd288cebfb74e3de7b612103e9cf5a)
- Fix test. [`6f2519b`](https://github.com/Urthen/case-sensitive-paths-webpack-plugin/commit/6f2519b11e3ad6a521ffeee248bfda372023c636)
- Fix badges. [`face6dc`](https://github.com/Urthen/case-sensitive-paths-webpack-plugin/commit/face6dc4b5b6a0f9820d89e79cab308e2dede4b8)
- Update README.md [`5cfb570`](https://github.com/Urthen/case-sensitive-paths-webpack-plugin/commit/5cfb5709682a572df21d36d181c90629d2355e98)

### [v2.0.0](https://github.com/Urthen/case-sensitive-paths-webpack-plugin/compare/1.1.4...v2.0.0)

> 31 March 2017

- Use compiler filesystem [`#14`](https://github.com/Urthen/case-sensitive-paths-webpack-plugin/pull/14)
- Add `files` to `package.json`. [`#15`](https://github.com/Urthen/case-sensitive-paths-webpack-plugin/pull/15)
- Update README.md [`#13`](https://github.com/Urthen/case-sensitive-paths-webpack-plugin/pull/13)

#### 1.1.4

> 6 September 2016

- Don't crash on folder deletion with tests [`#10`](https://github.com/Urthen/case-sensitive-paths-webpack-plugin/pull/10)
- Normalize filenames to default Unicode Normalization Form (NFC) so th… [`#6`](https://github.com/Urthen/case-sensitive-paths-webpack-plugin/pull/6)
- Working E2E Tests in a Demo Project [`#4`](https://github.com/Urthen/case-sensitive-paths-webpack-plugin/pull/4)
- check for windows-style root paths [`#2`](https://github.com/Urthen/case-sensitive-paths-webpack-plugin/pull/2)
- Create a working React/Webpack project, with Jasmine unit tests that demonstrate the functionality of the plugin. [`de4c1e5`](https://github.com/Urthen/case-sensitive-paths-webpack-plugin/commit/de4c1e5cb9d7e8bcc229876735236c0043f5fdeb)
- Initial Code [`bb1d65b`](https://github.com/Urthen/case-sensitive-paths-webpack-plugin/commit/bb1d65b0f7b1240a06e1f873ebf5a45f06b7d5bb)
- Drastically reduce filesystem operations required, release v1.1.0 [`ca03460`](https://github.com/Urthen/case-sensitive-paths-webpack-plugin/commit/ca034602148adc7617e1edc39e7931f35de865b5)
- Added failing test when a folder is deleted while watching files [`e35eada`](https://github.com/Urthen/case-sensitive-paths-webpack-plugin/commit/e35eadacc86cdcdaa864a4166a199b13ac852837)
- Initial commit [`e47ac63`](https://github.com/Urthen/case-sensitive-paths-webpack-plugin/commit/e47ac63b7a914f90e912cd67967ade9866a3c543)
- Added a basic test [`293d43a`](https://github.com/Urthen/case-sensitive-paths-webpack-plugin/commit/293d43abc8fc2217182eb8d3cdee5a826938f7af)
- More verbose output, add readme. [`961e350`](https://github.com/Urthen/case-sensitive-paths-webpack-plugin/commit/961e350faec9c942c580b0a0d23917cda02eea8c)
- Handle situations where user has CDed into incorrectly cased directory [`d02babf`](https://github.com/Urthen/case-sensitive-paths-webpack-plugin/commit/d02babf89f0bf4251efbd7ca5d64a79211487a74)
- 1.1.1 - Fix bug related to the cache and hot-reloading [`d287045`](https://github.com/Urthen/case-sensitive-paths-webpack-plugin/commit/d2870450be2d33b8b9d4deb692e2fcf7d00d895c)
- Use @gaearon's method to stop crashes [`83ac4db`](https://github.com/Urthen/case-sensitive-paths-webpack-plugin/commit/83ac4dbfe1288e09ba1a2971f3d9cb95779ba52c)
- Catch errors in plugin and propagate them [`e4fbf33`](https://github.com/Urthen/case-sensitive-paths-webpack-plugin/commit/e4fbf333b624aa1543712967668f48ad8ea1d587)
- Credit where credit is due [`8124d95`](https://github.com/Urthen/case-sensitive-paths-webpack-plugin/commit/8124d9545534fce33e3fd96aa9c4df18af00e329)
- update main README; [`52fc97c`](https://github.com/Urthen/case-sensitive-paths-webpack-plugin/commit/52fc97c2464c78052bd41faeb2c7016f05205b40)
- Update README.md [`33db517`](https://github.com/Urthen/case-sensitive-paths-webpack-plugin/commit/33db51747e6c20281de6497223bcabe1eba65994)
- Normalize filenames to default Unicode Normalization Form (NFC) so that all utf8-characters are compared correctly. [`41d9418`](https://github.com/Urthen/case-sensitive-paths-webpack-plugin/commit/41d94181cc7f5ad52487b2e8058f82865eefe466)
- kill the recursive reference loop by directly accessing the package's `main` [`9f980f6`](https://github.com/Urthen/case-sensitive-paths-webpack-plugin/commit/9f980f633dcb68829ff13e70ed72a9c70da688d5)
- Readme updates, bump version [`4be829d`](https://github.com/Urthen/case-sensitive-paths-webpack-plugin/commit/4be829dd3bd39b1156ddbb6fbab9da794f8b6064)
- I know how markdown works, I swear [`5daec2c`](https://github.com/Urthen/case-sensitive-paths-webpack-plugin/commit/5daec2cddfa4eda51c68e29e2adb5041e6e35f9e)
- Release 1.1.3 [`21390e1`](https://github.com/Urthen/case-sensitive-paths-webpack-plugin/commit/21390e1d25ff9ed46229fb0541329e753a1f3410)
- readability edit [`99c0f0d`](https://github.com/Urthen/case-sensitive-paths-webpack-plugin/commit/99c0f0de1a570ed8b67a9464bdf9287f24dce10e)
- Reduce waittime [`d0fd084`](https://github.com/Urthen/case-sensitive-paths-webpack-plugin/commit/d0fd084236b231283191a4099c97584b2bba1676)
- Credit [`8818e92`](https://github.com/Urthen/case-sensitive-paths-webpack-plugin/commit/8818e920f1c3f3df696489e89c08498389972ffa)
- remove the unnecessary require [`45bb0bb`](https://github.com/Urthen/case-sensitive-paths-webpack-plugin/commit/45bb0bbc5cca9137714bafca40ec8e351e2c4dbb)


code:
Case Sensitive Paths - Webpack Plugin
==========

[![Build Status](https://travis-ci.org/Urthen/case-sensitive-paths-webpack-plugin.svg?branch=master)](https://travis-ci.org/Urthen/case-sensitive-paths-webpack-plugin)
[![Known Vulnerabilities](https://snyk.io/test/github/urthen/case-sensitive-paths-webpack-plugin/badge.svg?targetFile=package.json)](https://snyk.io/test/github/urthen/case-sensitive-paths-webpack-plugin?targetFile=package.json)
[![npm version](https://badge.fury.io/js/case-sensitive-paths-webpack-plugin.svg)](https://badge.fury.io/js/case-sensitive-paths-webpack-plugin)
[![npm downloads](https://img.shields.io/npm/dw/case-sensitive-paths-webpack-plugin.svg)](https://www.npmjs.com/package/case-sensitive-paths-webpack-plugin)
![bananas: ripe](https://img.shields.io/badge/bananas-ripe-yellow.svg)
[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2FUrthen%2Fcase-sensitive-paths-webpack-plugin.svg?type=shield)](https://app.fossa.io/projects/git%2Bgithub.com%2FUrthen%2Fcase-sensitive-paths-webpack-plugin?ref=badge_shield)

This Webpack plugin enforces the entire path of all required modules match the exact case of the actual path on disk.
Using this plugin helps alleviate cases where developers working on OSX, which does not follow strict path case sensitivity,
will cause conflicts with other developers or build boxes running other operating systems which require correctly cased paths.

[Previous](https://gist.github.com/Morhaus/333579c2a5b4db644bd50) [iterations](https://github.com/dcousineau/force-case-sensitivity-webpack-plugin) on this same idea provide the basis for this plugin, but unfortunately do not properly check case on
the entire path. This plugin fixes that. Example output:

> ERROR in ./src/containers/SearchProducts.js
  Module not found: Error: [CaseSensitivePathsPlugin] `/Users/example/yourproject/src/components/searchProducts/searchproducts.js` does not match the corresponding path on disk `/Users/example/yourproject/src/components/searchproducts`
   @ ./src/containers/SearchProducts.js 9:22-84

Install
----
    npm install --save-dev case-sensitive-paths-webpack-plugin

Usage
----

```JavaScript
var CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin');

var webpackConfig = {
    plugins: [
        new CaseSensitivePathsPlugin()
        // other plugins ...
    ]
    // other webpack config ...
}
```

Want more information? Pass ```{debug: true}``` to the plugin like so:

```JavaScript
new CaseSensitivePathsPlugin({debug: true})
```

It will output every directory it reads, as well as a sum total of filesystem operations.
This is mostly useful for internal debugging of the plugin, but if you find it useful, more power to you.

Demo
---
Check the `/demo` directory for a working example of the plugin in action, with tests demonstrating the effect of the plugin. See `/demo/README.md` for more.

Thanks & Credit
----
* [Daniel Cousineau](https://github.com/dcousineau) who wrote an [earlier version](https://github.com/dcousineau/force-case-sensitivity-webpack-plugin) of this case-sensitivity plugin
* [Alexandre Kirszenberg](https://github.com/Morhaus) who's [gist](https://gist.github.com/Morhaus/333579c2a5b4db644bd5) formed the basis of both these plugins.
* [Cameron Brewer](https://github.com/morethanfire) and [Ben Collins](https://github.com/aggieben) who added Windows support.
* [Christian Lilley](https://github.com/xml) who added a demo/test package.
* [Lance Eastgate](https://github.com/NorwegianKiwi) who added some internationalization support
* [Jonathan Kim](https://github.com/jkimbo) and [Dan Abramov](https://github.com/gaearon) who investigated, fixed, and added some tests for a crashing bug.
* [Jason Quense](https://github.com/jquense) who switched it to properly use the webpack-provided fs object.
* [Cesare Soldini](https://github.com/caesarsol) who added a test
* [Kirill Konshin](https://github.com/kirill-konshin) who helped update to Webpack 5

## License
[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2FUrthen%2Fcase-sensitive-paths-webpack-plugin.svg?type=large)](https://app.fossa.io/projects/git%2Bgithub.com%2FUrthen%2Fcase-sensitive-paths-webpack-plugin?ref=badge_large)


code:
/* eslint-disable strict */

'use strict';

/* This plugin based on https://gist.github.com/Morhaus/333579c2a5b4db644bd5

 Original license:
 --------
 The MIT License (MIT)
 Copyright (c) 2015 Alexandre Kirszenberg
 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.
 --------

 And it's NPM-ified version: https://github.com/dcousineau/force-case-sensitivity-webpack-plugin
 Author Daniel Cousineau indicated MIT license as well but did not include it

 The originals did not properly case-sensitize the entire path, however. This plugin resolves that issue.

 This plugin license, also MIT:
 --------
 The MIT License (MIT)
 Copyright (c) 2016 Michael Pratt
 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.
 --------
 */

const path = require('path');

function CaseSensitivePathsPlugin(options) {
  this.options = options || {};
  this.logger = this.options.logger || console;
  this.pathCache = new Map();
  this.reset();
}

CaseSensitivePathsPlugin.prototype.reset = function() {
  this.pathCache = new Map();
  this.fsOperations = 0;
  this.primed = false;
};

CaseSensitivePathsPlugin.prototype.getFilenamesInDir = function(dir, callback) {
  const that = this;
  const fs = this.compiler.inputFileSystem;
  this.fsOperations += 1;

  if (this.pathCache.has(dir)) {
    callback(this.pathCache.get(dir));
    return;
  }
  if (this.options.debug) {
    this.logger.log('[CaseSensitivePathsPlugin] Reading directory', dir);
  }

  fs.readdir(dir, (err, files) => {
    if (err) {
      if (that.options.debug) {
        this.logger.log(
          '[CaseSensitivePathsPlugin] Failed to read directory',
          dir,
          err,
        );
      }
      callback([]);
      return;
    }

    callback(files.map((f) => (f.normalize ? f.normalize('NFC') : f)));
  });
};

// This function based on code found at http://stackoverflow.com/questions/27367261/check-if-file-exists-case-sensitive
// By Patrick McElhaney (No license indicated - Stack Overflow Answer)
// This version will return with the real name of any incorrectly-cased portion of the path, null otherwise.
CaseSensitivePathsPlugin.prototype.fileExistsWithCase = function(
  filepath,
  callback,
) {
  // Split filepath into current filename (or directory name) and parent directory tree.
  const that = this;
  const dir = path.dirname(filepath);
  const filename = path.basename(filepath);
  const parsedPath = path.parse(dir);

  // If we are at the root, or have found a path we already know is good, return.
  if (
    parsedPath.dir === parsedPath.root ||
    dir === '.' ||
    that.pathCache.has(filepath)
  ) {
    callback();
    return;
  }

  // Check all filenames in the current dir against current filename to ensure one of them matches.
  // Read from the cache if available, from FS if not.
  that.getFilenamesInDir(dir, (filenames) => {
    // If the exact match does not exist, attempt to find the correct filename.
    if (filenames.indexOf(filename) === -1) {
      // Fallback value which triggers us to abort.
      let correctFilename = '!nonexistent';

      for (let i = 0; i < filenames.length; i += 1) {
        if (filenames[i].toLowerCase() === filename.toLowerCase()) {
          correctFilename = `\`${filenames[i]}\`.`;
          break;
        }
      }
      callback(correctFilename);
      return;
    }

    // If exact match exists, recurse through directory tree until root.
    that.fileExistsWithCase(dir, (recurse) => {
      // If found an error elsewhere, return that correct filename
      // Don't bother caching - we're about to error out anyway.
      if (!recurse) {
        that.pathCache.set(dir, filenames);
      }

      callback(recurse);
    });
  });
};

CaseSensitivePathsPlugin.prototype.primeCache = function(callback) {
  if (this.primed) {
    callback();
    return;
  }

  const that = this;
  // Prime the cache with the current directory. We have to assume the current casing is correct,
  // as in certain circumstances people can switch into an incorrectly-cased directory.
  const currentPath = path.resolve();
  that.getFilenamesInDir(currentPath, (files) => {
    that.pathCache.set(currentPath,files);
    that.primed = true;
    callback();
  });
};

CaseSensitivePathsPlugin.prototype.apply = function(compiler) {
  this.compiler = compiler;

  const onDone = () => {
    if (this.options.debug) {
      this.logger.log(
        '[CaseSensitivePathsPlugin] Total filesystem reads:',
        this.fsOperations,
      );
    }

    this.reset();
  };

  const checkFile = (pathName, data, done) => {
    this.fileExistsWithCase(pathName, (realName) => {
      if (realName) {
        if (realName === '!nonexistent') {
          // If file does not exist, let Webpack show a more appropriate error.
          if (data.createData) done(null);
          else done(null, data);
        } else {
          done(
            new Error(
              `[CaseSensitivePathsPlugin] \`${pathName}\` does not match the corresponding path on disk ${realName}`,
            ),
          );
        }
      } else if (data.createData) {
        done(null);
      } else {
        done(null, data);
      }
    });
  };

  const cleanupPath = (resourcePath) => {
      // Trim ? off, since some loaders add that to the resource they're attemping to load
      return resourcePath.split('?')[0]
        // replace escaped \0# with # see: https://github.com/webpack/enhanced-resolve#escaping
        .replace('\u0000#', '#');
  }

  const onAfterResolve = (data, done) => {
    this.primeCache(() => {

      let pathName = cleanupPath((data.createData || data).resource);
      pathName = pathName.normalize ? pathName.normalize('NFC') : pathName;

      checkFile(pathName, data, done);
    });
  };

  if (compiler.hooks) {
    compiler.hooks.done.tap('CaseSensitivePathsPlugin', onDone);
    if (this.options.useBeforeEmitHook) {
      if (this.options.debug) {
        this.logger.log(
          '[CaseSensitivePathsPlugin] Using the hook for before emit.',
        );
      }
      compiler.hooks.emit.tapAsync(
        'CaseSensitivePathsPlugin',
        (compilation, callback) => {
          let resolvedFilesCount = 0;
          const errors = [];
          this.primeCache(() => {
            compilation.fileDependencies.forEach((filename) => {
              checkFile(filename, filename, (error) => {
                resolvedFilesCount += 1;
                if (error) {
                  errors.push(error);
                }
                if (resolvedFilesCount === compilation.fileDependencies.size) {
                  if (errors.length) {
                    // Send all errors to webpack
                    Array.prototype.push.apply(compilation.errors, errors);
                  }
                  callback();
                }
              });
            });
          });
        },
      );
    } else {
      compiler.hooks.normalModuleFactory.tap(
        'CaseSensitivePathsPlugin',
        (nmf) => {
          nmf.hooks.afterResolve.tapAsync(
            'CaseSensitivePathsPlugin',
            onAfterResolve,
          );
        },
      );
    }
  } else {
    compiler.plugin('done', onDone);
    compiler.plugin('normal-module-factory', (nmf) => {
      nmf.plugin('after-resolve', onAfterResolve);
    });
  }
};

module.exports = CaseSensitivePathsPlugin;


case-sensitive-paths-webpack-plugin

description: Enforces module path case sensitivity in Webpack

test: mocha test/

lint: eslint index.js

lintfix: eslint --fix index.js test/index.js

version: auto-changelog -p && git add CHANGELOG.md

type: git

keywords:
webpack
plugin
case sensitive
import
require

author: Michael Pratt


code:
'use strict';
const escapeStringRegexp = require('escape-string-regexp');
const ansiStyles = require('ansi-styles');
const stdoutColor = require('supports-color').stdout;

const template = require('./templates.js');

const isSimpleWindowsTerm = process.platform === 'win32' && !(process.env.TERM || '').toLowerCase().startsWith('xterm');

// `supportsColor.level` → `ansiStyles.color[name]` mapping
const levelMapping = ['ansi', 'ansi', 'ansi256', 'ansi16m'];

// `color-convert` models to exclude from the Chalk API due to conflicts and such
const skipModels = new Set(['gray']);

const styles = Object.create(null);

function applyOptions(obj, options) {
	options = options || {};

	// Detect level if not set manually
	const scLevel = stdoutColor ? stdoutColor.level : 0;
	obj.level = options.level === undefined ? scLevel : options.level;
	obj.enabled = 'enabled' in options ? options.enabled : obj.level > 0;
}

function Chalk(options) {
	// We check for this.template here since calling `chalk.constructor()`
	// by itself will have a `this` of a previously constructed chalk object
	if (!this || !(this instanceof Chalk) || this.template) {
		const chalk = {};
		applyOptions(chalk, options);

		chalk.template = function () {
			const args = [].slice.call(arguments);
			return chalkTag.apply(null, [chalk.template].concat(args));
		};

		Object.setPrototypeOf(chalk, Chalk.prototype);
		Object.setPrototypeOf(chalk.template, chalk);

		chalk.template.constructor = Chalk;

		return chalk.template;
	}

	applyOptions(this, options);
}

// Use bright blue on Windows as the normal blue color is illegible
if (isSimpleWindowsTerm) {
	ansiStyles.blue.open = '\u001B[94m';
}

for (const key of Object.keys(ansiStyles)) {
	ansiStyles[key].closeRe = new RegExp(escapeStringRegexp(ansiStyles[key].close), 'g');

	styles[key] = {
		get() {
			const codes = ansiStyles[key];
			return build.call(this, this._styles ? this._styles.concat(codes) : [codes], this._empty, key);
		}
	};
}

styles.visible = {
	get() {
		return build.call(this, this._styles || [], true, 'visible');
	}
};

ansiStyles.color.closeRe = new RegExp(escapeStringRegexp(ansiStyles.color.close), 'g');
for (const model of Object.keys(ansiStyles.color.ansi)) {
	if (skipModels.has(model)) {
		continue;
	}

	styles[model] = {
		get() {
			const level = this.level;
			return function () {
				const open = ansiStyles.color[levelMapping[level]][model].apply(null, arguments);
				const codes = {
					open,
					close: ansiStyles.color.close,
					closeRe: ansiStyles.color.closeRe
				};
				return build.call(this, this._styles ? this._styles.concat(codes) : [codes], this._empty, model);
			};
		}
	};
}

ansiStyles.bgColor.closeRe = new RegExp(escapeStringRegexp(ansiStyles.bgColor.close), 'g');
for (const model of Object.keys(ansiStyles.bgColor.ansi)) {
	if (skipModels.has(model)) {
		continue;
	}

	const bgModel = 'bg' + model[0].toUpperCase() + model.slice(1);
	styles[bgModel] = {
		get() {
			const level = this.level;
			return function () {
				const open = ansiStyles.bgColor[levelMapping[level]][model].apply(null, arguments);
				const codes = {
					open,
					close: ansiStyles.bgColor.close,
					closeRe: ansiStyles.bgColor.closeRe
				};
				return build.call(this, this._styles ? this._styles.concat(codes) : [codes], this._empty, model);
			};
		}
	};
}

const proto = Object.defineProperties(() => {}, styles);

function build(_styles, _empty, key) {
	const builder = function () {
		return applyStyle.apply(builder, arguments);
	};

	builder._styles = _styles;
	builder._empty = _empty;

	const self = this;

	Object.defineProperty(builder, 'level', {
		enumerable: true,
		get() {
			return self.level;
		},
		set(level) {
			self.level = level;
		}
	});

	Object.defineProperty(builder, 'enabled', {
		enumerable: true,
		get() {
			return self.enabled;
		},
		set(enabled) {
			self.enabled = enabled;
		}
	});

	// See below for fix regarding invisible grey/dim combination on Windows
	builder.hasGrey = this.hasGrey || key === 'gray' || key === 'grey';

	// `__proto__` is used because we must return a function, but there is
	// no way to create a function with a different prototype
	builder.__proto__ = proto; // eslint-disable-line no-proto

	return builder;
}

function applyStyle() {
	// Support varags, but simply cast to string in case there's only one arg
	const args = arguments;
	const argsLen = args.length;
	let str = String(arguments[0]);

	if (argsLen === 0) {
		return '';
	}

	if (argsLen > 1) {
		// Don't slice `arguments`, it prevents V8 optimizations
		for (let a = 1; a < argsLen; a++) {
			str += ' ' + args[a];
		}
	}

	if (!this.enabled || this.level <= 0 || !str) {
		return this._empty ? '' : str;
	}

	// Turns out that on Windows dimmed gray text becomes invisible in cmd.exe,
	// see https://github.com/chalk/chalk/issues/58
	// If we're on Windows and we're dealing with a gray color, temporarily make 'dim' a noop.
	const originalDim = ansiStyles.dim.open;
	if (isSimpleWindowsTerm && this.hasGrey) {
		ansiStyles.dim.open = '';
	}

	for (const code of this._styles.slice().reverse()) {
		// Replace any instances already present with a re-opening code
		// otherwise only the part of the string until said closing code
		// will be colored, and the rest will simply be 'plain'.
		str = code.open + str.replace(code.closeRe, code.open) + code.close;

		// Close the styling before a linebreak and reopen
		// after next line to fix a bleed issue on macOS
		// https://github.com/chalk/chalk/pull/92
		str = str.replace(/\r?\n/g, `${code.close}$&${code.open}`);
	}

	// Reset the original `dim` if we changed it to work around the Windows dimmed gray issue
	ansiStyles.dim.open = originalDim;

	return str;
}

function chalkTag(chalk, strings) {
	if (!Array.isArray(strings)) {
		// If chalk() was called by itself or with a string,
		// return the string itself as a string.
		return [].slice.call(arguments, 1).join(' ');
	}

	const args = [].slice.call(arguments, 2);
	const parts = [strings.raw[0]];

	for (let i = 1; i < strings.length; i++) {
		parts.push(String(args[i - 1]).replace(/[{}\\]/g, '\\$&'));
		parts.push(String(strings.raw[i]));
	}

	return template(chalk, parts.join(''));
}

Object.defineProperties(Chalk.prototype, styles);

module.exports = Chalk(); // eslint-disable-line new-cap
module.exports.supportsColor = stdoutColor;
module.exports.default = module.exports; // For TypeScript


code:
// @flow strict

type TemplateStringsArray = $ReadOnlyArray<string>;

export type Level = $Values<{
	None: 0,
	Basic: 1,
	Ansi256: 2,
	TrueColor: 3
}>;

export type ChalkOptions = {|
	enabled?: boolean,
	level?: Level
|};

export type ColorSupport = {|
	level: Level,
	hasBasic: boolean,
	has256: boolean,
	has16m: boolean
|};

export interface Chalk {
	(...text: string[]): string,
	(text: TemplateStringsArray, ...placeholders: string[]): string,
	constructor(options?: ChalkOptions): Chalk,
	enabled: boolean,
	level: Level,
	rgb(r: number, g: number, b: number): Chalk,
	hsl(h: number, s: number, l: number): Chalk,
	hsv(h: number, s: number, v: number): Chalk,
	hwb(h: number, w: number, b: number): Chalk,
	bgHex(color: string): Chalk,
	bgKeyword(color: string): Chalk,
	bgRgb(r: number, g: number, b: number): Chalk,
	bgHsl(h: number, s: number, l: number): Chalk,
	bgHsv(h: number, s: number, v: number): Chalk,
	bgHwb(h: number, w: number, b: number): Chalk,
	hex(color: string): Chalk,
	keyword(color: string): Chalk,

	+reset: Chalk,
	+bold: Chalk,
	+dim: Chalk,
	+italic: Chalk,
	+underline: Chalk,
	+inverse: Chalk,
	+hidden: Chalk,
	+strikethrough: Chalk,

	+visible: Chalk,

	+black: Chalk,
	+red: Chalk,
	+green: Chalk,
	+yellow: Chalk,
	+blue: Chalk,
	+magenta: Chalk,
	+cyan: Chalk,
	+white: Chalk,
	+gray: Chalk,
	+grey: Chalk,
	+blackBright: Chalk,
	+redBright: Chalk,
	+greenBright: Chalk,
	+yellowBright: Chalk,
	+blueBright: Chalk,
	+magentaBright: Chalk,
	+cyanBright: Chalk,
	+whiteBright: Chalk,

	+bgBlack: Chalk,
	+bgRed: Chalk,
	+bgGreen: Chalk,
	+bgYellow: Chalk,
	+bgBlue: Chalk,
	+bgMagenta: Chalk,
	+bgCyan: Chalk,
	+bgWhite: Chalk,
	+bgBlackBright: Chalk,
	+bgRedBright: Chalk,
	+bgGreenBright: Chalk,
	+bgYellowBright: Chalk,
	+bgBlueBright: Chalk,
	+bgMagentaBright: Chalk,
	+bgCyanBright: Chalk,
	+bgWhiteBrigh: Chalk,

	supportsColor: ColorSupport
};

declare module.exports: Chalk;


chalk

description: Terminal string styling done right

repository: chalk/chalk

test: xo && tsc --project types && flow --max-warnings=0 && nyc ava

bench: matcha benchmark.js

coveralls: nyc report --reporter=text-lcov | coveralls

keywords: color colour colors terminal console cli string str ansi style styles tty formatting rgb 256 shell xterm log logging command-line text

envs: node mocha


code:
> Terminal string styling done right

[![Build Status](https://travis-ci.org/chalk/chalk.svg?branch=master)](https://travis-ci.org/chalk/chalk) [![Coverage Status](https://coveralls.io/repos/github/chalk/chalk/badge.svg?branch=master)](https://coveralls.io/github/chalk/chalk?branch=master) [![](https://img.shields.io/badge/unicorn-approved-ff69b4.svg)](https://www.youtube.com/watch?v=9auOCbH5Ns4) [![XO code style](https://img.shields.io/badge/code_style-XO-5ed9c7.svg)](https://github.com/xojs/xo) [![Mentioned in Awesome Node.js](https://awesome.re/mentioned-badge.svg)](https://github.com/sindresorhus/awesome-nodejs)

### [See what's new in Chalk 2](https://github.com/chalk/chalk/releases/tag/v2.0.0)

## Highlights

- Expressive API
- Highly performant
- Ability to nest styles
- [256/Truecolor color support](#256-and-truecolor-color-support)
- Auto-detects color support
- Doesn't extend `String.prototype`
- Clean and focused
- Actively maintained
- [Used by ~23,000 packages](https://www.npmjs.com/browse/depended/chalk) as of December 31, 2017

## Install

```console
$ npm install chalk
```

## Usage

```js
const chalk = require('chalk');

console.log(chalk.blue('Hello world!'));
```

Chalk comes with an easy to use composable API where you just chain and nest the styles you want.

```js
const chalk = require('chalk');
const log = console.log;

// Combine styled and normal strings
log(chalk.blue('Hello') + ' World' + chalk.red('!'));

// Compose multiple styles using the chainable API
log(chalk.blue.bgRed.bold('Hello world!'));

// Pass in multiple arguments
log(chalk.blue('Hello', 'World!', 'Foo', 'bar', 'biz', 'baz'));

// Nest styles
log(chalk.red('Hello', chalk.underline.bgBlue('world') + '!'));

// Nest styles of the same type even (color, underline, background)
log(chalk.green(
	'I am a green line ' +
	chalk.blue.underline.bold('with a blue substring') +
	' that becomes green again!'
));

// ES2015 template literal
log(`
CPU: ${chalk.red('90%')}
RAM: ${chalk.green('40%')}
DISK: ${chalk.yellow('70%')}
`);

// ES2015 tagged template literal
log(chalk`
CPU: {red ${cpu.totalPercent}%}
RAM: {green ${ram.used / ram.total * 100}%}
DISK: {rgb(255,131,0) ${disk.used / disk.total * 100}%}
`);

// Use RGB colors in terminal emulators that support it.
log(chalk.keyword('orange')('Yay for orange colored text!'));
log(chalk.rgb(123, 45, 67).underline('Underlined reddish color'));
log(chalk.hex('#DEADED').bold('Bold gray!'));
```

Easily define your own themes:

```js
const chalk = require('chalk');

const error = chalk.bold.red;
const warning = chalk.keyword('orange');

console.log(error('Error!'));
console.log(warning('Warning!'));
```

Take advantage of console.log [string substitution](https://nodejs.org/docs/latest/api/console.html#console_console_log_data_args):

```js
const name = 'Sindre';
console.log(chalk.green('Hello %s'), name);
//=> 'Hello Sindre'
```

## API

### chalk.`<style>[.<style>...](string, [string...])`

Example: `chalk.red.bold.underline('Hello', 'world');`

Chain [styles](#styles) and call the last one as a method with a string argument. Order doesn't matter, and later styles take precedent in case of a conflict. This simply means that `chalk.red.yellow.green` is equivalent to `chalk.green`.

Multiple arguments will be separated by space.

### chalk.enabled

Color support is automatically detected, as is the level (see `chalk.level`). However, if you'd like to simply enable/disable Chalk, you can do so via the `.enabled` property.

Chalk is enabled by default unless explicitly disabled via the constructor or `chalk.level` is `0`.

If you need to change this in a reusable module, create a new instance:

```js
const ctx = new chalk.constructor({enabled: false});
```

### chalk.level

Color support is automatically detected, but you can override it by setting the `level` property. You should however only do this in your own code as it applies globally to all Chalk consumers.

If you need to change this in a reusable module, create a new instance:

```js
const ctx = new chalk.constructor({level: 0});
```

Levels are as follows:

0. All colors disabled
1. Basic color support (16 colors)
2. 256 color support
3. Truecolor support (16 million colors)

### chalk.supportsColor

Detect whether the terminal [supports color](https://github.com/chalk/supports-color). Used internally and handled for you, but exposed for convenience.

Can be overridden by the user with the flags `--color` and `--no-color`. For situations where using `--color` is not possible, add the environment variable `FORCE_COLOR=1` to forcefully enable color or `FORCE_COLOR=0` to forcefully disable. The use of `FORCE_COLOR` overrides all other color support checks.

Explicit 256/Truecolor mode can be enabled using the `--color=256` and `--color=16m` flags, respectively.

## Styles

### Modifiers

- `reset`
- `bold`
- `dim`
- `italic` *(Not widely supported)*
- `underline`
- `inverse`
- `hidden`
- `strikethrough` *(Not widely supported)*
- `visible` (Text is emitted only if enabled)

### Colors

- `black`
- `red`
- `green`
- `yellow`
- `blue` *(On Windows the bright version is used since normal blue is illegible)*
- `magenta`
- `cyan`
- `white`
- `gray` ("bright black")
- `redBright`
- `greenBright`
- `yellowBright`
- `blueBright`
- `magentaBright`
- `cyanBright`
- `whiteBright`

### Background colors

- `bgBlack`
- `bgRed`
- `bgGreen`
- `bgYellow`
- `bgBlue`
- `bgMagenta`
- `bgCyan`
- `bgWhite`
- `bgBlackBright`
- `bgRedBright`
- `bgGreenBright`
- `bgYellowBright`
- `bgBlueBright`
- `bgMagentaBright`
- `bgCyanBright`
- `bgWhiteBright`

## Tagged template literal

Chalk can be used as a [tagged template literal](http://exploringjs.com/es6/ch_template-literals.html#_tagged-template-literals).

```js
const chalk = require('chalk');

const miles = 18;
const calculateFeet = miles => miles * 5280;

console.log(chalk`
  There are {bold 5280 feet} in a mile.
  In {bold ${miles} miles}, there are {green.bold ${calculateFeet(miles)} feet}.
`);
```

Blocks are delimited by an opening curly brace (`{`), a style, some content, and a closing curly brace (`}`).

Template styles are chained exactly like normal Chalk styles. The following two statements are equivalent:

```js
console.log(chalk.bold.rgb(10, 100, 200)('Hello!'));
console.log(chalk`{bold.rgb(10,100,200) Hello!}`);
```

Note that function styles (`rgb()`, `hsl()`, `keyword()`, etc.) may not contain spaces between parameters.

All interpolated values (`` chalk`${foo}` ``) are converted to strings via the `.toString()` method. All curly braces (`{` and `}`) in interpolated value strings are escaped.

## 256 and Truecolor color support

Chalk supports 256 colors and [Truecolor](https://gist.github.com/XVilka/8346728) (16 million colors) on supported terminal apps.

Colors are downsampled from 16 million RGB values to an ANSI color format that is supported by the terminal emulator (or by specifying `{level: n}` as a Chalk option). For example, Chalk configured to run at level 1 (basic color support) will downsample an RGB value of #FF0000 (red) to 31 (ANSI escape for red).

Examples:

- `chalk.hex('#DEADED').underline('Hello, world!')`
- `chalk.keyword('orange')('Some orange text')`
- `chalk.rgb(15, 100, 204).inverse('Hello!')`

Background versions of these models are prefixed with `bg` and the first level of the module capitalized (e.g. `keyword` for foreground colors and `bgKeyword` for background colors).

- `chalk.bgHex('#DEADED').underline('Hello, world!')`
- `chalk.bgKeyword('orange')('Some orange text')`
- `chalk.bgRgb(15, 100, 204).inverse('Hello!')`

The following color models can be used:

- [`rgb`](https://en.wikipedia.org/wiki/RGB_color_model) - Example: `chalk.rgb(255, 136, 0).bold('Orange!')`
- [`hex`](https://en.wikipedia.org/wiki/Web_colors#Hex_triplet) - Example: `chalk.hex('#FF8800').bold('Orange!')`
- [`keyword`](https://www.w3.org/wiki/CSS/Properties/color/keywords) (CSS keywords) - Example: `chalk.keyword('orange').bold('Orange!')`
- [`hsl`](https://en.wikipedia.org/wiki/HSL_and_HSV) - Example: `chalk.hsl(32, 100, 50).bold('Orange!')`
- [`hsv`](https://en.wikipedia.org/wiki/HSL_and_HSV) - Example: `chalk.hsv(32, 100, 100).bold('Orange!')`
- [`hwb`](https://en.wikipedia.org/wiki/HWB_color_model)  - Example: `chalk.hwb(32, 0, 50).bold('Orange!')`
- `ansi16`
- `ansi256`

## Windows

If you're on Windows, do yourself a favor and use [`cmder`](http://cmder.net/) instead of `cmd.exe`.

## Origin story

[colors.js](https://github.com/Marak/colors.js) used to be the most popular string styling module, but it has serious deficiencies like extending `String.prototype` which causes all kinds of [problems](https://github.com/yeoman/yo/issues/68) and the package is unmaintained. Although there are other packages, they either do too much or not enough. Chalk is a clean and focused alternative.

## Related

- [chalk-cli](https://github.com/chalk/chalk-cli) - CLI for this module
- [ansi-styles](https://github.com/chalk/ansi-styles) - ANSI escape codes for styling strings in the terminal
- [supports-color](https://github.com/chalk/supports-color) - Detect whether a terminal supports color
- [strip-ansi](https://github.com/chalk/strip-ansi) - Strip ANSI escape codes
- [strip-ansi-stream](https://github.com/chalk/strip-ansi-stream) - Strip ANSI escape codes from a stream
- [has-ansi](https://github.com/chalk/has-ansi) - Check if a string has ANSI escape codes
- [ansi-regex](https://github.com/chalk/ansi-regex) - Regular expression for matching ANSI escape codes
- [wrap-ansi](https://github.com/chalk/wrap-ansi) - Wordwrap a string with ANSI escape codes
- [slice-ansi](https://github.com/chalk/slice-ansi) - Slice a string with ANSI escape codes
- [color-convert](https://github.com/qix-/color-convert) - Converts colors between different models
- [chalk-animation](https://github.com/bokub/chalk-animation) - Animate strings in the terminal
- [gradient-string](https://github.com/bokub/gradient-string) - Apply color gradients to strings
- [chalk-pipe](https://github.com/LitoMore/chalk-pipe) - Create chalk style schemes with simpler style strings
- [terminal-link](https://github.com/sindresorhus/terminal-link) - Create clickable links in the terminal

## Maintainers

- [Sindre Sorhus](https://github.com/sindresorhus)
- [Josh Junon](https://github.com/qix-)

## License

MIT


code:
'use strict';
const TEMPLATE_REGEX = /(?:\\(u[a-f\d]{4}|x[a-f\d]{2}|.))|(?:\{(~)?(\w+(?:\([^)]*\))?(?:\.\w+(?:\([^)]*\))?)*)(?:[ \t]|(?=\r?\n)))|(\})|((?:.|[\r\n\f])+?)/gi;
const STYLE_REGEX = /(?:^|\.)(\w+)(?:\(([^)]*)\))?/g;
const STRING_REGEX = /^(['"])((?:\\.|(?!\1)[^\\])*)\1$/;
const ESCAPE_REGEX = /\\(u[a-f\d]{4}|x[a-f\d]{2}|.)|([^\\])/gi;

const ESCAPES = new Map([
	['n', '\n'],
	['r', '\r'],
	['t', '\t'],
	['b', '\b'],
	['f', '\f'],
	['v', '\v'],
	['0', '\0'],
	['\\', '\\'],
	['e', '\u001B'],
	['a', '\u0007']
]);

function unescape(c) {
	if ((c[0] === 'u' && c.length === 5) || (c[0] === 'x' && c.length === 3)) {
		return String.fromCharCode(parseInt(c.slice(1), 16));
	}

	return ESCAPES.get(c) || c;
}

function parseArguments(name, args) {
	const results = [];
	const chunks = args.trim().split(/\s*,\s*/g);
	let matches;

	for (const chunk of chunks) {
		if (!isNaN(chunk)) {
			results.push(Number(chunk));
		} else if ((matches = chunk.match(STRING_REGEX))) {
			results.push(matches[2].replace(ESCAPE_REGEX, (m, escape, chr) => escape ? unescape(escape) : chr));
		} else {
			throw new Error(`Invalid Chalk template style argument: ${chunk} (in style '${name}')`);
		}
	}

	return results;
}

function parseStyle(style) {
	STYLE_REGEX.lastIndex = 0;

	const results = [];
	let matches;

	while ((matches = STYLE_REGEX.exec(style)) !== null) {
		const name = matches[1];

		if (matches[2]) {
			const args = parseArguments(name, matches[2]);
			results.push([name].concat(args));
		} else {
			results.push([name]);
		}
	}

	return results;
}

function buildStyle(chalk, styles) {
	const enabled = {};

	for (const layer of styles) {
		for (const style of layer.styles) {
			enabled[style[0]] = layer.inverse ? null : style.slice(1);
		}
	}

	let current = chalk;
	for (const styleName of Object.keys(enabled)) {
		if (Array.isArray(enabled[styleName])) {
			if (!(styleName in current)) {
				throw new Error(`Unknown Chalk style: ${styleName}`);
			}

			if (enabled[styleName].length > 0) {
				current = current[styleName].apply(current, enabled[styleName]);
			} else {
				current = current[styleName];
			}
		}
	}

	return current;
}

module.exports = (chalk, tmp) => {
	const styles = [];
	const chunks = [];
	let chunk = [];

	// eslint-disable-next-line max-params
	tmp.replace(TEMPLATE_REGEX, (m, escapeChar, inverse, style, close, chr) => {
		if (escapeChar) {
			chunk.push(unescape(escapeChar));
		} else if (style) {
			const str = chunk.join('');
			chunk = [];
			chunks.push(styles.length === 0 ? str : buildStyle(chalk, styles)(str));
			styles.push({inverse, styles: parseStyle(style)});
		} else if (close) {
			if (styles.length === 0) {
				throw new Error('Found extraneous } in Chalk template literal');
			}

			chunks.push(buildStyle(chalk, styles)(chunk.join('')));
			chunk = [];
			styles.pop();
		} else {
			chunk.push(chr);
		}
	});

	chunks.push(chunk.join(''));

	if (styles.length > 0) {
		const errMsg = `Chalk template literal is missing ${styles.length} closing bracket${styles.length === 1 ? '' : 's'} (\`}\`)`;
		throw new Error(errMsg);
	}

	return chunks.join('');
};


code:
// Type definitions for Chalk
// Definitions by: Thomas Sauer <https://github.com/t-sauer>

export const enum Level {
	None = 0,
	Basic = 1,
	Ansi256 = 2,
	TrueColor = 3
}

export interface ChalkOptions {
	enabled?: boolean;
	level?: Level;
}

export interface ChalkConstructor {
	new (options?: ChalkOptions): Chalk;
	(options?: ChalkOptions): Chalk;
}

export interface ColorSupport {
	level: Level;
	hasBasic: boolean;
	has256: boolean;
	has16m: boolean;
}

export interface Chalk {
	(...text: string[]): string;
	(text: TemplateStringsArray, ...placeholders: string[]): string;
	constructor: ChalkConstructor;
	enabled: boolean;
	level: Level;
	rgb(r: number, g: number, b: number): this;
	hsl(h: number, s: number, l: number): this;
	hsv(h: number, s: number, v: number): this;
	hwb(h: number, w: number, b: number): this;
	bgHex(color: string): this;
	bgKeyword(color: string): this;
	bgRgb(r: number, g: number, b: number): this;
	bgHsl(h: number, s: number, l: number): this;
	bgHsv(h: number, s: number, v: number): this;
	bgHwb(h: number, w: number, b: number): this;
	hex(color: string): this;
	keyword(color: string): this;

	readonly reset: this;
	readonly bold: this;
	readonly dim: this;
	readonly italic: this;
	readonly underline: this;
	readonly inverse: this;
	readonly hidden: this;
	readonly strikethrough: this;

	readonly visible: this;

	readonly black: this;
	readonly red: this;
	readonly green: this;
	readonly yellow: this;
	readonly blue: this;
	readonly magenta: this;
	readonly cyan: this;
	readonly white: this;
	readonly gray: this;
	readonly grey: this;
	readonly blackBright: this;
	readonly redBright: this;
	readonly greenBright: this;
	readonly yellowBright: this;
	readonly blueBright: this;
	readonly magentaBright: this;
	readonly cyanBright: this;
	readonly whiteBright: this;

	readonly bgBlack: this;
	readonly bgRed: this;
	readonly bgGreen: this;
	readonly bgYellow: this;
	readonly bgBlue: this;
	readonly bgMagenta: this;
	readonly bgCyan: this;
	readonly bgWhite: this;
	readonly bgBlackBright: this;
	readonly bgRedBright: this;
	readonly bgGreenBright: this;
	readonly bgYellowBright: this;
	readonly bgBlueBright: this;
	readonly bgMagentaBright: this;
	readonly bgCyanBright: this;
	readonly bgWhiteBright: this;
}

declare const chalk: Chalk & { supportsColor: ColorSupport };

export default chalk


code:
    Simple yet flexible JavaScript charting for designers & developers

## Documentation

All the links point to the new version 4 of the lib.

* [Introduction](https://www.chartjs.org/docs/latest/)
* [Getting Started](https://www.chartjs.org/docs/latest/getting-started/index)
* [General](https://www.chartjs.org/docs/latest/general/data-structures)
* [Configuration](https://www.chartjs.org/docs/latest/configuration/index)
* [Charts](https://www.chartjs.org/docs/latest/charts/line)
* [Axes](https://www.chartjs.org/docs/latest/axes/index)
* [Developers](https://www.chartjs.org/docs/latest/developers/index)
* [Popular Extensions](https://github.com/chartjs/awesome)
* [Samples](https://www.chartjs.org/samples/)

In case you are looking for an older version of the docs, you will have to specify the specific version in the url like this: [https://www.chartjs.org/docs/2.9.4/](https://www.chartjs.org/docs/2.9.4/)

## Contributing

Instructions on building and testing Chart.js can be found in [the documentation](https://www.chartjs.org/docs/master/developers/contributing.html#building-and-testing). Before submitting an issue or a pull request, please take a moment to look over the [contributing guidelines](https://www.chartjs.org/docs/master/developers/contributing) first. For support, please post questions on [Stack Overflow](https://stackoverflow.com/questions/tagged/chart.js) with the `chart.js` tag.

## License

Chart.js is available under the [MIT license](LICENSE.md).


code:
const chartjs = require('../dist/chart.cjs');
const {Chart, registerables} = chartjs;

Chart.register(...registerables);

module.exports = Object.assign(Chart, chartjs);


code:
import {Chart} from '../dist/types.js';

export * from '../dist/types.js';
export default Chart;


code:
import {Chart, registerables} from '../dist/chart.js';

Chart.register(...registerables);

export * from '../dist/chart.js';
export default Chart;


chart.js-auto

description: Auto registering package. Exists to support bundlers without exports support such as webpack 4.

type: module