code:
# js-queue Is Great for any queue

1. socket message queuing
2. async operations
3. synchronous operations
4. atomic operations
3. code with requirements before executing
4. queues you want to start running any time you add new items
5. any simple or complex queue operations
6. base class to extend
7. anything else that needs a queue
8. Anything which needs a stack instead of a queue.

# Stable and easy to use
Works great in node.js, webpack, browserify, or any other commonjs loader or compiler. To use in plain old vanilla browser javascript without common js just replace the requires in the examples with script tags. We show that below too.

` js-queue ` also exposes the ` easy-stack ` stack via ` require('js-queue/stack.js') ` this file exposes an ES6 stack which allows for Last In First Out (LIFO) queuing. This can come in handy depending on your application needs, check out the [easy-stack javascript documentation](https://github.com/RIAEvangelist/easy-stack) it follows the ` js-queue ` interface but is node 6 or greater as it uses ES6 classes.

**npm install js-queue**

npm info :  [See npm trends and stats for js-queue](http://npm-stat.com/charts.html?package=@node-ipc/js-queue&author=&from=&to=)
![js-queue npm version](https://img.shields.io/npm/v/js-queue.svg) ![supported node version for js-queue](https://img.shields.io/node/v/js-queue.svg) ![total npm downloads for js-queue](https://img.shields.io/npm/dt/js-queue.svg) ![monthly npm downloads for @node-ipc/js-queue](https://img.shields.io/npm/dm/@node-ipc/js-queue.svg) ![npm licence for @node-ipc/js-queue](https://img.shields.io/npm/l/@node-ipc/js-queue.svg)

GitHub info :
![js-queue GitHub Release](https://img.shields.io/github/release/node-ipc/js-queue.svg) ![GitHub license js-queue license](https://img.shields.io/github/license/node-ipc/js-queue.svg) ![open issues for js-queue on GitHub](https://img.shields.io/github/issues/node-ipc/js-queue.svg)

Package details websites :
* [GitHub.io site](http://node-ipc.github.io/js-queue/ "js-queue documentation"). A prettier version of this site.
* [NPM Module](https://www.npmjs.org/package/@node-ipc/js-queue "js-queue npm module"). The npm page for the js-queue module.

This work is licenced via the MIT Licence.

## Exposed methods and values

|key|type|paramaters|default|description|
|----|----|----|----|----|
|add|function|any number of functions|  |adds all parameter functions to queue and starts execution if autoRun is true, queue is not already running and queue is not forcibly stopped |
|next|function|  |  |executes next item in queue if queue is not forcibly stopped|
|clear|function|  |  |removes remaining items in the queue|
|contents|Array|  |  | Queue instance contents |
|autoRun|Bool|  | true |should autoRun queue when new item added|
|stop|Bool|  | false |setting this to true will forcibly prevent the queue from executing|

### Basic queue use in node, react, browserify, webpack or any other commonjs implementation

```javascript

    var Queue=require('js-queue');
    //create a new queue instance
    var queue=new Queue;

    for(var i=0; i<50; i++){
        //add a bunch of stuff to the queue
        queue.add(makeRequest);
    }

    function makeRequest(){
        //do stuff
        console.log('making some request');

        this.next();
    }

```

### Basic browser use

The only difference is including via a script tag instead of using require.

```html

    <html>
            <head>
                    <!-- this is the only difference -->
                    <script src='./queue-vanilla.js'></script>
                    <script>
                            console.log('my awesome app script');
                            var queue=new Queue;

                            for(var i=0; i<50; i++){
                                queue.add(makeRequest);
                            }

                            function makeRequest(){
                                console.log('making some request');

                                this.next();
                            }
                    </script>
            </head>
            <body>
            </body>
    </html>

```

### Basic use with websockets in node, react, browserify, webpack or any other commonjs implementation

This allows you to start adding requests immediately and only execute if the websocket is connected. To use in plain browser based JS without webpack or browserify just replace the requires with the script tag.

```javascript

    var Queue=require('js-queue');

    //ws-share just makes it easier to share websocket code and ensure you don't open a websocket more than once
    var WS=require('ws-share');

    //js-message makes it easy to create and parse normalized JSON messages.
    var Message=require('js-message');

    //create a new queue instance
    var queue=new Queue;

    //force stop until websocket opened
    queue.stop=true;

    var ws=null;

    function startWS(){
        //websocket.org rocks
        ws=new WS('wss://echo.websocket.org/?encoding=text');

        ws.on(
            'open',
            function(){
                ws.on(
                    'message',
                    handleResponse
                );

                //now that websocket is opened allow auto execution
                queue.stop=false;
                queue.next();
            }
        );

        ws.on(
            'error',
            function(err){
                //stop execution of queue if there is an error because the websocket is likely closed
                queue.stop=true;
                //remove remaining items in the queue
                queue.clear();
                throw(err);
            }
        );

        ws.on(
            'close',
            function(){
                //stop execution of queue when the websocket closed
                queue.stop=true;
            }
        );
    }

    //simulate a lot of requests being queued up for the websocket
    for(var i=0; i<50; i++){
        queue.add(makeRequest);
    }

    var messageID=0;

    function handleResponse(e){
        var message=new Message;
        message.load(e.data);

        console.log(message.type,message.data);
    }

    function makeRequest(){
        messageID++;
        var message=new Message;
        message.type='testMessage';
        message.data=messageID;

        ws.send(message.JSON);

        this.next();
    }

    startWS();

```

# Extending Queue

```javascript

    var Queue=require('js-queue');

    //MyAwesomeQueue inherits from Queue
    MyAwesomeQueue.prototype = new Queue;
    //Constructor will extend Queue
    MyAwesomeQueue.prototype.constructor = MyAwesomeQueue;

    function MyAwesomeQueue(){
        //extend with some stuff your app needs,
        //maybe npm publish your extention with js-queue as a dependancy?
        Object.defineProperties(
            this,
            {
                isStopped:{
                    enumerable:true,
                    get:checkStopped,
                    set:checkStopped
                },
                removeThirdItem:{
                    enumerable:true,
                    writable:false,
                    value:removeThird
                }
            }
        );

        //enforce Object.assign for extending by locking down Class structure
        //no willy nilly cowboy coding
        Object.seal(this);

        function checkStopped(){
            return this.stop;
        }

        function removeThird(){
            //get the queue content
            var list=this.contents;
            //modify the queue content
            list.splice(2,1);
            //save the modified queue content
            this.contents=list;

            return this.contents;
        }
    }

```


code:
MIT License

Copyright (c) 2020 Brandon Nozaki Miller

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.

license: mit


@node-ipc/js-queue

description: Simple JS queue with auto run for node and browsers

test: echo "Error: no test specified" && exit 1

type: git

keywords: queue node js auto run execute browser react

author: Brandon Nozaki Miller

license: MIT


code:
function Queue(){
    Object.defineProperties(
        this,
        {
            add:{
                enumerable:true,
                writable:false,
                value:addToQueue
            },
            next:{
                enumerable:true,
                writable:false,
                value:run
            },
            clear:{
                enumerable:true,
                writable:false,
                value:clearQueue
            },
            contents:{
                enumerable:false,
                get:getQueue,
                set:setQueue
            },
            autoRun:{
                enumerable:true,
                writable:true,
                value:true
            },
            stop:{
                enumerable:true,
                writable:true,
                value:false
            }
        }
    );

    var queue=[];
    var running=false;
    var stop=false;

    function clearQueue(){
        queue=[];
        return queue;
    }

    function getQueue(){
        return queue;
    }

    function setQueue(val){
        queue=val;
        return queue;
    }

    function addToQueue(){
        for(var i in arguments){
            queue.push(arguments[i]);
        }
        if(!running && !this.stop && this.autoRun){
            this.next();
        }
    }

    function run(){
        running=true;
        if(queue.length<1 || this.stop){
            running=false;
            return;
        }

        queue.shift().bind(this)();
    }
}


code:
function Queue(asStack){
    Object.defineProperties(
        this,
        {
            add:{
                enumerable:true,
                writable:false,
                value:addToQueue
            },
            next:{
                enumerable:true,
                writable:false,
                value:run
            },
            clear:{
                enumerable:true,
                writable:false,
                value:clearQueue
            },
            contents:{
                enumerable:false,
                get:getQueue,
                set:setQueue
            },
            autoRun:{
                enumerable:true,
                writable:true,
                value:true
            },
            stop:{
                enumerable:true,
                writable:true,
                value:false
            }
        }
    );

    var queue=[];
    var running=false;
    var stop=false;

    function clearQueue(){
        queue=[];
        return queue;
    }

    function getQueue(){
        return queue;
    }

    function setQueue(val){
        queue=val;
        return queue;
    }

    function addToQueue(){
        for(var i in arguments){
            queue.push(arguments[i]);
        }
        if(!running && !this.stop && this.autoRun){
            this.next();
        }
    }

    function run(){
        running=true;
        if(queue.length<1 || this.stop){
            running=false;
            return;
        }

        queue.shift().bind(this)();
    }
}

module.exports=Queue;


code:
const Stack=require('easy-stack');

module.exports = Stack;


code:
# @nodelib/fs.scandir

> List files and directories inside the specified directory.

## :bulb: Highlights

The package is aimed at obtaining information about entries in the directory.

* :moneybag: Returns useful information: `name`, `path`, `dirent` and `stats` (optional).
* :gear: On Node.js 10.10+ uses the mechanism without additional calls to determine the entry type. See [`old` and `modern` mode](#old-and-modern-mode).
* :link: Can safely work with broken symbolic links.

## Install

```console
npm install @nodelib/fs.scandir
```

## Usage

```ts
import * as fsScandir from '@nodelib/fs.scandir';

fsScandir.scandir('path', (error, stats) => { /* … */ });
```

## API

### .scandir(path, [optionsOrSettings], callback)

Returns an array of plain objects ([`Entry`](#entry)) with information about entry for provided path with standard callback-style.

```ts
fsScandir.scandir('path', (error, entries) => { /* … */ });
fsScandir.scandir('path', {}, (error, entries) => { /* … */ });
fsScandir.scandir('path', new fsScandir.Settings(), (error, entries) => { /* … */ });
```

### .scandirSync(path, [optionsOrSettings])

Returns an array of plain objects ([`Entry`](#entry)) with information about entry for provided path.

```ts
const entries = fsScandir.scandirSync('path');
const entries = fsScandir.scandirSync('path', {});
const entries = fsScandir.scandirSync(('path', new fsScandir.Settings());
```

#### path

* Required: `true`
* Type: `string | Buffer | URL`

A path to a file. If a URL is provided, it must use the `file:` protocol.

#### optionsOrSettings

* Required: `false`
* Type: `Options | Settings`
* Default: An instance of `Settings` class

An [`Options`](#options) object or an instance of [`Settings`](#settingsoptions) class.

> :book: When you pass a plain object, an instance of the `Settings` class will be created automatically. If you plan to call the method frequently, use a pre-created instance of the `Settings` class.

### Settings([options])

A class of full settings of the package.

```ts
const settings = new fsScandir.Settings({ followSymbolicLinks: false });

const entries = fsScandir.scandirSync('path', settings);
```

## Entry

* `name` — The name of the entry (`unknown.txt`).
* `path` — The path of the entry relative to call directory (`root/unknown.txt`).
* `dirent` — An instance of [`fs.Dirent`](./src/types/index.ts) class. On Node.js below 10.10 will be emulated by [`DirentFromStats`](./src/utils/fs.ts) class.
* `stats` (optional) — An instance of `fs.Stats` class.

For example, the `scandir` call for `tools` directory with one directory inside:

```ts
{
	dirent: Dirent { name: 'typedoc', /* … */ },
	name: 'typedoc',
	path: 'tools/typedoc'
}
```

## Options

### stats

* Type: `boolean`
* Default: `false`

Adds an instance of `fs.Stats` class to the [`Entry`](#entry).

> :book: Always use `fs.readdir` without the `withFileTypes` option. ??TODO??

### followSymbolicLinks

* Type: `boolean`
* Default: `false`

Follow symbolic links or not. Call `fs.stat` on symbolic link if `true`.

### `throwErrorOnBrokenSymbolicLink`

* Type: `boolean`
* Default: `true`

Throw an error when symbolic link is broken if `true` or safely use `lstat` call if `false`.

### `pathSegmentSeparator`

* Type: `string`
* Default: `path.sep`

By default, this package uses the correct path separator for your OS (`\` on Windows, `/` on Unix-like systems). But you can set this option to any separator character(s) that you want to use instead.

### `fs`

* Type: [`FileSystemAdapter`](./src/adapters/fs.ts)
* Default: A default FS methods

By default, the built-in Node.js module (`fs`) is used to work with the file system. You can replace any method with your own.

```ts
interface FileSystemAdapter {
	lstat?: typeof fs.lstat;
	stat?: typeof fs.stat;
	lstatSync?: typeof fs.lstatSync;
	statSync?: typeof fs.statSync;
	readdir?: typeof fs.readdir;
	readdirSync?: typeof fs.readdirSync;
}

const settings = new fsScandir.Settings({
	fs: { lstat: fakeLstat }
});
```

## `old` and `modern` mode

This package has two modes that are used depending on the environment and parameters of use.

### old

* Node.js below `10.10` or when the `stats` option is enabled

When working in the old mode, the directory is read first (`fs.readdir`), then the type of entries is determined (`fs.lstat` and/or `fs.stat` for symbolic links).

### modern

* Node.js 10.10+ and the `stats` option is disabled

In the modern mode, reading the directory (`fs.readdir` with the `withFileTypes` option) is combined with obtaining information about its entries. An additional call for symbolic links (`fs.stat`) is still present.

This mode makes fewer calls to the file system. It's faster.

## Changelog

See the [Releases section of our GitHub project](https://github.com/nodelib/nodelib/releases) for changelog for each release version.

## License

This software is released under the terms of the MIT license.


code:
import type * as fsStat from '@nodelib/fs.stat';
import type { Dirent, ErrnoException } from '../types';
export interface ReaddirAsynchronousMethod {
    (filepath: string, options: {
        withFileTypes: true;
    }, callback: (error: ErrnoException | null, files: Dirent[]) => void): void;
    (filepath: string, callback: (error: ErrnoException | null, files: string[]) => void): void;
}
export interface ReaddirSynchronousMethod {
    (filepath: string, options: {
        withFileTypes: true;
    }): Dirent[];
    (filepath: string): string[];
}
export declare type FileSystemAdapter = fsStat.FileSystemAdapter & {
    readdir: ReaddirAsynchronousMethod;
    readdirSync: ReaddirSynchronousMethod;
};
export declare const FILE_SYSTEM_ADAPTER: FileSystemAdapter;
export declare function createFileSystemAdapter(fsMethods?: Partial<FileSystemAdapter>): FileSystemAdapter;


code:
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createFileSystemAdapter = exports.FILE_SYSTEM_ADAPTER = void 0;
const fs = require("fs");
exports.FILE_SYSTEM_ADAPTER = {
    lstat: fs.lstat,
    stat: fs.stat,
    lstatSync: fs.lstatSync,
    statSync: fs.statSync,
    readdir: fs.readdir,
    readdirSync: fs.readdirSync
};
function createFileSystemAdapter(fsMethods) {
    if (fsMethods === undefined) {
        return exports.FILE_SYSTEM_ADAPTER;
    }
    return Object.assign(Object.assign({}, exports.FILE_SYSTEM_ADAPTER), fsMethods);
}
exports.createFileSystemAdapter = createFileSystemAdapter;


code:
/**
 * IS `true` for Node.js 10.10 and greater.
 */
export declare const IS_SUPPORT_READDIR_WITH_FILE_TYPES: boolean;


code:
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.IS_SUPPORT_READDIR_WITH_FILE_TYPES = void 0;
const NODE_PROCESS_VERSION_PARTS = process.versions.node.split('.');
if (NODE_PROCESS_VERSION_PARTS[0] === undefined || NODE_PROCESS_VERSION_PARTS[1] === undefined) {
    throw new Error(`Unexpected behavior. The 'process.versions.node' variable has invalid value: ${process.versions.node}`);
}
const MAJOR_VERSION = Number.parseInt(NODE_PROCESS_VERSION_PARTS[0], 10);
const MINOR_VERSION = Number.parseInt(NODE_PROCESS_VERSION_PARTS[1], 10);
const SUPPORTED_MAJOR_VERSION = 10;
const SUPPORTED_MINOR_VERSION = 10;
const IS_MATCHED_BY_MAJOR = MAJOR_VERSION > SUPPORTED_MAJOR_VERSION;
const IS_MATCHED_BY_MAJOR_AND_MINOR = MAJOR_VERSION === SUPPORTED_MAJOR_VERSION && MINOR_VERSION >= SUPPORTED_MINOR_VERSION;
/**
 * IS `true` for Node.js 10.10 and greater.
 */
exports.IS_SUPPORT_READDIR_WITH_FILE_TYPES = IS_MATCHED_BY_MAJOR || IS_MATCHED_BY_MAJOR_AND_MINOR;


code:
import type { FileSystemAdapter, ReaddirAsynchronousMethod, ReaddirSynchronousMethod } from './adapters/fs';
import * as async from './providers/async';
import Settings, { Options } from './settings';
import type { Dirent, Entry } from './types';
declare type AsyncCallback = async.AsyncCallback;
declare function scandir(path: string, callback: AsyncCallback): void;
declare function scandir(path: string, optionsOrSettings: Options | Settings, callback: AsyncCallback): void;
declare namespace scandir {
    function __promisify__(path: string, optionsOrSettings?: Options | Settings): Promise<Entry[]>;
}
declare function scandirSync(path: string, optionsOrSettings?: Options | Settings): Entry[];
export { scandir, scandirSync, Settings, AsyncCallback, Dirent, Entry, FileSystemAdapter, ReaddirAsynchronousMethod, ReaddirSynchronousMethod, Options };


code:
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Settings = exports.scandirSync = exports.scandir = void 0;
const async = require("./providers/async");
const sync = require("./providers/sync");
const settings_1 = require("./settings");
exports.Settings = settings_1.default;
function scandir(path, optionsOrSettingsOrCallback, callback) {
    if (typeof optionsOrSettingsOrCallback === 'function') {
        async.read(path, getSettings(), optionsOrSettingsOrCallback);
        return;
    }
    async.read(path, getSettings(optionsOrSettingsOrCallback), callback);
}
exports.scandir = scandir;
function scandirSync(path, optionsOrSettings) {
    const settings = getSettings(optionsOrSettings);
    return sync.read(path, settings);
}
exports.scandirSync = scandirSync;
function getSettings(settingsOrOptions = {}) {
    if (settingsOrOptions instanceof settings_1.default) {
        return settingsOrOptions;
    }
    return new settings_1.default(settingsOrOptions);
}


code:
/// <reference types="node" />
import type Settings from '../settings';
import type { Entry } from '../types';
export declare type AsyncCallback = (error: NodeJS.ErrnoException, entries: Entry[]) => void;
export declare function read(directory: string, settings: Settings, callback: AsyncCallback): void;
export declare function readdirWithFileTypes(directory: string, settings: Settings, callback: AsyncCallback): void;
export declare function readdir(directory: string, settings: Settings, callback: AsyncCallback): void;


code:
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.readdir = exports.readdirWithFileTypes = exports.read = void 0;
const fsStat = require("@nodelib/fs.stat");
const rpl = require("run-parallel");
const constants_1 = require("../constants");
const utils = require("../utils");
const common = require("./common");
function read(directory, settings, callback) {
    if (!settings.stats && constants_1.IS_SUPPORT_READDIR_WITH_FILE_TYPES) {
        readdirWithFileTypes(directory, settings, callback);
        return;
    }
    readdir(directory, settings, callback);
}
exports.read = read;
function readdirWithFileTypes(directory, settings, callback) {
    settings.fs.readdir(directory, { withFileTypes: true }, (readdirError, dirents) => {
        if (readdirError !== null) {
            callFailureCallback(callback, readdirError);
            return;
        }
        const entries = dirents.map((dirent) => ({
            dirent,
            name: dirent.name,
            path: common.joinPathSegments(directory, dirent.name, settings.pathSegmentSeparator)
        }));
        if (!settings.followSymbolicLinks) {
            callSuccessCallback(callback, entries);
            return;
        }
        const tasks = entries.map((entry) => makeRplTaskEntry(entry, settings));
        rpl(tasks, (rplError, rplEntries) => {
            if (rplError !== null) {
                callFailureCallback(callback, rplError);
                return;
            }
            callSuccessCallback(callback, rplEntries);
        });
    });
}
exports.readdirWithFileTypes = readdirWithFileTypes;
function makeRplTaskEntry(entry, settings) {
    return (done) => {
        if (!entry.dirent.isSymbolicLink()) {
            done(null, entry);
            return;
        }
        settings.fs.stat(entry.path, (statError, stats) => {
            if (statError !== null) {
                if (settings.throwErrorOnBrokenSymbolicLink) {
                    done(statError);
                    return;
                }
                done(null, entry);
                return;
            }
            entry.dirent = utils.fs.createDirentFromStats(entry.name, stats);
            done(null, entry);
        });
    };
}
function readdir(directory, settings, callback) {
    settings.fs.readdir(directory, (readdirError, names) => {
        if (readdirError !== null) {
            callFailureCallback(callback, readdirError);
            return;
        }
        const tasks = names.map((name) => {
            const path = common.joinPathSegments(directory, name, settings.pathSegmentSeparator);
            return (done) => {
                fsStat.stat(path, settings.fsStatSettings, (error, stats) => {
                    if (error !== null) {
                        done(error);
                        return;
                    }
                    const entry = {
                        name,
                        path,
                        dirent: utils.fs.createDirentFromStats(name, stats)
                    };
                    if (settings.stats) {
                        entry.stats = stats;
                    }
                    done(null, entry);
                });
            };
        });
        rpl(tasks, (rplError, entries) => {
            if (rplError !== null) {
                callFailureCallback(callback, rplError);
                return;
            }
            callSuccessCallback(callback, entries);
        });
    });
}
exports.readdir = readdir;
function callFailureCallback(callback, error) {
    callback(error);
}
function callSuccessCallback(callback, result) {
    callback(null, result);
}


code: export declare function joinPathSegments(a: string, b: string, separator: string): string;


code:
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.joinPathSegments = void 0;
function joinPathSegments(a, b, separator) {
    /**
     * The correct handling of cases when the first segment is a root (`/`, `C:/`) or UNC path (`//?/C:/`).
     */
    if (a.endsWith(separator)) {
        return a + b;
    }
    return a + separator + b;
}
exports.joinPathSegments = joinPathSegments;


code:
import type Settings from '../settings';
import type { Entry } from '../types';
export declare function read(directory: string, settings: Settings): Entry[];
export declare function readdirWithFileTypes(directory: string, settings: Settings): Entry[];
export declare function readdir(directory: string, settings: Settings): Entry[];


code:
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.readdir = exports.readdirWithFileTypes = exports.read = void 0;
const fsStat = require("@nodelib/fs.stat");
const constants_1 = require("../constants");
const utils = require("../utils");
const common = require("./common");
function read(directory, settings) {
    if (!settings.stats && constants_1.IS_SUPPORT_READDIR_WITH_FILE_TYPES) {
        return readdirWithFileTypes(directory, settings);
    }
    return readdir(directory, settings);
}
exports.read = read;
function readdirWithFileTypes(directory, settings) {
    const dirents = settings.fs.readdirSync(directory, { withFileTypes: true });
    return dirents.map((dirent) => {
        const entry = {
            dirent,
            name: dirent.name,
            path: common.joinPathSegments(directory, dirent.name, settings.pathSegmentSeparator)
        };
        if (entry.dirent.isSymbolicLink() && settings.followSymbolicLinks) {
            try {
                const stats = settings.fs.statSync(entry.path);
                entry.dirent = utils.fs.createDirentFromStats(entry.name, stats);
            }
            catch (error) {
                if (settings.throwErrorOnBrokenSymbolicLink) {
                    throw error;
                }
            }
        }
        return entry;
    });
}
exports.readdirWithFileTypes = readdirWithFileTypes;
function readdir(directory, settings) {
    const names = settings.fs.readdirSync(directory);
    return names.map((name) => {
        const entryPath = common.joinPathSegments(directory, name, settings.pathSegmentSeparator);
        const stats = fsStat.statSync(entryPath, settings.fsStatSettings);
        const entry = {
            name,
            path: entryPath,
            dirent: utils.fs.createDirentFromStats(name, stats)
        };
        if (settings.stats) {
            entry.stats = stats;
        }
        return entry;
    });
}
exports.readdir = readdir;


code:
import * as fsStat from '@nodelib/fs.stat';
import * as fs from './adapters/fs';
export interface Options {
    followSymbolicLinks?: boolean;
    fs?: Partial<fs.FileSystemAdapter>;
    pathSegmentSeparator?: string;
    stats?: boolean;
    throwErrorOnBrokenSymbolicLink?: boolean;
}
export default class Settings {
    private readonly _options;
    readonly followSymbolicLinks: boolean;
    readonly fs: fs.FileSystemAdapter;
    readonly pathSegmentSeparator: string;
    readonly stats: boolean;
    readonly throwErrorOnBrokenSymbolicLink: boolean;
    readonly fsStatSettings: fsStat.Settings;
    constructor(_options?: Options);
    private _getValue;
}


code:
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const path = require("path");
const fsStat = require("@nodelib/fs.stat");
const fs = require("./adapters/fs");
class Settings {
    constructor(_options = {}) {
        this._options = _options;
        this.followSymbolicLinks = this._getValue(this._options.followSymbolicLinks, false);
        this.fs = fs.createFileSystemAdapter(this._options.fs);
        this.pathSegmentSeparator = this._getValue(this._options.pathSegmentSeparator, path.sep);
        this.stats = this._getValue(this._options.stats, false);
        this.throwErrorOnBrokenSymbolicLink = this._getValue(this._options.throwErrorOnBrokenSymbolicLink, true);
        this.fsStatSettings = new fsStat.Settings({
            followSymbolicLink: this.followSymbolicLinks,
            fs: this.fs,
            throwErrorOnBrokenSymbolicLink: this.throwErrorOnBrokenSymbolicLink
        });
    }
    _getValue(option, value) {
        return option !== null && option !== void 0 ? option : value;
    }
}
exports.default = Settings;


code:
/// <reference types="node" />
import type * as fs from 'fs';
export interface Entry {
    dirent: Dirent;
    name: string;
    path: string;
    stats?: Stats;
}
export declare type Stats = fs.Stats;
export declare type ErrnoException = NodeJS.ErrnoException;
export interface Dirent {
    isBlockDevice: () => boolean;
    isCharacterDevice: () => boolean;
    isDirectory: () => boolean;
    isFIFO: () => boolean;
    isFile: () => boolean;
    isSocket: () => boolean;
    isSymbolicLink: () => boolean;
    name: string;
}


code:
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });


code:
import type { Dirent, Stats } from '../types';
export declare function createDirentFromStats(name: string, stats: Stats): Dirent;


code:
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createDirentFromStats = void 0;
class DirentFromStats {
    constructor(name, stats) {
        this.name = name;
        this.isBlockDevice = stats.isBlockDevice.bind(stats);
        this.isCharacterDevice = stats.isCharacterDevice.bind(stats);
        this.isDirectory = stats.isDirectory.bind(stats);
        this.isFIFO = stats.isFIFO.bind(stats);
        this.isFile = stats.isFile.bind(stats);
        this.isSocket = stats.isSocket.bind(stats);
        this.isSymbolicLink = stats.isSymbolicLink.bind(stats);
    }
}
function createDirentFromStats(name, stats) {
    return new DirentFromStats(name, stats);
}
exports.createDirentFromStats = createDirentFromStats;


code:
import * as fs from './fs';
export { fs };


code:
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.fs = void 0;
const fs = require("./fs");
exports.fs = fs;


@nodelib/fs.scandir

description: List files and directories inside the specified directory

keywords:
NodeLib
fs
FileSystem
file system
scandir
readdir
dirent

clean: rimraf {tsconfig.tsbuildinfo,out}

lint: eslint "src/**/*.ts" --cache

compile: tsc -b .

compile:watch: tsc -p . --watch --sourceMap

test: mocha "out/**/*.spec.js" -s 0

build: npm run clean && npm run compile && npm run lint && npm test

watch: npm run clean && npm run compile:watch


code:
# @nodelib/fs.stat

> Get the status of a file with some features.

## :bulb: Highlights

Wrapper around standard method `fs.lstat` and `fs.stat` with some features.

* :beginner: Normally follows symbolic link.
* :gear: Can safely work with broken symbolic link.

## Install

```console
npm install @nodelib/fs.stat
```

## Usage

```ts
import * as fsStat from '@nodelib/fs.stat';

fsStat.stat('path', (error, stats) => { /* … */ });
```

## API

### .stat(path, [optionsOrSettings], callback)

Returns an instance of `fs.Stats` class for provided path with standard callback-style.

```ts
fsStat.stat('path', (error, stats) => { /* … */ });
fsStat.stat('path', {}, (error, stats) => { /* … */ });
fsStat.stat('path', new fsStat.Settings(), (error, stats) => { /* … */ });
```

### .statSync(path, [optionsOrSettings])

Returns an instance of `fs.Stats` class for provided path.

```ts
const stats = fsStat.stat('path');
const stats = fsStat.stat('path', {});
const stats = fsStat.stat('path', new fsStat.Settings());
```

#### path

* Required: `true`
* Type: `string | Buffer | URL`

A path to a file. If a URL is provided, it must use the `file:` protocol.

#### optionsOrSettings

* Required: `false`
* Type: `Options | Settings`
* Default: An instance of `Settings` class

An [`Options`](#options) object or an instance of [`Settings`](#settings) class.

> :book: When you pass a plain object, an instance of the `Settings` class will be created automatically. If you plan to call the method frequently, use a pre-created instance of the `Settings` class.

### Settings([options])

A class of full settings of the package.

```ts
const settings = new fsStat.Settings({ followSymbolicLink: false });

const stats = fsStat.stat('path', settings);
```

## Options

### `followSymbolicLink`

* Type: `boolean`
* Default: `true`

Follow symbolic link or not. Call `fs.stat` on symbolic link if `true`.

### `markSymbolicLink`

* Type: `boolean`
* Default: `false`

Mark symbolic link by setting the return value of `isSymbolicLink` function to always `true` (even after `fs.stat`).

> :book: Can be used if you want to know what is hidden behind a symbolic link, but still continue to know that it is a symbolic link.

### `throwErrorOnBrokenSymbolicLink`

* Type: `boolean`
* Default: `true`

Throw an error when symbolic link is broken if `true` or safely return `lstat` call if `false`.

### `fs`

* Type: [`FileSystemAdapter`](./src/adapters/fs.ts)
* Default: A default FS methods

By default, the built-in Node.js module (`fs`) is used to work with the file system. You can replace any method with your own.

```ts
interface FileSystemAdapter {
	lstat?: typeof fs.lstat;
	stat?: typeof fs.stat;
	lstatSync?: typeof fs.lstatSync;
	statSync?: typeof fs.statSync;
}

const settings = new fsStat.Settings({
	fs: { lstat: fakeLstat }
});
```

## Changelog

See the [Releases section of our GitHub project](https://github.com/nodelib/nodelib/releases) for changelog for each release version.

## License

This software is released under the terms of the MIT license.


code:
/// <reference types="node" />
import * as fs from 'fs';
import type { ErrnoException } from '../types';
export declare type StatAsynchronousMethod = (path: string, callback: (error: ErrnoException | null, stats: fs.Stats) => void) => void;
export declare type StatSynchronousMethod = (path: string) => fs.Stats;
export interface FileSystemAdapter {
    lstat: StatAsynchronousMethod;
    stat: StatAsynchronousMethod;
    lstatSync: StatSynchronousMethod;
    statSync: StatSynchronousMethod;
}
export declare const FILE_SYSTEM_ADAPTER: FileSystemAdapter;
export declare function createFileSystemAdapter(fsMethods?: Partial<FileSystemAdapter>): FileSystemAdapter;


code:
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createFileSystemAdapter = exports.FILE_SYSTEM_ADAPTER = void 0;
const fs = require("fs");
exports.FILE_SYSTEM_ADAPTER = {
    lstat: fs.lstat,
    stat: fs.stat,
    lstatSync: fs.lstatSync,
    statSync: fs.statSync
};
function createFileSystemAdapter(fsMethods) {
    if (fsMethods === undefined) {
        return exports.FILE_SYSTEM_ADAPTER;
    }
    return Object.assign(Object.assign({}, exports.FILE_SYSTEM_ADAPTER), fsMethods);
}
exports.createFileSystemAdapter = createFileSystemAdapter;


code:
import type { FileSystemAdapter, StatAsynchronousMethod, StatSynchronousMethod } from './adapters/fs';
import * as async from './providers/async';
import Settings, { Options } from './settings';
import type { Stats } from './types';
declare type AsyncCallback = async.AsyncCallback;
declare function stat(path: string, callback: AsyncCallback): void;
declare function stat(path: string, optionsOrSettings: Options | Settings, callback: AsyncCallback): void;
declare namespace stat {
    function __promisify__(path: string, optionsOrSettings?: Options | Settings): Promise<Stats>;
}
declare function statSync(path: string, optionsOrSettings?: Options | Settings): Stats;
export { Settings, stat, statSync, AsyncCallback, FileSystemAdapter, StatAsynchronousMethod, StatSynchronousMethod, Options, Stats };


code:
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.statSync = exports.stat = exports.Settings = void 0;
const async = require("./providers/async");
const sync = require("./providers/sync");
const settings_1 = require("./settings");
exports.Settings = settings_1.default;
function stat(path, optionsOrSettingsOrCallback, callback) {
    if (typeof optionsOrSettingsOrCallback === 'function') {
        async.read(path, getSettings(), optionsOrSettingsOrCallback);
        return;
    }
    async.read(path, getSettings(optionsOrSettingsOrCallback), callback);
}
exports.stat = stat;
function statSync(path, optionsOrSettings) {
    const settings = getSettings(optionsOrSettings);
    return sync.read(path, settings);
}
exports.statSync = statSync;
function getSettings(settingsOrOptions = {}) {
    if (settingsOrOptions instanceof settings_1.default) {
        return settingsOrOptions;
    }
    return new settings_1.default(settingsOrOptions);
}


code:
import type Settings from '../settings';
import type { ErrnoException, Stats } from '../types';
export declare type AsyncCallback = (error: ErrnoException, stats: Stats) => void;
export declare function read(path: string, settings: Settings, callback: AsyncCallback): void;


code:
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.read = void 0;
function read(path, settings, callback) {
    settings.fs.lstat(path, (lstatError, lstat) => {
        if (lstatError !== null) {
            callFailureCallback(callback, lstatError);
            return;
        }
        if (!lstat.isSymbolicLink() || !settings.followSymbolicLink) {
            callSuccessCallback(callback, lstat);
            return;
        }
        settings.fs.stat(path, (statError, stat) => {
            if (statError !== null) {
                if (settings.throwErrorOnBrokenSymbolicLink) {
                    callFailureCallback(callback, statError);
                    return;
                }
                callSuccessCallback(callback, lstat);
                return;
            }
            if (settings.markSymbolicLink) {
                stat.isSymbolicLink = () => true;
            }
            callSuccessCallback(callback, stat);
        });
    });
}
exports.read = read;
function callFailureCallback(callback, error) {
    callback(error);
}
function callSuccessCallback(callback, result) {
    callback(null, result);
}


code:
import type Settings from '../settings';
import type { Stats } from '../types';
export declare function read(path: string, settings: Settings): Stats;


code:
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.read = void 0;
function read(path, settings) {
    const lstat = settings.fs.lstatSync(path);
    if (!lstat.isSymbolicLink() || !settings.followSymbolicLink) {
        return lstat;
    }
    try {
        const stat = settings.fs.statSync(path);
        if (settings.markSymbolicLink) {
            stat.isSymbolicLink = () => true;
        }
        return stat;
    }
    catch (error) {
        if (!settings.throwErrorOnBrokenSymbolicLink) {
            return lstat;
        }
        throw error;
    }
}
exports.read = read;


code:
import * as fs from './adapters/fs';
export interface Options {
    followSymbolicLink?: boolean;
    fs?: Partial<fs.FileSystemAdapter>;
    markSymbolicLink?: boolean;
    throwErrorOnBrokenSymbolicLink?: boolean;
}
export default class Settings {
    private readonly _options;
    readonly followSymbolicLink: boolean;
    readonly fs: fs.FileSystemAdapter;
    readonly markSymbolicLink: boolean;
    readonly throwErrorOnBrokenSymbolicLink: boolean;
    constructor(_options?: Options);
    private _getValue;
}


code:
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const fs = require("./adapters/fs");
class Settings {
    constructor(_options = {}) {
        this._options = _options;
        this.followSymbolicLink = this._getValue(this._options.followSymbolicLink, true);
        this.fs = fs.createFileSystemAdapter(this._options.fs);
        this.markSymbolicLink = this._getValue(this._options.markSymbolicLink, false);
        this.throwErrorOnBrokenSymbolicLink = this._getValue(this._options.throwErrorOnBrokenSymbolicLink, true);
    }
    _getValue(option, value) {
        return option !== null && option !== void 0 ? option : value;
    }
}
exports.default = Settings;


code:
/// <reference types="node" />
import type * as fs from 'fs';
export declare type Stats = fs.Stats;
export declare type ErrnoException = NodeJS.ErrnoException;


code:
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });


@nodelib/fs.stat

description: Get the status of a file with some features

keywords:
NodeLib
fs
FileSystem
file system
stat


code:
# @nodelib/fs.walk

> A library for efficiently walking a directory recursively.

## :bulb: Highlights

* :moneybag: Returns useful information: `name`, `path`, `dirent` and `stats` (optional).
* :rocket: On Node.js 10.10+ uses the mechanism without additional calls to determine the entry type for performance reasons. See [`old` and `modern` mode](https://github.com/nodelib/nodelib/blob/master/packages/fs/fs.scandir/README.md#old-and-modern-mode).
* :gear: Built-in directories/files and error filtering system.
* :link: Can safely work with broken symbolic links.

## Install

```console
npm install @nodelib/fs.walk
```

## Usage

```ts
import * as fsWalk from '@nodelib/fs.walk';

fsWalk.walk('path', (error, entries) => { /* … */ });
```

## API

### .walk(path, [optionsOrSettings], callback)

Reads the directory recursively and asynchronously. Requires a callback function.

> :book: If you want to use the Promise API, use `util.promisify`.

```ts
fsWalk.walk('path', (error, entries) => { /* … */ });
fsWalk.walk('path', {}, (error, entries) => { /* … */ });
fsWalk.walk('path', new fsWalk.Settings(), (error, entries) => { /* … */ });
```

### .walkStream(path, [optionsOrSettings])

Reads the directory recursively and asynchronously. [Readable Stream](https://nodejs.org/dist/latest-v12.x/docs/api/stream.html#stream_readable_streams) is used as a provider.

```ts
const stream = fsWalk.walkStream('path');
const stream = fsWalk.walkStream('path', {});
const stream = fsWalk.walkStream('path', new fsWalk.Settings());
```

### .walkSync(path, [optionsOrSettings])

Reads the directory recursively and synchronously. Returns an array of entries.

```ts
const entries = fsWalk.walkSync('path');
const entries = fsWalk.walkSync('path', {});
const entries = fsWalk.walkSync('path', new fsWalk.Settings());
```

#### path

* Required: `true`
* Type: `string | Buffer | URL`

A path to a file. If a URL is provided, it must use the `file:` protocol.

#### optionsOrSettings

* Required: `false`
* Type: `Options | Settings`
* Default: An instance of `Settings` class

An [`Options`](#options) object or an instance of [`Settings`](#settings) class.

> :book: When you pass a plain object, an instance of the `Settings` class will be created automatically. If you plan to call the method frequently, use a pre-created instance of the `Settings` class.

### Settings([options])

A class of full settings of the package.

```ts
const settings = new fsWalk.Settings({ followSymbolicLinks: true });

const entries = fsWalk.walkSync('path', settings);
```

## Entry

* `name` — The name of the entry (`unknown.txt`).
* `path` — The path of the entry relative to call directory (`root/unknown.txt`).
* `dirent` — An instance of [`fs.Dirent`](./src/types/index.ts) class.
* [`stats`] — An instance of `fs.Stats` class.

## Options

### basePath

* Type: `string`
* Default: `undefined`

By default, all paths are built relative to the root path. You can use this option to set custom root path.

In the example below we read the files from the `root` directory, but in the results the root path will be `custom`.

```ts
fsWalk.walkSync('root'); // → ['root/file.txt']
fsWalk.walkSync('root', { basePath: 'custom' }); // → ['custom/file.txt']
```

### concurrency

* Type: `number`
* Default: `Infinity`

The maximum number of concurrent calls to `fs.readdir`.

> :book: The higher the number, the higher performance and the load on the File System. If you want to read in quiet mode, set the value to `4 * os.cpus().length` (4 is default size of [thread pool work scheduling](http://docs.libuv.org/en/v1.x/threadpool.html#thread-pool-work-scheduling)).

### deepFilter

* Type: [`DeepFilterFunction`](./src/settings.ts)
* Default: `undefined`

A function that indicates whether the directory will be read deep or not.

```ts
// Skip all directories that starts with `node_modules`
const filter: DeepFilterFunction = (entry) => !entry.path.startsWith('node_modules');
```

### entryFilter

* Type: [`EntryFilterFunction`](./src/settings.ts)
* Default: `undefined`

A function that indicates whether the entry will be included to results or not.

```ts
// Exclude all `.js` files from results
const filter: EntryFilterFunction = (entry) => !entry.name.endsWith('.js');
```

### errorFilter

* Type: [`ErrorFilterFunction`](./src/settings.ts)
* Default: `undefined`

A function that allows you to skip errors that occur when reading directories.

For example, you can skip `ENOENT` errors if required:

```ts
// Skip all ENOENT errors
const filter: ErrorFilterFunction = (error) => error.code == 'ENOENT';
```

### stats

* Type: `boolean`
* Default: `false`

Adds an instance of `fs.Stats` class to the [`Entry`](#entry).

> :book: Always use `fs.readdir` with additional `fs.lstat/fs.stat` calls to determine the entry type.

### followSymbolicLinks

* Type: `boolean`
* Default: `false`

Follow symbolic links or not. Call `fs.stat` on symbolic link if `true`.

### `throwErrorOnBrokenSymbolicLink`

* Type: `boolean`
* Default: `true`

Throw an error when symbolic link is broken if `true` or safely return `lstat` call if `false`.

### `pathSegmentSeparator`

* Type: `string`
* Default: `path.sep`

By default, this package uses the correct path separator for your OS (`\` on Windows, `/` on Unix-like systems). But you can set this option to any separator character(s) that you want to use instead.

### `fs`

* Type: `FileSystemAdapter`
* Default: A default FS methods

By default, the built-in Node.js module (`fs`) is used to work with the file system. You can replace any method with your own.

```ts
interface FileSystemAdapter {
	lstat: typeof fs.lstat;
	stat: typeof fs.stat;
	lstatSync: typeof fs.lstatSync;
	statSync: typeof fs.statSync;
	readdir: typeof fs.readdir;
	readdirSync: typeof fs.readdirSync;
}

const settings = new fsWalk.Settings({
	fs: { lstat: fakeLstat }
});
```

## Changelog

See the [Releases section of our GitHub project](https://github.com/nodelib/nodelib/releases) for changelog for each release version.

## License

This software is released under the terms of the MIT license.


code:
/// <reference types="node" />
import type { Readable } from 'stream';
import type { Dirent, FileSystemAdapter } from '@nodelib/fs.scandir';
import { AsyncCallback } from './providers/async';
import Settings, { DeepFilterFunction, EntryFilterFunction, ErrorFilterFunction, Options } from './settings';
import type { Entry } from './types';
declare function walk(directory: string, callback: AsyncCallback): void;
declare function walk(directory: string, optionsOrSettings: Options | Settings, callback: AsyncCallback): void;
declare namespace walk {
    function __promisify__(directory: string, optionsOrSettings?: Options | Settings): Promise<Entry[]>;
}
declare function walkSync(directory: string, optionsOrSettings?: Options | Settings): Entry[];
declare function walkStream(directory: string, optionsOrSettings?: Options | Settings): Readable;
export { walk, walkSync, walkStream, Settings, AsyncCallback, Dirent, Entry, FileSystemAdapter, Options, DeepFilterFunction, EntryFilterFunction, ErrorFilterFunction };


code:
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Settings = exports.walkStream = exports.walkSync = exports.walk = void 0;
const async_1 = require("./providers/async");
const stream_1 = require("./providers/stream");
const sync_1 = require("./providers/sync");
const settings_1 = require("./settings");
exports.Settings = settings_1.default;
function walk(directory, optionsOrSettingsOrCallback, callback) {
    if (typeof optionsOrSettingsOrCallback === 'function') {
        new async_1.default(directory, getSettings()).read(optionsOrSettingsOrCallback);
        return;
    }
    new async_1.default(directory, getSettings(optionsOrSettingsOrCallback)).read(callback);
}
exports.walk = walk;
function walkSync(directory, optionsOrSettings) {
    const settings = getSettings(optionsOrSettings);
    const provider = new sync_1.default(directory, settings);
    return provider.read();
}
exports.walkSync = walkSync;
function walkStream(directory, optionsOrSettings) {
    const settings = getSettings(optionsOrSettings);
    const provider = new stream_1.default(directory, settings);
    return provider.read();
}
exports.walkStream = walkStream;
function getSettings(settingsOrOptions = {}) {
    if (settingsOrOptions instanceof settings_1.default) {
        return settingsOrOptions;
    }
    return new settings_1.default(settingsOrOptions);
}


code:
import AsyncReader from '../readers/async';
import type Settings from '../settings';
import type { Entry, Errno } from '../types';
export declare type AsyncCallback = (error: Errno, entries: Entry[]) => void;
export default class AsyncProvider {
    private readonly _root;
    private readonly _settings;
    protected readonly _reader: AsyncReader;
    private readonly _storage;
    constructor(_root: string, _settings: Settings);
    read(callback: AsyncCallback): void;
}


code:
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const async_1 = require("../readers/async");
class AsyncProvider {
    constructor(_root, _settings) {
        this._root = _root;
        this._settings = _settings;
        this._reader = new async_1.default(this._root, this._settings);
        this._storage = [];
    }
    read(callback) {
        this._reader.onError((error) => {
            callFailureCallback(callback, error);
        });
        this._reader.onEntry((entry) => {
            this._storage.push(entry);
        });
        this._reader.onEnd(() => {
            callSuccessCallback(callback, this._storage);
        });
        this._reader.read();
    }
}
exports.default = AsyncProvider;
function callFailureCallback(callback, error) {
    callback(error);
}
function callSuccessCallback(callback, entries) {
    callback(null, entries);
}


code:
import AsyncProvider from './async';
import StreamProvider from './stream';
import SyncProvider from './sync';
export { AsyncProvider, StreamProvider, SyncProvider };


code:
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.SyncProvider = exports.StreamProvider = exports.AsyncProvider = void 0;
const async_1 = require("./async");
exports.AsyncProvider = async_1.default;
const stream_1 = require("./stream");
exports.StreamProvider = stream_1.default;
const sync_1 = require("./sync");
exports.SyncProvider = sync_1.default;


code:
/// <reference types="node" />
import { Readable } from 'stream';
import AsyncReader from '../readers/async';
import type Settings from '../settings';
export default class StreamProvider {
    private readonly _root;
    private readonly _settings;
    protected readonly _reader: AsyncReader;
    protected readonly _stream: Readable;
    constructor(_root: string, _settings: Settings);
    read(): Readable;
}


code:
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const stream_1 = require("stream");
const async_1 = require("../readers/async");
class StreamProvider {
    constructor(_root, _settings) {
        this._root = _root;
        this._settings = _settings;
        this._reader = new async_1.default(this._root, this._settings);
        this._stream = new stream_1.Readable({
            objectMode: true,
            read: () => { },
            destroy: () => {
                if (!this._reader.isDestroyed) {
                    this._reader.destroy();
                }
            }
        });
    }
    read() {
        this._reader.onError((error) => {
            this._stream.emit('error', error);
        });
        this._reader.onEntry((entry) => {
            this._stream.push(entry);
        });
        this._reader.onEnd(() => {
            this._stream.push(null);
        });
        this._reader.read();
        return this._stream;
    }
}
exports.default = StreamProvider;


code:
import SyncReader from '../readers/sync';
import type Settings from '../settings';
import type { Entry } from '../types';
export default class SyncProvider {
    private readonly _root;
    private readonly _settings;
    protected readonly _reader: SyncReader;
    constructor(_root: string, _settings: Settings);
    read(): Entry[];
}


code:
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const sync_1 = require("../readers/sync");
class SyncProvider {
    constructor(_root, _settings) {
        this._root = _root;
        this._settings = _settings;
        this._reader = new sync_1.default(this._root, this._settings);
    }
    read() {
        return this._reader.read();
    }
}
exports.default = SyncProvider;


code:
/// <reference types="node" />
import { EventEmitter } from 'events';
import * as fsScandir from '@nodelib/fs.scandir';
import type Settings from '../settings';
import type { Entry, Errno } from '../types';
import Reader from './reader';
declare type EntryEventCallback = (entry: Entry) => void;
declare type ErrorEventCallback = (error: Errno) => void;
declare type EndEventCallback = () => void;
export default class AsyncReader extends Reader {
    protected readonly _settings: Settings;
    protected readonly _scandir: typeof fsScandir.scandir;
    protected readonly _emitter: EventEmitter;
    private readonly _queue;
    private _isFatalError;
    private _isDestroyed;
    constructor(_root: string, _settings: Settings);
    read(): EventEmitter;
    get isDestroyed(): boolean;
    destroy(): void;
    onEntry(callback: EntryEventCallback): void;
    onError(callback: ErrorEventCallback): void;
    onEnd(callback: EndEventCallback): void;
    private _pushToQueue;
    private _worker;
    private _handleError;
    private _handleEntry;
    private _emitEntry;
}
export {};


code:
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const events_1 = require("events");
const fsScandir = require("@nodelib/fs.scandir");
const fastq = require("fastq");
const common = require("./common");
const reader_1 = require("./reader");
class AsyncReader extends reader_1.default {
    constructor(_root, _settings) {
        super(_root, _settings);
        this._settings = _settings;
        this._scandir = fsScandir.scandir;
        this._emitter = new events_1.EventEmitter();
        this._queue = fastq(this._worker.bind(this), this._settings.concurrency);
        this._isFatalError = false;
        this._isDestroyed = false;
        this._queue.drain = () => {
            if (!this._isFatalError) {
                this._emitter.emit('end');
            }
        };
    }
    read() {
        this._isFatalError = false;
        this._isDestroyed = false;
        setImmediate(() => {
            this._pushToQueue(this._root, this._settings.basePath);
        });
        return this._emitter;
    }
    get isDestroyed() {
        return this._isDestroyed;
    }
    destroy() {
        if (this._isDestroyed) {
            throw new Error('The reader is already destroyed');
        }
        this._isDestroyed = true;
        this._queue.killAndDrain();
    }
    onEntry(callback) {
        this._emitter.on('entry', callback);
    }
    onError(callback) {
        this._emitter.once('error', callback);
    }
    onEnd(callback) {
        this._emitter.once('end', callback);
    }
    _pushToQueue(directory, base) {
        const queueItem = { directory, base };
        this._queue.push(queueItem, (error) => {
            if (error !== null) {
                this._handleError(error);
            }
        });
    }
    _worker(item, done) {
        this._scandir(item.directory, this._settings.fsScandirSettings, (error, entries) => {
            if (error !== null) {
                done(error, undefined);
                return;
            }
            for (const entry of entries) {
                this._handleEntry(entry, item.base);
            }
            done(null, undefined);
        });
    }
    _handleError(error) {
        if (this._isDestroyed || !common.isFatalError(this._settings, error)) {
            return;
        }
        this._isFatalError = true;
        this._isDestroyed = true;
        this._emitter.emit('error', error);
    }
    _handleEntry(entry, base) {
        if (this._isDestroyed || this._isFatalError) {
            return;
        }
        const fullpath = entry.path;
        if (base !== undefined) {
            entry.path = common.joinPathSegments(base, entry.name, this._settings.pathSegmentSeparator);
        }
        if (common.isAppliedFilter(this._settings.entryFilter, entry)) {
            this._emitEntry(entry);
        }
        if (entry.dirent.isDirectory() && common.isAppliedFilter(this._settings.deepFilter, entry)) {
            this._pushToQueue(fullpath, base === undefined ? undefined : entry.path);
        }
    }
    _emitEntry(entry) {
        this._emitter.emit('entry', entry);
    }
}
exports.default = AsyncReader;


code:
import type { FilterFunction } from '../settings';
import type Settings from '../settings';
import type { Errno } from '../types';
export declare function isFatalError(settings: Settings, error: Errno): boolean;
export declare function isAppliedFilter<T>(filter: FilterFunction<T> | null, value: T): boolean;
export declare function replacePathSegmentSeparator(filepath: string, separator: string): string;
export declare function joinPathSegments(a: string, b: string, separator: string): string;


code:
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.joinPathSegments = exports.replacePathSegmentSeparator = exports.isAppliedFilter = exports.isFatalError = void 0;
function isFatalError(settings, error) {
    if (settings.errorFilter === null) {
        return true;
    }
    return !settings.errorFilter(error);
}
exports.isFatalError = isFatalError;
function isAppliedFilter(filter, value) {
    return filter === null || filter(value);
}
exports.isAppliedFilter = isAppliedFilter;
function replacePathSegmentSeparator(filepath, separator) {
    return filepath.split(/[/\\]/).join(separator);
}
exports.replacePathSegmentSeparator = replacePathSegmentSeparator;
function joinPathSegments(a, b, separator) {
    if (a === '') {
        return b;
    }
    /**
     * The correct handling of cases when the first segment is a root (`/`, `C:/`) or UNC path (`//?/C:/`).
     */
    if (a.endsWith(separator)) {
        return a + b;
    }
    return a + separator + b;
}
exports.joinPathSegments = joinPathSegments;


code:
import type Settings from '../settings';
export default class Reader {
    protected readonly _root: string;
    protected readonly _settings: Settings;
    constructor(_root: string, _settings: Settings);
}


code:
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const common = require("./common");
class Reader {
    constructor(_root, _settings) {
        this._root = _root;
        this._settings = _settings;
        this._root = common.replacePathSegmentSeparator(_root, _settings.pathSegmentSeparator);
    }
}
exports.default = Reader;


code:
import * as fsScandir from '@nodelib/fs.scandir';
import type { Entry } from '../types';
import Reader from './reader';
export default class SyncReader extends Reader {
    protected readonly _scandir: typeof fsScandir.scandirSync;
    private readonly _storage;
    private readonly _queue;
    read(): Entry[];
    private _pushToQueue;
    private _handleQueue;
    private _handleDirectory;
    private _handleError;
    private _handleEntry;
    private _pushToStorage;
}


code:
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const fsScandir = require("@nodelib/fs.scandir");
const common = require("./common");
const reader_1 = require("./reader");
class SyncReader extends reader_1.default {
    constructor() {
        super(...arguments);
        this._scandir = fsScandir.scandirSync;
        this._storage = [];
        this._queue = new Set();
    }
    read() {
        this._pushToQueue(this._root, this._settings.basePath);
        this._handleQueue();
        return this._storage;
    }
    _pushToQueue(directory, base) {
        this._queue.add({ directory, base });
    }
    _handleQueue() {
        for (const item of this._queue.values()) {
            this._handleDirectory(item.directory, item.base);
        }
    }
    _handleDirectory(directory, base) {
        try {
            const entries = this._scandir(directory, this._settings.fsScandirSettings);
            for (const entry of entries) {
                this._handleEntry(entry, base);
            }
        }
        catch (error) {
            this._handleError(error);
        }
    }
    _handleError(error) {
        if (!common.isFatalError(this._settings, error)) {
            return;
        }
        throw error;
    }
    _handleEntry(entry, base) {
        const fullpath = entry.path;
        if (base !== undefined) {
            entry.path = common.joinPathSegments(base, entry.name, this._settings.pathSegmentSeparator);
        }
        if (common.isAppliedFilter(this._settings.entryFilter, entry)) {
            this._pushToStorage(entry);
        }
        if (entry.dirent.isDirectory() && common.isAppliedFilter(this._settings.deepFilter, entry)) {
            this._pushToQueue(fullpath, base === undefined ? undefined : entry.path);
        }
    }
    _pushToStorage(entry) {
        this._storage.push(entry);
    }
}
exports.default = SyncReader;


code:
import * as fsScandir from '@nodelib/fs.scandir';
import type { Entry, Errno } from './types';
export declare type FilterFunction<T> = (value: T) => boolean;
export declare type DeepFilterFunction = FilterFunction<Entry>;
export declare type EntryFilterFunction = FilterFunction<Entry>;
export declare type ErrorFilterFunction = FilterFunction<Errno>;
export interface Options {
    basePath?: string;
    concurrency?: number;
    deepFilter?: DeepFilterFunction;
    entryFilter?: EntryFilterFunction;
    errorFilter?: ErrorFilterFunction;
    followSymbolicLinks?: boolean;
    fs?: Partial<fsScandir.FileSystemAdapter>;
    pathSegmentSeparator?: string;
    stats?: boolean;
    throwErrorOnBrokenSymbolicLink?: boolean;
}
export default class Settings {
    private readonly _options;
    readonly basePath?: string;
    readonly concurrency: number;
    readonly deepFilter: DeepFilterFunction | null;
    readonly entryFilter: EntryFilterFunction | null;
    readonly errorFilter: ErrorFilterFunction | null;
    readonly pathSegmentSeparator: string;
    readonly fsScandirSettings: fsScandir.Settings;
    constructor(_options?: Options);
    private _getValue;
}


code:
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const path = require("path");
const fsScandir = require("@nodelib/fs.scandir");
class Settings {
    constructor(_options = {}) {
        this._options = _options;
        this.basePath = this._getValue(this._options.basePath, undefined);
        this.concurrency = this._getValue(this._options.concurrency, Number.POSITIVE_INFINITY);
        this.deepFilter = this._getValue(this._options.deepFilter, null);
        this.entryFilter = this._getValue(this._options.entryFilter, null);
        this.errorFilter = this._getValue(this._options.errorFilter, null);
        this.pathSegmentSeparator = this._getValue(this._options.pathSegmentSeparator, path.sep);
        this.fsScandirSettings = new fsScandir.Settings({
            followSymbolicLinks: this._options.followSymbolicLinks,
            fs: this._options.fs,
            pathSegmentSeparator: this._options.pathSegmentSeparator,
            stats: this._options.stats,
            throwErrorOnBrokenSymbolicLink: this._options.throwErrorOnBrokenSymbolicLink
        });
    }
    _getValue(option, value) {
        return option !== null && option !== void 0 ? option : value;
    }
}
exports.default = Settings;


code:
/// <reference types="node" />
import type * as scandir from '@nodelib/fs.scandir';
export declare type Entry = scandir.Entry;
export declare type Errno = NodeJS.ErrnoException;
export interface QueueItem {
    directory: string;
    base?: string;
}


code:
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });


@nodelib/fs.walk

description: A library for efficiently walking a directory recursively

keywords:
NodeLib
fs
FileSystem
file system
walk
scanner
crawler


code:
/// <reference types="node" />
export declare const CWD: string;
export declare const cjsRequire: NodeRequire;
export declare const EXTENSIONS: string[];


code:
import { createRequire } from 'node:module';
export const CWD = process.cwd();
export const cjsRequire = typeof require === 'undefined' ? createRequire(import.meta.url) : require;
export const EXTENSIONS = ['.ts', '.tsx', ...Object.keys(cjsRequire.extensions)];
//# sourceMappingURL=constants.js.map


code:
export declare const tryPkg: (pkg: string) => string | undefined;
export declare const isPkgAvailable: (pkg: string) => boolean;
export declare const tryFile: (filePath?: string[] | string, includeDir?: boolean) => string;
export declare const tryExtensions: (filepath: string, extensions?: string[]) => string;
export declare const findUp: (searchEntry: string, searchFileOrIncludeDir?: boolean | string, includeDir?: boolean) => string;


code:
import fs from 'node:fs';
import path from 'node:path';
import { CWD, EXTENSIONS, cjsRequire } from './constants.js';
export const tryPkg = (pkg) => {
    try {
        return cjsRequire.resolve(pkg);
    }
    catch (_a) { }
};
export const isPkgAvailable = (pkg) => !!tryPkg(pkg);
export const tryFile = (filePath, includeDir = false) => {
    if (typeof filePath === 'string') {
        return fs.existsSync(filePath) &&
            (includeDir || fs.statSync(filePath).isFile())
            ? filePath
            : '';
    }
    for (const file of filePath !== null && filePath !== void 0 ? filePath : []) {
        if (tryFile(file, includeDir)) {
            return file;
        }
    }
    return '';
};
export const tryExtensions = (filepath, extensions = EXTENSIONS) => {
    const ext = [...extensions, ''].find(ext => tryFile(filepath + ext));
    return ext == null ? '' : filepath + ext;
};
export const findUp = (searchEntry, searchFileOrIncludeDir, includeDir) => {
    console.assert(path.isAbsolute(searchEntry));
    if (!tryFile(searchEntry, true) ||
        (searchEntry !== CWD && !searchEntry.startsWith(CWD + path.sep))) {
        return '';
    }
    searchEntry = path.resolve(fs.statSync(searchEntry).isDirectory()
        ? searchEntry
        : path.resolve(searchEntry, '..'));
    const isSearchFile = typeof searchFileOrIncludeDir === 'string';
    const searchFile = isSearchFile ? searchFileOrIncludeDir : 'package.json';
    do {
        const searched = tryFile(path.resolve(searchEntry, searchFile), isSearchFile && includeDir);
        if (searched) {
            return searched;
        }
        searchEntry = path.resolve(searchEntry, '..');
    } while (searchEntry === CWD || searchEntry.startsWith(CWD + path.sep));
    return '';
};
//# sourceMappingURL=helpers.js.map


code:
'use strict';

var node_module = require('node:module');
var fs = require('node:fs');
var path = require('node:path');

const import_meta = {};
const CWD = process.cwd();
const cjsRequire = typeof require === "undefined" ? node_module.createRequire(import_meta.url) : require;
const EXTENSIONS = [".ts", ".tsx", ...Object.keys(cjsRequire.extensions)];

const tryPkg = (pkg) => {
  try {
    return cjsRequire.resolve(pkg);
  } catch (e) {
  }
};
const isPkgAvailable = (pkg) => !!tryPkg(pkg);
const tryFile = (filePath, includeDir = false) => {
  if (typeof filePath === "string") {
    return fs.existsSync(filePath) && (includeDir || fs.statSync(filePath).isFile()) ? filePath : "";
  }
  for (const file of filePath != null ? filePath : []) {
    if (tryFile(file, includeDir)) {
      return file;
    }
  }
  return "";
};
const tryExtensions = (filepath, extensions = EXTENSIONS) => {
  const ext = [...extensions, ""].find((ext2) => tryFile(filepath + ext2));
  return ext == null ? "" : filepath + ext;
};
const findUp = (searchEntry, searchFileOrIncludeDir, includeDir) => {
  console.assert(path.isAbsolute(searchEntry));
  if (!tryFile(searchEntry, true) || searchEntry !== CWD && !searchEntry.startsWith(CWD + path.sep)) {
    return "";
  }
  searchEntry = path.resolve(
    fs.statSync(searchEntry).isDirectory() ? searchEntry : path.resolve(searchEntry, "..")
  );
  const isSearchFile = typeof searchFileOrIncludeDir === "string";
  const searchFile = isSearchFile ? searchFileOrIncludeDir : "package.json";
  do {
    const searched = tryFile(
      path.resolve(searchEntry, searchFile),
      isSearchFile && includeDir
    );
    if (searched) {
      return searched;
    }
    searchEntry = path.resolve(searchEntry, "..");
  } while (searchEntry === CWD || searchEntry.startsWith(CWD + path.sep));
  return "";
};

exports.CWD = CWD;
exports.EXTENSIONS = EXTENSIONS;
exports.cjsRequire = cjsRequire;
exports.findUp = findUp;
exports.isPkgAvailable = isPkgAvailable;
exports.tryExtensions = tryExtensions;
exports.tryFile = tryFile;
exports.tryPkg = tryPkg;


code:
export * from './constants.js';
export * from './helpers.js';


code:
export * from './constants.js';
export * from './helpers.js';
//# sourceMappingURL=index.js.map


@pkgr/core

type: module

description: Shared core module for `@pkgr` packages or any package else

access: public


code:
const qs = require('querystring');

/**
 * @typedef ParsedURL
 * @type {import('.').ParsedURL}
 */

/**
 * @typedef Request
 * @property {string} url
 * @property {ParsedURL} _parsedUrl
 */

/**
 * @param {Request} req
 * @returns {ParsedURL|void}
 */
function parse(req) {
	let raw = req.url;
	if (raw == null) return;

	let prev = req._parsedUrl;
	if (prev && prev.raw === raw) return prev;

	let pathname=raw, search='', query;

	if (raw.length > 1) {
		let idx = raw.indexOf('?', 1);

		if (idx !== -1) {
			search = raw.substring(idx);
			pathname = raw.substring(0, idx);
			if (search.length > 1) {
				query = qs.parse(search.substring(1));
			}
		}
	}

	return req._parsedUrl = { pathname, search, query, raw };
}

exports.parse = parse;


code:
import * as qs from 'querystring';

/**
 * @typedef ParsedURL
 * @type {import('.').ParsedURL}
 */

/**
 * @typedef Request
 * @property {string} url
 * @property {ParsedURL} _parsedUrl
 */

/**
 * @param {Request} req
 * @returns {ParsedURL|void}
 */
export function parse(req) {
	let raw = req.url;
	if (raw == null) return;

	let prev = req._parsedUrl;
	if (prev && prev.raw === raw) return prev;

	let pathname=raw, search='', query;

	if (raw.length > 1) {
		let idx = raw.indexOf('?', 1);

		if (idx !== -1) {
			search = raw.substring(idx);
			pathname = raw.substring(0, idx);
			if (search.length > 1) {
				query = qs.parse(search.substring(1));
			}
		}
	}

	return req._parsedUrl = { pathname, search, query, raw };
}


code:
import type { IncomingMessage } from 'http';

export interface ParsedURL {
	pathname: string;
	search: string;
	query: Record<string, string | string[]> | void;
	raw: string;
}

export function parse(req: IncomingMessage): ParsedURL;


@polka/url

repository: lukeed/polka

description: Super fast, memoized `req.url` parser


code:
# @polka/url [![npm](https://badgen.now.sh/npm/v/@polka/url)](https://npmjs.org/package/@polka/url) [![licenses](https://licenses.dev/b/npm/%40polka%2Furl)](https://licenses.dev/npm/%40polka%2Furl)

> Super fast, memoized `req.url` parser; _not_ limited to [Polka][polka]!

Parses the `url` from a [`IncomingMessage`](https://nodejs.org/api/http.html#http_class_http_incomingmessage) request. The returned object will always only contain the following keys: `search`, `query`, `pathname`, and `raw`.

> **Note:** This library does not process `protocol`, `hostname`, `port`, etc.
This is because the incoming `req.url` value only begins with the path information.

Parsed requests will be mutated with a `_parsedUrl` key, containing the returned output. This is used for future memoization, avoiding the need to fully parse the same `url` value multiple times.

## Install

```
$ npm install --save @polka/url
```

## Usage

```js
const parse = require('@polka/url');

let req = {
  url: '/foo/bar?fizz=buzz'
};
let output = parse(req);
//=> {
//=>   pathname: '/foo/bar',
//=>   raw: '/foo/bar?fizz=buzz',
//=>   search: '?fizz=buzz',
//=>   query: {
//=>     fizz: 'buzz'
//=>   },
//=> }

// Attaches result for future memoization
assert.deepEqual(output, req._parsedUrl); //=> true
```

## API

### url(req)
Returns: `Object` or `undefined`

> **Important:** The `req` must have a `url` key, otherwise `undefined` will be returned.
If no input is provided at all, a `TypeError` will be thrown.

#### req
Type: `IncomingMessage` or `{ url: string }`

The incoming HTTP request (`req`) or a plain `Object` with a `url` key.

> **Note:** In Node.js servers, the [`req.url`](https://nodejs.org/api/http.html#http_message_url) begins with a pathname & does not include a `hash`.

## Benchmarks

Check out the [`bench`](/bench) directory for in-depth benchmark results and comparisons.

## Support

Any issues or questions can be sent to the [Polka][polka] repository.
However, please specify that your inquiry is about `@polka/url` specifically.

## License

MIT © [Luke Edwards](https://lukeed.com)

[polka]: https://github.com/lukeed/polka


code:
Tooltip & Popover Positioning Engine

**Positioning tooltips and popovers is difficult. Popper is here to help!**

Given an element, such as a button, and a tooltip element describing it, Popper
will automatically put the tooltip in the right place near the button.

It will position _any_ UI element that "pops out" from the flow of your document
and floats near a target element. The most common example is a tooltip, but it
also includes popovers, drop-downs, and more. All of these can be generically
described as a "popper" element.

## Demo

[![Popper visualized](https://i.imgur.com/F7qWsmV.jpg)](https://popper.js.org)

## Docs

- [v2.x (latest)](https://popper.js.org/docs/v2/)
- [v1.x](https://popper.js.org/docs/v1/)

We've created a
[Migration Guide](https://popper.js.org/docs/v2/migration-guide/) to help you
migrate from Popper 1 to Popper 2.

To contribute to the Popper website and documentation, please visit the
[dedicated repository](https://github.com/popperjs/website).

## Why not use pure CSS?

- **Clipping and overflow issues**: Pure CSS poppers will not be prevented from
  overflowing clipping boundaries, such as the viewport. It will get partially
  cut off or overflows if it's near the edge since there is no dynamic
  positioning logic. When using Popper, your popper will always be positioned in
  the right place without needing manual adjustments.
- **No flipping**: CSS poppers will not flip to a different placement to fit
  better in view if necessary. While you can manually adjust for the main axis
  overflow, this feature cannot be achieved via CSS alone. Popper automatically
  flips the tooltip to make it fit in view as best as possible for the user.
- **No virtual positioning**: CSS poppers cannot follow the mouse cursor or be
  used as a context menu. Popper allows you to position your tooltip relative to
  any coordinates you desire.
- **Slower development cycle**: When pure CSS is used to position popper
  elements, the lack of dynamic positioning means they must be carefully placed
  to consider overflow on all screen sizes. In reusable component libraries,
  this means a developer can't just add the component anywhere on the page,
  because these issues need to be considered and adjusted for every time. With
  Popper, you can place your elements anywhere and they will be positioned
  correctly, without needing to consider different screen sizes, layouts, etc.
  This massively speeds up development time because this work is automatically
  offloaded to Popper.
- **Lack of extensibility**: CSS poppers cannot be easily extended to fit any
  arbitrary use case you may need to adjust for. Popper is built with
  extensibility in mind.

## Why Popper?

With the CSS drawbacks out of the way, we now move on to Popper in the
JavaScript space itself.

Naive JavaScript tooltip implementations usually have the following problems:

- **Scrolling containers**: They don't ensure the tooltip stays with the
  reference element while scrolling when inside any number of scrolling
  containers.
- **DOM context**: They often require the tooltip move outside of its original
  DOM context because they don't handle `offsetParent` contexts.
- **Compatibility**: Popper handles an incredible number of edge cases regarding
  different browsers and environments (mobile viewports, RTL, scrollbars enabled
  or disabled, etc.). Popper is a popular and well-maintained library, so you
  can be confident positioning will work for your users on any device.
- **Configurability**: They often lack advanced configurability to suit any
  possible use case.
- **Size**: They are usually relatively large in size, or require an ancient
  jQuery dependency.
- **Performance**: They often have runtime performance issues and update the
  tooltip position too slowly.

**Popper solves all of these key problems in an elegant, performant manner.** It
is a lightweight ~3 kB library that aims to provide a reliable and extensible
positioning engine you can use to ensure all your popper elements are positioned
in the right place.

When you start writing your own popper implementation, you'll quickly run into
all of the problems mentioned above. These widgets are incredibly common in our
UIs; we've done the hard work figuring this out so you don't need to spend hours
fixing and handling numerous edge cases that we already ran into while building
the library!

Popper is used in popular libraries like Bootstrap, Foundation, Material UI, and
more. It's likely you've already used popper elements on the web positioned by
Popper at some point in the past few years.

Since we write UIs using powerful abstraction libraries such as React or Angular
nowadays, you'll also be glad to know Popper can fully integrate with them and
be a good citizen together with your other components. Check out `react-popper`
for the official Popper wrapper for React.

## Installation

### 1. Package Manager

```bash
# With npm
npm i @popperjs/core

# With Yarn
yarn add @popperjs/core
```

### 2. CDN

```html
<!-- Development version -->
<script src="https://unpkg.com/@popperjs/core@2/dist/umd/popper.js"></script>

<!-- Production version -->
<script src="https://unpkg.com/@popperjs/core@2"></script>
```

### 3. Direct Download?

Managing dependencies by "directly downloading" them and placing them into your
source code is not recommended for a variety of reasons, including missing out
on feat/fix updates easily. Please use a versioning management system like a CDN
or npm/Yarn.

## Usage

The most straightforward way to get started is to import Popper from the `unpkg`
CDN, which includes all of its features. You can call the `Popper.createPopper`
constructor to create new popper instances.

Here is a complete example:

```html
<!DOCTYPE html>
<title>Popper example</title>

<style>
  #tooltip {
    background-color: #333;
    color: white;
    padding: 5px 10px;
    border-radius: 4px;
    font-size: 13px;
  }
</style>

<button id="button" aria-describedby="tooltip">I'm a button</button>
<div id="tooltip" role="tooltip">I'm a tooltip</div>

<script src="https://unpkg.com/@popperjs/core@^2.0.0"></script>
<script>
  const button = document.querySelector('#button');
  const tooltip = document.querySelector('#tooltip');

  // Pass the button, the tooltip, and some options, and Popper will do the
  // magic positioning for you:
  Popper.createPopper(button, tooltip, {
    placement: 'right',
  });
</script>
```

Visit the [tutorial](https://popper.js.org/docs/v2/tutorial/) for an example of
how to build your own tooltip from scratch using Popper.

### Module bundlers

You can import the `createPopper` constructor from the fully-featured file:

```js
import { createPopper } from '@popperjs/core';

const button = document.querySelector('#button');
const tooltip = document.querySelector('#tooltip');

// Pass the button, the tooltip, and some options, and Popper will do the
// magic positioning for you:
createPopper(button, tooltip, {
  placement: 'right',
});
```

All the modifiers listed in the docs menu will be enabled and "just work", so
you don't need to think about setting Popper up. The size of Popper including
all of its features is about 5 kB minzipped, but it may grow a bit in the
future.

#### Popper Lite (tree-shaking)

If bundle size is important, you'll want to take advantage of tree-shaking. The
library is built in a modular way to allow to import only the parts you really
need.

```js
import { createPopperLite as createPopper } from '@popperjs/core';
```

The Lite version includes the most necessary modifiers that will compute the
offsets of the popper, compute and add the positioning styles, and add event
listeners. This is close in bundle size to pure CSS tooltip libraries, and
behaves somewhat similarly.

However, this does not include the features that makes Popper truly useful.

The two most useful modifiers not included in Lite are `preventOverflow` and
`flip`:

```js
import {
  createPopperLite as createPopper,
  preventOverflow,
  flip,
} from '@popperjs/core';

const button = document.querySelector('#button');
const tooltip = document.querySelector('#tooltip');

createPopper(button, tooltip, {
  modifiers: [preventOverflow, flip],
});
```

As you make more poppers, you may be finding yourself needing other modifiers
provided by the library.

See [tree-shaking](https://popper.js.org/docs/v2/performance/#tree-shaking) for more
information.

## Distribution targets

Popper is distributed in 3 different versions, in 3 different file formats.

The 3 file formats are:

- `esm` (works with `import` syntax — **recommended**)
- `umd` (works with `<script>` tags or RequireJS)
- `cjs` (works with `require()` syntax)

There are two different `esm` builds, one for bundler consumers (e.g. webpack,
Rollup, etc..), which is located under `/lib`, and one for browsers with native
support for ES Modules, under `/dist/esm`. The only difference within the two,
is that the browser-compatible version doesn't make use of
`process.env.NODE_ENV` to run development checks.

The 3 versions are:

- `popper`: includes all the modifiers (features) in one file (**default**);
- `popper-lite`: includes only the minimum amount of modifiers to provide the
  basic functionality;
- `popper-base`: doesn't include any modifier, you must import them separately;

Below you can find the size of each version, minified and compressed with the
[Brotli compression algorithm](https://medium.com/groww-engineering/enable-brotli-compression-in-webpack-with-fallback-to-gzip-397a57cf9fc6):

![](https://badge-size.now.sh/https://unpkg.com/@popperjs/core/dist/umd/popper.min.js?compression=brotli&label=popper)
![](https://badge-size.now.sh/https://unpkg.com/@popperjs/core/dist/umd/popper-lite.min.js?compression=brotli&label=popper%20lite)
![](https://badge-size.now.sh/https://unpkg.com/@popperjs/core/dist/umd/popper-base.min.js?compression=brotli&label=popper%20base)

## Hacking the library

If you want to play with the library, implement new features, fix a bug you
found, or simply experiment with it, this section is for you!

First of all, make sure to have
[Yarn installed](https://yarnpkg.com/lang/en/docs/install).

Install the development dependencies:

```bash
yarn install
```

And run the development environment:

```bash
yarn dev
```

Then, simply open one the development server web page:

```bash
# macOS and Linux
open localhost:5000

# Windows
start localhost:5000
```

From there, you can open any of the examples (`.html` files) to fiddle with
them.

Now any change you will made to the source code, will be automatically compiled,
you just need to refresh the page.

If the page is not working properly, try to go in _"Developer Tools >
Application > Clear storage"_ and click on "_Clear site data_".
To run the examples you need a browser with
[JavaScript modules via script tag support](https://caniuse.com/#feat=es6-module).

## Test Suite

Popper is currently tested with unit tests, and functional tests. Both of them
are run by Jest.

### Unit Tests

The unit tests use JSDOM to provide a primitive document object API, they are
used to ensure the utility functions behave as expected in isolation.

### Functional Tests

The functional tests run with Puppeteer, to take advantage of a complete browser
environment. They are currently running on Chromium, and Firefox.

You can run them with `yarn test:functional`. Set the `PUPPETEER_BROWSER`
environment variable to `firefox` to run them on the Mozilla browser.

The assertions are written in form of image snapshots, so that it's easy to
assert for the correct Popper behavior without having to write a lot of offsets
comparisons manually.

You can mark a `*.test.js` file to run in the Puppeteer environment by
prepending a `@jest-environment puppeteer` JSDoc comment to the interested file.

Here's an example of a basic functional test:

```js
/**
 * @jest-environment puppeteer
 * @flow
 */
import { screenshot } from '../utils/puppeteer.js';

it('should position the popper on the right', async () => {
  const page = await browser.newPage();
  await page.goto(`${TEST_URL}/basic.html`);

  expect(await screenshot(page)).toMatchImageSnapshot();
});
```

You can find the complete
[`jest-puppeteer` documentation here](https://github.com/smooth-code/jest-puppeteer#api),
and the
[`jest-image-snapshot` documentation here](https://github.com/americanexpress/jest-image-snapshot#%EF%B8%8F-api).

## License

MIT


code:
import type { OptionsGeneric, Modifier, Instance, VirtualElement } from "./types";
import detectOverflow from "./utils/detectOverflow";
declare type PopperGeneratorArgs = {
    defaultModifiers?: Array<Modifier<any, any>>;
    defaultOptions?: Partial<OptionsGeneric<any>>;
};
export declare function popperGenerator(generatorOptions?: PopperGeneratorArgs): <TModifier extends Partial<Modifier<any, any>>>(reference: Element | VirtualElement, popper: HTMLElement, options?: Partial<OptionsGeneric<TModifier>>) => Instance;
export declare const createPopper: <TModifier extends Partial<Modifier<any, any>>>(reference: Element | VirtualElement, popper: HTMLElement, options?: Partial<OptionsGeneric<TModifier>>) => Instance;
export { detectOverflow };


code: export default function contains(parent: Element, child: Element): boolean;


code:
import type { ClientRectObject, VirtualElement } from "../types";
export default function getBoundingClientRect(element: Element | VirtualElement, includeScale?: boolean): ClientRectObject;


code:
import type { ClientRectObject } from "../types";
import type { Boundary, RootBoundary } from "../enums";
export default function getClippingRect(element: Element, boundary: Boundary, rootBoundary: RootBoundary): ClientRectObject;


code:
import type { Rect, VirtualElement, Window } from "../types";
export default function getCompositeRect(elementOrVirtualElement: Element | VirtualElement, offsetParent: Element | Window, isFixed?: boolean): Rect;


code: export default function getComputedStyle(element: Element): CSSStyleDeclaration;


code:
import type { Window } from "../types";
export default function getDocumentElement(element: Element | Window): HTMLElement;


code:
import type { Rect } from "../types";
export default function getDocumentRect(element: HTMLElement): Rect;


code:
export default function getHTMLElementScroll(element: HTMLElement): {
    scrollLeft: number;
    scrollTop: number;
};


code:
import type { Rect } from "../types";
export default function getLayoutRect(element: HTMLElement): Rect;


code:
import type { Window } from "../types";
export default function getNodeName(element: (Node | null | undefined) | Window): string | null | undefined;


code:
import type { Window } from "../types";
export default function getNodeScroll(node: Node | Window): {
    scrollLeft: any;
    scrollTop: any;
};


code: export default function getOffsetParent(element: Element): any;


code: export default function getParentNode(element: Node | ShadowRoot): Node;


code: export default function getScrollParent(node: Node): HTMLElement;


code:
export default function getViewportRect(element: Element): {
    width: number;
    height: number;
    x: number;
    y: number;
};


code: export default function getWindow(node: any): any;


code:
import type { Window } from "../types";
export default function getWindowScroll(node: Node | Window): {
    scrollLeft: any;
    scrollTop: any;
};


code: export default function getWindowScrollBarX(element: Element): number;


code:
declare function isElement(node: unknown): boolean;
declare function isHTMLElement(node: unknown): boolean;
declare function isShadowRoot(node: unknown): boolean;
export { isElement, isHTMLElement, isShadowRoot };


code: export default function isScrollParent(element: HTMLElement): boolean;


code: export default function isTableElement(element: Element): boolean;


code:
import type { Window, VisualViewport } from "../types";
export default function listScrollParents(element: Node, list?: Array<Element | Window>): Array<Element | Window | VisualViewport>;


code:
export declare const top: "top";
export declare const bottom: "bottom";
export declare const right: "right";
export declare const left: "left";
export declare const auto: "auto";
export declare type BasePlacement = typeof top | typeof bottom | typeof right | typeof left;
export declare const basePlacements: Array<BasePlacement>;
export declare const start: "start";
export declare const end: "end";
export declare type Variation = typeof start | typeof end;
export declare const clippingParents: "clippingParents";
export declare const viewport: "viewport";
export declare type Boundary = Element | Array<Element> | typeof clippingParents;
export declare type RootBoundary = typeof viewport | "document";
export declare const popper: "popper";
export declare const reference: "reference";
export declare type Context = typeof popper | typeof reference;
export declare type VariationPlacement = "top-start" | "top-end" | "bottom-start" | "bottom-end" | "right-start" | "right-end" | "left-start" | "left-end";
export declare type AutoPlacement = "auto" | "auto-start" | "auto-end";
export declare type ComputedPlacement = VariationPlacement | BasePlacement;
export declare type Placement = AutoPlacement | BasePlacement | VariationPlacement;
export declare const variationPlacements: Array<VariationPlacement>;
export declare const placements: Array<Placement>;
export declare const beforeRead: "beforeRead";
export declare const read: "read";
export declare const afterRead: "afterRead";
export declare const beforeMain: "beforeMain";
export declare const main: "main";
export declare const afterMain: "afterMain";
export declare const beforeWrite: "beforeWrite";
export declare const write: "write";
export declare const afterWrite: "afterWrite";
export declare const modifierPhases: Array<ModifierPhases>;
export declare type ModifierPhases = typeof beforeRead | typeof read | typeof afterRead | typeof beforeMain | typeof main | typeof afterMain | typeof beforeWrite | typeof write | typeof afterWrite;


code:
export * from "./types";
export * from "./enums";
export * from "./modifiers";
export { popperGenerator, detectOverflow, createPopper as createPopperBase } from "./createPopper";
export { createPopper } from "./popper";
export { createPopper as createPopperLite } from "./popper-lite";


code:
import type { Modifier } from "../types";
export declare type ApplyStylesModifier = Modifier<"applyStyles", {}>;
declare const _default: ApplyStylesModifier;
export default _default;


code:
import type { Modifier, Padding, Rect } from "../types";
import type { Placement } from "../enums";
export declare type Options = {
    element: HTMLElement | string | null;
    padding: Padding | ((arg0: {
        popper: Rect;
        reference: Rect;
        placement: Placement;
    }) => Padding);
};
export declare type ArrowModifier = Modifier<"arrow", Options>;
declare const _default: ArrowModifier;
export default _default;


code:
import type { PositioningStrategy, Offsets, Modifier, Rect } from "../types";
import { BasePlacement, Variation } from "../enums";
export declare type RoundOffsets = (offsets: Partial<{
    x: number;
    y: number;
    centerOffset: number;
}>) => Offsets;
export declare type Options = {
    gpuAcceleration: boolean;
    adaptive: boolean;
    roundOffsets?: boolean | RoundOffsets;
};
export declare function mapToStyles({ popper, popperRect, placement, variation, offsets, position, gpuAcceleration, adaptive, roundOffsets, isFixed }: {
    popper: HTMLElement;
    popperRect: Rect;
    placement: BasePlacement;
    variation: Variation | null | undefined;
    offsets: Partial<{
        x: number;
        y: number;
        centerOffset: number;
    }>;
    position: PositioningStrategy;
    gpuAcceleration: boolean;
    adaptive: boolean;
    roundOffsets: boolean | RoundOffsets;
    isFixed: boolean;
}): {
    transform: string;
    top: string;
    right: string;
    bottom: string;
    left: string;
    position: PositioningStrategy;
};
export declare type ComputeStylesModifier = Modifier<"computeStyles", Options>;
declare const _default: ComputeStylesModifier;
export default _default;


code:
import type { Modifier } from "../types";
export declare type Options = {
    scroll: boolean;
    resize: boolean;
};
export declare type EventListenersModifier = Modifier<"eventListeners", Options>;
declare const _default: EventListenersModifier;
export default _default;


code:
import type { Placement, Boundary, RootBoundary } from "../enums";
import type { Modifier, Padding } from "../types";
export declare type Options = {
    mainAxis: boolean;
    altAxis: boolean;
    fallbackPlacements: Array<Placement>;
    padding: Padding;
    boundary: Boundary;
    rootBoundary: RootBoundary;
    altBoundary: boolean;
    flipVariations: boolean;
    allowedAutoPlacements: Array<Placement>;
};
export declare type FlipModifier = Modifier<"flip", Options>;
declare const _default: FlipModifier;
export default _default;


code:
import type { Modifier } from "../types";
export declare type HideModifier = Modifier<"hide", {}>;
declare const _default: HideModifier;
export default _default;


code:
export { default as applyStyles } from "./applyStyles";
export { default as arrow } from "./arrow";
export { default as computeStyles } from "./computeStyles";
export { default as eventListeners } from "./eventListeners";
export { default as flip } from "./flip";
export { default as hide } from "./hide";
export { default as offset } from "./offset";
export { default as popperOffsets } from "./popperOffsets";
export { default as preventOverflow } from "./preventOverflow";


code:
import type { Placement } from "../enums";
import type { Modifier, Rect, Offsets } from "../types";
export declare type OffsetsFunction = (arg0: {
    popper: Rect;
    reference: Rect;
    placement: Placement;
}) => [number | null | undefined, number | null | undefined];
declare type Offset = OffsetsFunction | [number | null | undefined, number | null | undefined];
export declare type Options = {
    offset: Offset;
};
export declare function distanceAndSkiddingToXY(placement: Placement, rects: {
    popper: Rect;
    reference: Rect;
}, offset: Offset): Offsets;
export declare type OffsetModifier = Modifier<"offset", Options>;
declare const _default: OffsetModifier;
export default _default;


code:
import type { Modifier } from "../types";
export declare type PopperOffsetsModifier = Modifier<"popperOffsets", {}>;
declare const _default: PopperOffsetsModifier;
export default _default;


code:
import type { Placement, Boundary, RootBoundary } from "../enums";
import type { Rect, Modifier, Padding } from "../types";
declare type TetherOffset = ((arg0: {
    popper: Rect;
    reference: Rect;
    placement: Placement;
}) => number | {
    mainAxis: number;
    altAxis: number;
}) | number | {
    mainAxis: number;
    altAxis: number;
};
export declare type Options = {
    mainAxis: boolean;
    altAxis: boolean;
    boundary: Boundary;
    rootBoundary: RootBoundary;
    altBoundary: boolean;
    /**
     * Allows the popper to overflow from its boundaries to keep it near its
     * reference element
     */
    tether: boolean;
    tetherOffset: TetherOffset;
    padding: Padding;
};
export declare type PreventOverflowModifier = Modifier<"preventOverflow", Options>;
declare const _default: PreventOverflowModifier;
export default _default;