code:
declare class GraphemerHelper {
    /**
     * Check if the the character at the position {pos} of the string is surrogate
     * @param str {string}
     * @param pos {number}
     * @returns {boolean}
     */
    static isSurrogate(str: string, pos: number): boolean;
    /**
     * The String.prototype.codePointAt polyfill
     * Private function, gets a Unicode code point from a JavaScript UTF-16 string
     * handling surrogate pairs appropriately
     * @param str {string}
     * @param idx {number}
     * @returns {number}
     */
    static codePointAt(str: string, idx: number): number;
    /**
     * Private function, returns whether a break is allowed between the two given grapheme breaking classes
     * Implemented the UAX #29 3.1.1 Grapheme Cluster Boundary Rules on extended grapheme clusters
     * @param start {number}
     * @param mid {Array<number>}
     * @param end {number}
     * @param startEmoji {number}
     * @param midEmoji {Array<number>}
     * @param endEmoji {number}
     * @returns {number}
     */
    static shouldBreak(start: number, mid: number[], end: number, startEmoji: number, midEmoji: number[], endEmoji: number): number;
}
export default GraphemerHelper;
//# sourceMappingURL=GraphemerHelper.d.ts.map

license: mit


code:
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const boundaries_1 = require("./boundaries");
// BreakTypes
// @type {BreakType}
const NotBreak = 0;
const BreakStart = 1;
const Break = 2;
const BreakLastRegional = 3;
const BreakPenultimateRegional = 4;
class GraphemerHelper {
    /**
     * Check if the the character at the position {pos} of the string is surrogate
     * @param str {string}
     * @param pos {number}
     * @returns {boolean}
     */
    static isSurrogate(str, pos) {
        return (0xd800 <= str.charCodeAt(pos) &&
            str.charCodeAt(pos) <= 0xdbff &&
            0xdc00 <= str.charCodeAt(pos + 1) &&
            str.charCodeAt(pos + 1) <= 0xdfff);
    }
    /**
     * The String.prototype.codePointAt polyfill
     * Private function, gets a Unicode code point from a JavaScript UTF-16 string
     * handling surrogate pairs appropriately
     * @param str {string}
     * @param idx {number}
     * @returns {number}
     */
    static codePointAt(str, idx) {
        if (idx === undefined) {
            idx = 0;
        }
        const code = str.charCodeAt(idx);
        // if a high surrogate
        if (0xd800 <= code && code <= 0xdbff && idx < str.length - 1) {
            const hi = code;
            const low = str.charCodeAt(idx + 1);
            if (0xdc00 <= low && low <= 0xdfff) {
                return (hi - 0xd800) * 0x400 + (low - 0xdc00) + 0x10000;
            }
            return hi;
        }
        // if a low surrogate
        if (0xdc00 <= code && code <= 0xdfff && idx >= 1) {
            const hi = str.charCodeAt(idx - 1);
            const low = code;
            if (0xd800 <= hi && hi <= 0xdbff) {
                return (hi - 0xd800) * 0x400 + (low - 0xdc00) + 0x10000;
            }
            return low;
        }
        // just return the char if an unmatched surrogate half or a
        // single-char codepoint
        return code;
    }
    //
    /**
     * Private function, returns whether a break is allowed between the two given grapheme breaking classes
     * Implemented the UAX #29 3.1.1 Grapheme Cluster Boundary Rules on extended grapheme clusters
     * @param start {number}
     * @param mid {Array<number>}
     * @param end {number}
     * @param startEmoji {number}
     * @param midEmoji {Array<number>}
     * @param endEmoji {number}
     * @returns {number}
     */
    static shouldBreak(start, mid, end, startEmoji, midEmoji, endEmoji) {
        const all = [start].concat(mid).concat([end]);
        const allEmoji = [startEmoji].concat(midEmoji).concat([endEmoji]);
        const previous = all[all.length - 2];
        const next = end;
        const nextEmoji = endEmoji;
        // Lookahead terminator for:
        // GB12. ^ (RI RI)* RI ? RI
        // GB13. [^RI] (RI RI)* RI ? RI
        const rIIndex = all.lastIndexOf(boundaries_1.CLUSTER_BREAK.REGIONAL_INDICATOR);
        if (rIIndex > 0 &&
            all.slice(1, rIIndex).every(function (c) {
                return c === boundaries_1.CLUSTER_BREAK.REGIONAL_INDICATOR;
            }) &&
            [boundaries_1.CLUSTER_BREAK.PREPEND, boundaries_1.CLUSTER_BREAK.REGIONAL_INDICATOR].indexOf(previous) === -1) {
            if (all.filter(function (c) {
                return c === boundaries_1.CLUSTER_BREAK.REGIONAL_INDICATOR;
            }).length %
                2 ===
                1) {
                return BreakLastRegional;
            }
            else {
                return BreakPenultimateRegional;
            }
        }
        // GB3. CR × LF
        if (previous === boundaries_1.CLUSTER_BREAK.CR && next === boundaries_1.CLUSTER_BREAK.LF) {
            return NotBreak;
        }
        // GB4. (Control|CR|LF) ÷
        else if (previous === boundaries_1.CLUSTER_BREAK.CONTROL ||
            previous === boundaries_1.CLUSTER_BREAK.CR ||
            previous === boundaries_1.CLUSTER_BREAK.LF) {
            return BreakStart;
        }
        // GB5. ÷ (Control|CR|LF)
        else if (next === boundaries_1.CLUSTER_BREAK.CONTROL ||
            next === boundaries_1.CLUSTER_BREAK.CR ||
            next === boundaries_1.CLUSTER_BREAK.LF) {
            return BreakStart;
        }
        // GB6. L × (L|V|LV|LVT)
        else if (previous === boundaries_1.CLUSTER_BREAK.L &&
            (next === boundaries_1.CLUSTER_BREAK.L ||
                next === boundaries_1.CLUSTER_BREAK.V ||
                next === boundaries_1.CLUSTER_BREAK.LV ||
                next === boundaries_1.CLUSTER_BREAK.LVT)) {
            return NotBreak;
        }
        // GB7. (LV|V) × (V|T)
        else if ((previous === boundaries_1.CLUSTER_BREAK.LV || previous === boundaries_1.CLUSTER_BREAK.V) &&
            (next === boundaries_1.CLUSTER_BREAK.V || next === boundaries_1.CLUSTER_BREAK.T)) {
            return NotBreak;
        }
        // GB8. (LVT|T) × (T)
        else if ((previous === boundaries_1.CLUSTER_BREAK.LVT || previous === boundaries_1.CLUSTER_BREAK.T) &&
            next === boundaries_1.CLUSTER_BREAK.T) {
            return NotBreak;
        }
        // GB9. × (Extend|ZWJ)
        else if (next === boundaries_1.CLUSTER_BREAK.EXTEND || next === boundaries_1.CLUSTER_BREAK.ZWJ) {
            return NotBreak;
        }
        // GB9a. × SpacingMark
        else if (next === boundaries_1.CLUSTER_BREAK.SPACINGMARK) {
            return NotBreak;
        }
        // GB9b. Prepend ×
        else if (previous === boundaries_1.CLUSTER_BREAK.PREPEND) {
            return NotBreak;
        }
        // GB11. \p{Extended_Pictographic} Extend* ZWJ × \p{Extended_Pictographic}
        const previousNonExtendIndex = allEmoji
            .slice(0, -1)
            .lastIndexOf(boundaries_1.EXTENDED_PICTOGRAPHIC);
        if (previousNonExtendIndex !== -1 &&
            allEmoji[previousNonExtendIndex] === boundaries_1.EXTENDED_PICTOGRAPHIC &&
            all.slice(previousNonExtendIndex + 1, -2).every(function (c) {
                return c === boundaries_1.CLUSTER_BREAK.EXTEND;
            }) &&
            previous === boundaries_1.CLUSTER_BREAK.ZWJ &&
            nextEmoji === boundaries_1.EXTENDED_PICTOGRAPHIC) {
            return NotBreak;
        }
        // GB12. ^ (RI RI)* RI × RI
        // GB13. [^RI] (RI RI)* RI × RI
        if (mid.indexOf(boundaries_1.CLUSTER_BREAK.REGIONAL_INDICATOR) !== -1) {
            return Break;
        }
        if (previous === boundaries_1.CLUSTER_BREAK.REGIONAL_INDICATOR &&
            next === boundaries_1.CLUSTER_BREAK.REGIONAL_INDICATOR) {
            return NotBreak;
        }
        // GB999. Any ? Any
        return BreakStart;
    }
}
exports.default = GraphemerHelper;


code:
/**
 * GraphemerIterator
 *
 * Takes a string and a "BreakHandler" method during initialisation
 * and creates an iterable object that returns individual graphemes.
 *
 * @param str {string}
 * @return GraphemerIterator
 */
declare class GraphemerIterator implements Iterator<string> {
    private _index;
    private _str;
    private _nextBreak;
    constructor(str: string, nextBreak: (str: string, index: number) => number);
    [Symbol.iterator](): this;
    next(): {
        value: string;
        done: boolean;
    };
}
export default GraphemerIterator;
//# sourceMappingURL=GraphemerIterator.d.ts.map


code:
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
/**
 * GraphemerIterator
 *
 * Takes a string and a "BreakHandler" method during initialisation
 * and creates an iterable object that returns individual graphemes.
 *
 * @param str {string}
 * @return GraphemerIterator
 */
class GraphemerIterator {
    constructor(str, nextBreak) {
        this._index = 0;
        this._str = str;
        this._nextBreak = nextBreak;
    }
    [Symbol.iterator]() {
        return this;
    }
    next() {
        let brk;
        if ((brk = this._nextBreak(this._str, this._index)) < this._str.length) {
            const value = this._str.slice(this._index, brk);
            this._index = brk;
            return { value: value, done: false };
        }
        if (this._index < this._str.length) {
            const value = this._str.slice(this._index);
            this._index = this._str.length;
            return { value: value, done: false };
        }
        return { value: undefined, done: true };
    }
}
exports.default = GraphemerIterator;


code:
/**
 * The Grapheme_Cluster_Break property value
 * @see https://www.unicode.org/reports/tr29/#Default_Grapheme_Cluster_Table
 */
export declare enum CLUSTER_BREAK {
    CR = 0,
    LF = 1,
    CONTROL = 2,
    EXTEND = 3,
    REGIONAL_INDICATOR = 4,
    SPACINGMARK = 5,
    L = 6,
    V = 7,
    T = 8,
    LV = 9,
    LVT = 10,
    OTHER = 11,
    PREPEND = 12,
    E_BASE = 13,
    E_MODIFIER = 14,
    ZWJ = 15,
    GLUE_AFTER_ZWJ = 16,
    E_BASE_GAZ = 17
}
/**
 * The Emoji character property is an extension of UCD but shares the same namespace and structure
 * @see http://www.unicode.org/reports/tr51/tr51-14.html#Emoji_Properties_and_Data_Files
 *
 * Here we model Extended_Pictograhpic only to implement UAX #29 GB11
 * \p{Extended_Pictographic} Extend* ZWJ	×	\p{Extended_Pictographic}
 *
 * The Emoji character property should not be mixed with Grapheme_Cluster_Break since they are not exclusive
 */
export declare const EXTENDED_PICTOGRAPHIC = 101;
//# sourceMappingURL=boundaries.d.ts.map


code:
"use strict";
/**
 * The Grapheme_Cluster_Break property value
 * @see https://www.unicode.org/reports/tr29/#Default_Grapheme_Cluster_Table
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.EXTENDED_PICTOGRAPHIC = exports.CLUSTER_BREAK = void 0;
var CLUSTER_BREAK;
(function (CLUSTER_BREAK) {
    CLUSTER_BREAK[CLUSTER_BREAK["CR"] = 0] = "CR";
    CLUSTER_BREAK[CLUSTER_BREAK["LF"] = 1] = "LF";
    CLUSTER_BREAK[CLUSTER_BREAK["CONTROL"] = 2] = "CONTROL";
    CLUSTER_BREAK[CLUSTER_BREAK["EXTEND"] = 3] = "EXTEND";
    CLUSTER_BREAK[CLUSTER_BREAK["REGIONAL_INDICATOR"] = 4] = "REGIONAL_INDICATOR";
    CLUSTER_BREAK[CLUSTER_BREAK["SPACINGMARK"] = 5] = "SPACINGMARK";
    CLUSTER_BREAK[CLUSTER_BREAK["L"] = 6] = "L";
    CLUSTER_BREAK[CLUSTER_BREAK["V"] = 7] = "V";
    CLUSTER_BREAK[CLUSTER_BREAK["T"] = 8] = "T";
    CLUSTER_BREAK[CLUSTER_BREAK["LV"] = 9] = "LV";
    CLUSTER_BREAK[CLUSTER_BREAK["LVT"] = 10] = "LVT";
    CLUSTER_BREAK[CLUSTER_BREAK["OTHER"] = 11] = "OTHER";
    CLUSTER_BREAK[CLUSTER_BREAK["PREPEND"] = 12] = "PREPEND";
    CLUSTER_BREAK[CLUSTER_BREAK["E_BASE"] = 13] = "E_BASE";
    CLUSTER_BREAK[CLUSTER_BREAK["E_MODIFIER"] = 14] = "E_MODIFIER";
    CLUSTER_BREAK[CLUSTER_BREAK["ZWJ"] = 15] = "ZWJ";
    CLUSTER_BREAK[CLUSTER_BREAK["GLUE_AFTER_ZWJ"] = 16] = "GLUE_AFTER_ZWJ";
    CLUSTER_BREAK[CLUSTER_BREAK["E_BASE_GAZ"] = 17] = "E_BASE_GAZ";
})(CLUSTER_BREAK = exports.CLUSTER_BREAK || (exports.CLUSTER_BREAK = {}));
/**
 * The Emoji character property is an extension of UCD but shares the same namespace and structure
 * @see http://www.unicode.org/reports/tr51/tr51-14.html#Emoji_Properties_and_Data_Files
 *
 * Here we model Extended_Pictograhpic only to implement UAX #29 GB11
 * \p{Extended_Pictographic} Extend* ZWJ	×	\p{Extended_Pictographic}
 *
 * The Emoji character property should not be mixed with Grapheme_Cluster_Break since they are not exclusive
 */
exports.EXTENDED_PICTOGRAPHIC = 101;


code:
import Graphemer from './Graphemer';
export default Graphemer;
//# sourceMappingURL=index.d.ts.map


code:
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const Graphemer_1 = __importDefault(require("./Graphemer"));
exports.default = Graphemer_1.default;


graphemer

description: A JavaScript library that breaks strings into their individual user-perceived characters (including emojis!)

author: Matt Davies <matt@filament.so> (https://github.com/mattpauldavies)

license: MIT

keywords: utf-8 strings emoji split

prepublishOnly: npm run build

build: tsc --project tsconfig.json

pretest: npm run build

prettier:check: prettier --check .

prettier:fix: prettier --write .

type: git

pre-commit: lint-staged

pre-push: npm test

*.{js,ts,md,json}: prettier --write


code:
/// <reference types="node"/>
import * as stream from 'stream';
import {ZlibOptions} from 'zlib';

declare namespace gzipSize {
	type Options = ZlibOptions;

	interface GzipSizeStream extends stream.PassThrough {
		/**
		Contains the gzip size of the stream after it is finished. Since this happens asynchronously, it is recommended you use the `gzip-size` event instead.
		*/
		gzipSize?: number;

		addListener(event: 'gzip-size', listener: (size: number) => void): this;
		addListener(
			event: string | symbol,
			listener: (...args: any[]) => void
		): this;
		on(event: 'gzip-size', listener: (size: number) => void): this;
		on(event: string | symbol, listener: (...args: any[]) => void): this;
		once(event: 'gzip-size', listener: (size: number) => void): this;
		once(event: string | symbol, listener: (...args: any[]) => void): this;
		removeListener(event: 'gzip-size', listener: (size: number) => void): this;
		removeListener(
			event: string | symbol,
			listener: (...args: any[]) => void
		): this;
		off(event: 'gzip-size', listener: (size: number) => void): this;
		off(event: string | symbol, listener: (...args: any[]) => void): this;
		emit(event: 'gzip-size', size: number): boolean;
		emit(event: string | symbol, ...args: any[]): boolean;
		prependListener(event: 'gzip-size', listener: (size: number) => void): this;
		prependListener(
			event: string | symbol,
			listener: (...args: any[]) => void
		): this;
		prependOnceListener(
			event: 'gzip-size',
			listener: (size: number) => void
		): this;
		prependOnceListener(
			event: string | symbol,
			listener: (...args: any[]) => void
		): this;
	}
}

declare const gzipSize: {
	/**
	Get the gzipped size of a string or buffer.

	@returns The gzipped size of `input`.
	*/
	(input: string | Buffer, options?: gzipSize.Options): Promise<number>;

	/**
	Synchronously get the gzipped size of a string or buffer.

	@returns The gzipped size of `input`.

	@example
	```
	import gzipSize = require('gzip-size');

	const text = 'Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.';

	console.log(text.length);
	//=> 191

	console.log(gzipSize.sync(text));
	//=> 78
	```
	*/
	sync(input: string | Buffer, options?: gzipSize.Options): number;

	/**
	@returns A stream that emits a `gzip-size` event and has a `gzipSize` property.
	*/
	stream(options?: gzipSize.Options): gzipSize.GzipSizeStream;

	/**
	Get the gzipped size of a file.

	@returns The size of the file.
	*/
	file(path: string, options?: gzipSize.Options): Promise<number>;

	/**
	Synchronously get the gzipped size of a file.

	@returns The size of the file.
	*/
	fileSync(path: string, options?: gzipSize.Options): number;
};

export = gzipSize;


code:
'use strict';
const fs = require('fs');
const stream = require('stream');
const zlib = require('zlib');
const {promisify} = require('util');
const duplexer = require('duplexer');

const getOptions = options => ({level: 9, ...options});
const gzip = promisify(zlib.gzip);

module.exports = async (input, options) => {
	if (!input) {
		return 0;
	}

	const data = await gzip(input, getOptions(options));
	return data.length;
};

module.exports.sync = (input, options) => zlib.gzipSync(input, getOptions(options)).length;

module.exports.stream = options => {
	const input = new stream.PassThrough();
	const output = new stream.PassThrough();
	const wrapper = duplexer(input, output);

	let gzipSize = 0;
	const gzip = zlib.createGzip(getOptions(options))
		.on('data', buf => {
			gzipSize += buf.length;
		})
		.on('error', () => {
			wrapper.gzipSize = 0;
		})
		.on('end', () => {
			wrapper.gzipSize = gzipSize;
			wrapper.emit('gzip-size', gzipSize);
			output.end();
		});

	input.pipe(gzip);
	input.pipe(output, {end: false});

	return wrapper;
};

module.exports.file = (path, options) => {
	return new Promise((resolve, reject) => {
		const stream = fs.createReadStream(path);
		stream.on('error', reject);

		const gzipStream = stream.pipe(module.exports.stream(options));
		gzipStream.on('error', reject);
		gzipStream.on('gzip-size', resolve);
	});
};

module.exports.fileSync = (path, options) => module.exports.sync(fs.readFileSync(path), options);


gzip-size

description: Get the gzipped size of a string or buffer

repository: sindresorhus/gzip-size

test: xo && ava && tsd

keywords: app tool zlib gzip compressed size string buffer


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

> Get the gzipped size of a string or buffer

## Install

```
$ npm install gzip-size
```

## Usage

```js
const gzipSize = require('gzip-size');

const text = 'Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.';

console.log(text.length);
//=> 191

console.log(gzipSize.sync(text));
//=> 78
```

## API

### gzipSize(input, options?)

Returns a `Promise<number>` with the size.

### gzipSize.sync(input, options?)

Returns the size.

#### input

Type: `string | Buffer`

#### options

Type: `object`

Any [`zlib` option](https://nodejs.org/api/zlib.html#zlib_class_options).

### gzipSize.stream(options?)

Returns a [`stream.PassThrough`](https://nodejs.org/api/stream.html#stream_class_stream_passthrough). The stream emits a `gzip-size` event and has a `gzipSize` property.

### gzipSize.file(path, options?)

Returns a `Promise<number>` with the size of the file.

#### path

Type: `string`

### gzipSize.fileSync(path, options?)

Returns the size of the file.

## Related

- [gzip-size-cli](https://github.com/sindresorhus/gzip-size-cli) - CLI for this module

---

		Get professional support for this package with a Tidelift subscription

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


code:
sudo: false

language: node_js

node_js:
  - "6"
  - "8"
  - "10"
  - "11.1"
  - "12"

script:
  - npm run lint
  - npm test
  - npm run coverage


code:
# Handle Thing

[![Build Status](https://travis-ci.org/spdy-http2/handle-thing.svg?branch=master)](http://travis-ci.org/spdy-http2/handle-thing)
[![NPM version](https://badge.fury.io/js/handle-thing.svg)](http://badge.fury.io/js/handle-thing)
[![dependencies Status](https://david-dm.org/spdy-http2/handle-thing/status.svg?style=flat-square)](https://david-dm.org/spdy-http2/handle-thing)
[![Standard - JavaScript Style Guide](https://img.shields.io/badge/code_style-standard-brightgreen.svg?style=flat-square)](http://standardjs.com/)
[![Waffle](https://img.shields.io/badge/track-waffle-blue.svg?style=flat-square)](https://waffle.io/spdy-http2/node-spdy)

> Wrap Streams2 instance into a HandleWrap. The right thing when you need it

## Usage

### Examples

`soon™`

### API

`soon™`

## LICENSE

This software is licensed under the MIT License.

Copyright Fedor Indutny, 2015.

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.


code:
var assert = require('assert')
var util = require('util')

var EventEmitter = require('events').EventEmitter
var Buffer = require('buffer').Buffer

var Queue = require('./queue')

// Node.js version
var match = /^v(\d+)\.(\d+)\./.exec(process.version)
var version = match ? Number(match[1]) + Number('0.' + match[2]) : 11
var onreadMode = version >= 11.1 ? 2 : 1
var mode = 'modern'

var setNRead
if (onreadMode === 2) {
  var sw = process.binding('stream_wrap')
  setNRead = function (nread) {
    sw.streamBaseState[sw.kReadBytesOrError] = nread
  }
}

function Handle (stream, options) {
  EventEmitter.call(this)

  this._stream = stream
  this._flowing = false
  this._reading = false
  this._options = options || {}

  this.onread = null

  // Pending requests
  this.pending = new Queue()
}
util.inherits(Handle, EventEmitter)
module.exports = Handle

Handle.mode = mode

Handle.create = function create (stream, options) {
  return new Handle(stream, options)
}

Handle.prototype._onread = function _onread (nread, buffer) {
  if (onreadMode === 1) {
    this.onread(nread, buffer)
  } else {
    setNRead(nread)
    this.onread(buffer)
  }
}

Handle.prototype._queueReq = function _queueReq (type, req) {
  return this.pending.append(type, req)
}

Handle.prototype._pendingList = function _pendingList () {
  var list = []
  while (!this.pending.isEmpty()) { list.push(this.pending.first().dequeue()) }
  return list
}

Handle.prototype.setStream = function setStream (stream) {
  assert(this._stream === null, 'Can\'t set stream two times')
  this._stream = stream

  this.emit('stream', stream)
}

Handle.prototype.readStart = function readStart () {
  this._reading = true

  if (!this._stream) {
    this.once('stream', this.readStart)
    return 0
  }

  if (!this._flowing) {
    this._flowing = true
    this._flow()
  }

  this._stream.resume()
  return 0
}

Handle.prototype.readStop = function readStop () {
  this._reading = false

  if (!this._stream) {
    this.once('stream', this.readStop)
    return 0
  }
  this._stream.pause()
  return 0
}

var uv = process.binding('uv')

Handle.prototype._flow = function flow () {
  var self = this
  this._stream.on('data', function (chunk) {
    self._onread(chunk.length, chunk)
  })

  this._stream.on('end', function () {
    self._onread(uv.UV_EOF, Buffer.alloc(0))
  })

  this._stream.on('close', function () {
    setImmediate(function () {
      if (self._reading) {
        self._onread(uv.UV_ECONNRESET, Buffer.alloc(0))
      }
    })
  })
}

Handle.prototype._close = function _close () {
  var list = this._pendingList()

  var self = this
  setImmediate(function () {
    for (var i = 0; i < list.length; i++) {
      var req = list[i]
      req.oncomplete(uv.UV_ECANCELED, self, req)
    }
  })

  this.readStop()
}

Handle.prototype.shutdown = function shutdown (req) {
  var wrap = this._queueReq('shutdown', req)

  if (!this._stream) {
    this.once('stream', function () {
      this._shutdown(wrap)
    })
    return 0
  }

  return this._shutdown(wrap)
}

Handle.prototype._shutdown = function _shutdown (wrap) {
  var self = this
  this._stream.end(function () {
    var req = wrap.dequeue()
    if (!req) { return }

    req.oncomplete(0, self, req)
  })
  return 0
}

Handle.prototype.close = function close (callback) {
  this._close()

  if (!this._stream) {
    this.once('stream', function () {
      this.close(callback)
    })
    return 0
  }

  if (this._options.close) {
    this._options.close(callback)
  } else {
    process.nextTick(callback)
  }

  return 0
}

Handle.prototype.writeEnc = function writeEnc (req, data, enc) {
  var wrap = this._queueReq('write', req)

  if (!this._stream) {
    this.once('stream', function () {
      this._writeEnc(wrap, req, data, enc)
    })

    return 0
  }

  return this._writeEnc(wrap, req, data, enc)
}

Handle.prototype._writeEnc = function _writeEnc (wrap, req, data, enc) {
  var self = this

  req.async = true
  req.bytes = data.length

  if (wrap.isEmpty()) {
    return 0
  }

  this._stream.write(data, enc, function () {
    var req = wrap.dequeue()
    if (!req) { return }
    req.oncomplete(0, self, req)
  })

  return 0
}

/**
 * @param {WriteWrap} req
 * @param {string[]} chunks
 * @param {Boolean} allBuffers
 */
Handle.prototype.writev = function _writev (req, chunks, allBuffers) {
  while (chunks.length > 0) {
    this._stream.write(chunks.shift(), chunks.shift())
  }
  return 0
}

Handle.prototype.writeBuffer = function writeBuffer (req, data) {
  return this.writeEnc(req, data, null)
}

Handle.prototype.writeAsciiString = function writeAsciiString (req, data) {
  return this.writeEnc(req, data, 'ascii')
}

Handle.prototype.writeUtf8String = function writeUtf8String (req, data) {
  return this.writeEnc(req, data, 'utf8')
}

Handle.prototype.writeUcs2String = function writeUcs2String (req, data) {
  return this.writeEnc(req, data, 'ucs2')
}

Handle.prototype.writeBinaryString = function writeBinaryString (req, data) {
  return this.writeEnc(req, data, 'binary')
}

Handle.prototype.writeLatin1String = function writeLatin1String (req, data) {
  return this.writeEnc(req, data, 'binary')
}

// v0.8
Handle.prototype.getsockname = function getsockname () {
  if (this._options.getPeerName) {
    return this._options.getPeerName()
  }
  return null
}

Handle.prototype.getpeername = function getpeername (out) {
  var res = this.getsockname()
  if (!res) { return -1 }

  Object.keys(res).forEach(function (key) {
    out[key] = res[key]
  })

  return 0
}


code:
function Queue () {
  this.head = new Item('head', null)
}
module.exports = Queue

Queue.prototype.append = function append (kind, value) {
  var item = new Item(kind, value)
  this.head.prepend(item)
  return item
}

Queue.prototype.isEmpty = function isEmpty () {
  return this.head.prev === this.head
}

Queue.prototype.first = function first () {
  return this.head.next
}

function Item (kind, value) {
  this.prev = this
  this.next = this
  this.kind = kind
  this.value = value
}

Item.prototype.prepend = function prepend (other) {
  other.prev = this.prev
  other.next = this
  other.prev.next = other
  other.next.prev = other
}

Item.prototype.dequeue = function dequeue () {
  var prev = this.prev
  var next = this.next

  prev.next = next
  next.prev = prev
  this.prev = this
  this.next = this

  return this.value
}

Item.prototype.isEmpty = function isEmpty () {
  return this.prev === this
}


handle-thing

description: Wrap Streams2 instance into a HandleWrap

lint: standard

test: mocha --reporter=spec test/*-test.js

coverage: istanbul cover node_modules/.bin/_mocha -- --reporter=spec test/**/*-test.js

pre-commit: lint test

keywords: handle net streams2

author: Fedor Indutny <fedor@indutny.com>


code:
/* eslint-env mocha */

var assert = require('assert')
var net = require('net')
var streamPair = require('stream-pair')

var thing = require('../')

describe('Handle Thing', function () {
  var handle
  var pair
  var socket;

  [ 'normal', 'lazy' ].forEach(function (mode) {
    describe(mode, function () {
      beforeEach(function () {
        pair = streamPair.create()
        handle = thing.create(mode === 'normal' ? pair.other : null)
        socket = new net.Socket({
          handle: handle,
          readable: true,
          writable: true
        })

        if (mode === 'lazy') {
          setTimeout(function () {
            handle.setStream(pair.other)
          }, 50)
        }
      })

      afterEach(function () {
        assert(handle._stream)
      })

      it('should write data to Socket', function (done) {
        pair.write('hello')
        pair.write(' world')
        pair.end('... ok')

        var chunks = ''
        socket.on('data', function (chunk) {
          chunks += chunk
        })
        socket.on('end', function () {
          assert.strictEqual(chunks, 'hello world... ok')

          // allowHalfOpen is `false`, so the `end` should be followed by `close`
          socket.once('close', function () {
            done()
          })
        })
      })

      it('should read data from Socket', function (done) {
        socket.write('hello')
        socket.write(' world')
        socket.end('... ok')

        var chunks = ''
        pair.on('data', function (chunk) {
          chunks += chunk
        })
        pair.on('end', function () {
          assert.strictEqual(chunks, 'hello world... ok')

          done()
        })
      })

      it('should invoke `close` callback', function (done) {
        handle._options.close = function (callback) {
          done()
          process.nextTick(callback)
        }

        pair.end('hello')
        socket.resume()
      })

      it('should kill pending requests', function (done) {
        handle._options.close = function () {
          setTimeout(done, 75)
        }

        socket.write('hello')
        socket.destroy()
      })

      if (mode === 'normal') {
        it('should invoke `getPeerName` callback', function () {
          handle._options.getPeerName = function () {
            return { address: 'ohai' }
          }

          assert.strictEqual(socket.remoteAddress, 'ohai')
        })

        it('should emit ECONNRESET at `close` event', function (done) {
          pair.other.emit('close')

          socket.on('error', function (err) {
            assert(/ECONNRESET/.test(err.message))
            done()
          })
        })
      }
    })
  })
})


code:
'use strict';
module.exports = (flag, argv) => {
	argv = argv || process.argv;
	const prefix = flag.startsWith('-') ? '' : (flag.length === 1 ? '-' : '--');
	const pos = argv.indexOf(prefix + flag);
	const terminatorPos = argv.indexOf('--');
	return pos !== -1 && (terminatorPos === -1 ? true : pos < terminatorPos);
};


has-flag

description: Check if argv has a specific flag

repository: sindresorhus/has-flag

test: xo && ava

keywords: has check detect contains find flag cli command-line argv process arg args argument arguments getopt minimist optimist


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

> Check if [`argv`](https://nodejs.org/docs/latest/api/process.html#process_process_argv) has a specific flag

Correctly stops looking after an `--` argument terminator.

## Install

```
$ npm install has-flag
```

## Usage

```js
// foo.js
const hasFlag = require('has-flag');

hasFlag('unicorn');
//=> true

hasFlag('--unicorn');
//=> true

hasFlag('f');
//=> true

hasFlag('-f');
//=> true

hasFlag('foo=bar');
//=> true

hasFlag('foo');
//=> false

hasFlag('rainbow');
//=> false
```

```
$ node foo.js -f --unicorn --foo=bar -- --rainbow
```

## API

### hasFlag(flag, [argv])

Returns a boolean for whether the flag exists.

#### flag

Type: `string`

CLI flag to look for. The `--` prefix is optional.

#### argv

Type: `string[]`<br>
Default: `process.argv`

CLI arguments.

## License

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


code:
{
	"root": true,

	"extends": "@ljharb",

	"rules": {
		"func-name-matching": 0,
		"id-length": 0,
		"new-cap": [2, {
			"capIsNewExceptions": ["GetIntrinsic"],
		}],
	},
}


code:
# These are supported funding model platforms

github: [ljharb]
patreon: # Replace with a single Patreon username
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
tidelift: npm/has-property-descriptors
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']


reporter: text-summary text html json

exclude: coverage test


code:
# Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [v1.0.2](https://github.com/inspect-js/has-property-descriptors/compare/v1.0.1...v1.0.2) - 2024-02-12

### Commits

- [Refactor] use `es-define-property` [`f93a8c8`](https://github.com/inspect-js/has-property-descriptors/commit/f93a8c85eba70cbceab500f2619fb5cce73a1805)
- [Dev Deps] update `aud`, `npmignore`, `tape` [`42b0c9d`](https://github.com/inspect-js/has-property-descriptors/commit/42b0c9d1c23e747755f0f2924923c418ea34a9ee)
- [Deps] update `get-intrinsic` [`35e9b46`](https://github.com/inspect-js/has-property-descriptors/commit/35e9b46a7f14331bf0de98b644dd803676746037)

## [v1.0.1](https://github.com/inspect-js/has-property-descriptors/compare/v1.0.0...v1.0.1) - 2023-10-20

### Commits

- [meta] use `npmignore` to autogenerate an npmignore file [`5bbf4da`](https://github.com/inspect-js/has-property-descriptors/commit/5bbf4dae1b58950d87bb3af508bee7513e640868)
- [actions] update rebase action to use reusable workflow [`3a5585b`](https://github.com/inspect-js/has-property-descriptors/commit/3a5585bf74988f71a8f59e67a07d594e62c51fd8)
- [Dev Deps] update `@ljharb/eslint-config`, `aud`, `tape` [`e5c1212`](https://github.com/inspect-js/has-property-descriptors/commit/e5c1212048a8fda549794c47863724ca60b89cae)
- [Dev Deps] update `aud`, `tape` [`e942917`](https://github.com/inspect-js/has-property-descriptors/commit/e942917b6c2f7c090d5623048989cf20d0834ebf)
- [Deps] update `get-intrinsic` [`f4a44ec`](https://github.com/inspect-js/has-property-descriptors/commit/f4a44ec6d94146fa6c550d3c15c31a2062c83ef4)
- [Deps] update `get-intrinsic` [`eeb275b`](https://github.com/inspect-js/has-property-descriptors/commit/eeb275b473e5d72ca843b61ca25cfcb06a5d4300)

## v1.0.0 - 2022-04-14

### Commits

- Initial implementation, tests [`303559f`](https://github.com/inspect-js/has-property-descriptors/commit/303559f2a72dfe7111573a1aec475ed4a184c35a)
- Initial commit [`3a7ca2d`](https://github.com/inspect-js/has-property-descriptors/commit/3a7ca2dc49f1fff0279a28bb16265e7615e14749)
- read me [`dd73dce`](https://github.com/inspect-js/has-property-descriptors/commit/dd73dce09d89d0f7a4a6e3b1e562a506f979a767)
- npm init [`c1e6557`](https://github.com/inspect-js/has-property-descriptors/commit/c1e655779de632d68cb944c50da6b71bcb7b8c85)
- Only apps should have lockfiles [`e72f7c6`](https://github.com/inspect-js/has-property-descriptors/commit/e72f7c68de534b2d273ee665f8b18d4ecc7f70b0)


code:
# has-property-descriptors <sup>[![Version Badge][npm-version-svg]][package-url]</sup>

[![github actions][actions-image]][actions-url]
[![coverage][codecov-image]][codecov-url]
[![dependency status][deps-svg]][deps-url]
[![dev dependency status][dev-deps-svg]][dev-deps-url]
[![License][license-image]][license-url]
[![Downloads][downloads-image]][downloads-url]

[![npm badge][npm-badge-png]][package-url]

Does the environment have full property descriptor support? Handles IE 8's broken defineProperty/gOPD.

## Example

```js
var hasPropertyDescriptors = require('has-property-descriptors');
var assert = require('assert');

assert.equal(hasPropertyDescriptors(), true); // will be `false` in IE 6-8, and ES5 engines

// Arrays can not have their length `[[Defined]]` in some engines
assert.equal(hasPropertyDescriptors.hasArrayLengthDefineBug(), false); // will be `true` in Firefox 4-22, and node v0.6
```

## Tests
Simply clone the repo, `npm install`, and run `npm test`

[package-url]: https://npmjs.org/package/has-property-descriptors
[npm-version-svg]: https://versionbadg.es/inspect-js/has-property-descriptors.svg
[deps-svg]: https://david-dm.org/inspect-js/has-property-descriptors.svg
[deps-url]: https://david-dm.org/inspect-js/has-property-descriptors
[dev-deps-svg]: https://david-dm.org/inspect-js/has-property-descriptors/dev-status.svg
[dev-deps-url]: https://david-dm.org/inspect-js/has-property-descriptors#info=devDependencies
[npm-badge-png]: https://nodei.co/npm/has-property-descriptors.png?downloads=true&stars=true
[license-image]: https://img.shields.io/npm/l/has-property-descriptors.svg
[license-url]: LICENSE
[downloads-image]: https://img.shields.io/npm/dm/has-property-descriptors.svg
[downloads-url]: https://npm-stat.com/charts.html?package=has-property-descriptors
[codecov-image]: https://codecov.io/gh/inspect-js/has-property-descriptors/branch/main/graphs/badge.svg
[codecov-url]: https://app.codecov.io/gh/inspect-js/has-property-descriptors/
[actions-image]: https://img.shields.io/endpoint?url=https://github-actions-badge-u3jn4tfpocch.runkit.sh/inspect-js/has-property-descriptors
[actions-url]: https://github.com/inspect-js/has-property-descriptors/actions


code:
'use strict';

var $defineProperty = require('es-define-property');

var hasPropertyDescriptors = function hasPropertyDescriptors() {
	return !!$defineProperty;
};

hasPropertyDescriptors.hasArrayLengthDefineBug = function hasArrayLengthDefineBug() {
	// node v0.6 has a bug where array lengths can be Set but not Defined
	if (!$defineProperty) {
		return null;
	}
	try {
		return $defineProperty([], 'length', { value: 1 }).length !== 1;
	} catch (e) {
		// In Firefox 4-22, defining length on an array throws an exception.
		return true;
	}
};

module.exports = hasPropertyDescriptors;


has-property-descriptors

description: Does the environment have full property descriptor support? Handles IE 8's broken defineProperty/gOPD.

prepublishOnly: safe-publish-latest

prepublish: not-in-publish || npm run prepublishOnly

pretest: npm run lint

prelint: evalmd README.md

lint: eslint --ext=js,mjs .

tests-only: nyc tape 'test/**/*.js'

test: npm run tests-only

posttest: aud --production

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

postversion: auto-changelog && git add CHANGELOG.md && git commit --no-edit --amend && git tag -f "v$(node -e "console.log(require('./package.json').version)")"

keywords: property descriptors has environment env defineProperty getOwnPropertyDescriptor

author: Jordan Harband <ljharb@gmail.com>

output: CHANGELOG.md

template: keepachangelog


code:
'use strict';

var test = require('tape');

var hasPropertyDescriptors = require('../');

var sentinel = {};

test('hasPropertyDescriptors', function (t) {
	t.equal(typeof hasPropertyDescriptors, 'function', 'is a function');
	t.equal(typeof hasPropertyDescriptors.hasArrayLengthDefineBug, 'function', '`hasArrayLengthDefineBug` property is a function');

	var yes = hasPropertyDescriptors();
	t.test('property descriptors', { skip: !yes }, function (st) {
		var o = { a: sentinel };

		st.deepEqual(
			Object.getOwnPropertyDescriptor(o, 'a'),
			{
				configurable: true,
				enumerable: true,
				value: sentinel,
				writable: true
			},
			'has expected property descriptor'
		);

		Object.defineProperty(o, 'a', { enumerable: false, writable: false });

		st.deepEqual(
			Object.getOwnPropertyDescriptor(o, 'a'),
			{
				configurable: true,
				enumerable: false,
				value: sentinel,
				writable: false
			},
			'has expected property descriptor after [[Define]]'
		);

		st.end();
	});

	var arrayBug = hasPropertyDescriptors.hasArrayLengthDefineBug();
	t.test('defining array lengths', { skip: !yes || arrayBug }, function (st) {
		var arr = [1, , 3]; // eslint-disable-line no-sparse-arrays
		st.equal(arr.length, 3, 'array starts with length 3');

		Object.defineProperty(arr, 'length', { value: 5 });

		st.equal(arr.length, 5, 'array ends with length 5');

		st.end();
	});

	t.end();
});


code:
{
	"root": true,

	"extends": "@ljharb",
}


code:
# These are supported funding model platforms

github: [ljharb]
patreon: # Replace with a single Patreon username
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
tidelift: npm/has-proto
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']


code:
# Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [v1.0.3](https://github.com/inspect-js/has-proto/compare/v1.0.2...v1.0.3) - 2024-02-19

### Commits

- [types] add missing declaration file [`26ecade`](https://github.com/inspect-js/has-proto/commit/26ecade05d253bb5dc376945ee3186d1fbe334f8)

## [v1.0.2](https://github.com/inspect-js/has-proto/compare/v1.0.1...v1.0.2) - 2024-02-19

### Commits

- add types [`6435262`](https://github.com/inspect-js/has-proto/commit/64352626cf511c0276d5f4bb6be770a0bf0f8524)
- [Dev Deps] update `@ljharb/eslint-config`, `aud`, `npmignore`, `tape` [`f16a5e4`](https://github.com/inspect-js/has-proto/commit/f16a5e4121651e551271419f9d60fdd3561fd82c)
- [Refactor] tiny cleanup [`d1f1a4b`](https://github.com/inspect-js/has-proto/commit/d1f1a4bdc135f115a10f148ce302676224534702)
- [meta] add `sideEffects` flag [`e7ab1a6`](https://github.com/inspect-js/has-proto/commit/e7ab1a6f153b3e80dee68d1748b71e46767a0531)

## [v1.0.1](https://github.com/inspect-js/has-proto/compare/v1.0.0...v1.0.1) - 2022-12-21

### Commits

- [meta] correct URLs and description [`ef34483`](https://github.com/inspect-js/has-proto/commit/ef34483ca0d35680f271b6b96e35526151b25dfc)
- [patch] add an additional criteria [`e81959e`](https://github.com/inspect-js/has-proto/commit/e81959ed7c7a77fbf459f00cb4ef824f1099497f)
- [Dev Deps] update `aud` [`2bec2c4`](https://github.com/inspect-js/has-proto/commit/2bec2c47b072b122ff5443fba0263f6dc649531f)

## v1.0.0 - 2022-12-12

### Commits

- Initial implementation, tests, readme [`6886fea`](https://github.com/inspect-js/has-proto/commit/6886fea578f67daf69a7920b2eb7637ea6ebb0bc)
- Initial commit [`99129c8`](https://github.com/inspect-js/has-proto/commit/99129c8f42471ac89cb681ba9cb9d52a583eb94f)
- npm init [`2844ad8`](https://github.com/inspect-js/has-proto/commit/2844ad8e75b84d66a46765b3bab9d2e8ea692e10)
- Only apps should have lockfiles [`c65bc5e`](https://github.com/inspect-js/has-proto/commit/c65bc5e40b9004463f7336d47c67245fb139a36a)


code:
# has-proto <sup>[![Version Badge][npm-version-svg]][package-url]</sup>

[![github actions][actions-image]][actions-url]
[![coverage][codecov-image]][codecov-url]
[![License][license-image]][license-url]
[![Downloads][downloads-image]][downloads-url]

[![npm badge][npm-badge-png]][package-url]

Does this environment have the ability to set the [[Prototype]] of an object on creation with `__proto__`?

## Example

```js
var hasProto = require('has-proto');
var assert = require('assert');

assert.equal(typeof hasProto(), 'boolean');
```

## Tests
Simply clone the repo, `npm install`, and run `npm test`

[package-url]: https://npmjs.org/package/has-proto
[npm-version-svg]: https://versionbadg.es/inspect-js/has-proto.svg
[deps-svg]: https://david-dm.org/inspect-js/has-proto.svg
[deps-url]: https://david-dm.org/inspect-js/has-proto
[dev-deps-svg]: https://david-dm.org/inspect-js/has-proto/dev-status.svg
[dev-deps-url]: https://david-dm.org/inspect-js/has-proto#info=devDependencies
[npm-badge-png]: https://nodei.co/npm/has-proto.png?downloads=true&stars=true
[license-image]: https://img.shields.io/npm/l/has-proto.svg
[license-url]: LICENSE
[downloads-image]: https://img.shields.io/npm/dm/has-proto.svg
[downloads-url]: https://npm-stat.com/charts.html?package=has-proto
[codecov-image]: https://codecov.io/gh/inspect-js/has-proto/branch/main/graphs/badge.svg
[codecov-url]: https://app.codecov.io/gh/inspect-js/has-proto/
[actions-image]: https://img.shields.io/endpoint?url=https://github-actions-badge-u3jn4tfpocch.runkit.sh/inspect-js/has-proto
[actions-url]: https://github.com/inspect-js/has-proto/actions


code:
declare function hasProto(): boolean;

export = hasProto;


code:
'use strict';

var test = {
	__proto__: null,
	foo: {}
};

var $Object = Object;

/** @type {import('.')} */
module.exports = function hasProto() {
	// @ts-expect-error: TS errors on an inherited property for some reason
	return { __proto__: test }.foo === test.foo
		&& !(test instanceof $Object);
};


has-proto

description: Does this environment have the ability to get the [[Prototype]] of an object on creation with `__proto__`?

postlint: tsc -p .

tests-only: tape 'test/**/*.js'

keywords: prototype proto set get __proto__ getPrototypeOf setPrototypeOf has

typescript: next

output: CHANGELOG.md


code:
'use strict';

var test = require('tape');
var hasProto = require('../');

test('hasProto', function (t) {
	var result = hasProto();
	t.equal(typeof result, 'boolean', 'returns a boolean (' + result + ')');

	var obj = { __proto__: null };
	if (result) {
		t.notOk('toString' in obj, 'null object lacks toString');
	} else {
		t.ok('toString' in obj, 'without proto, null object has toString');
		t.equal(obj.__proto__, null); // eslint-disable-line no-proto
	}

	t.end();
});


code:
{
  "compilerOptions": {
    /* Visit https://aka.ms/tsconfig to read more about this file */

    /* Projects */

    /* Language and Environment */
    "target": "ESNext",                                  /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
    // "lib": [],                                        /* Specify a set of bundled library declaration files that describe the target runtime environment. */
    // "noLib": true,                                    /* Disable including any library files, including the default lib.d.ts. */
    "useDefineForClassFields": true,                     /* Emit ECMAScript-standard-compliant class fields. */
    // "moduleDetection": "auto",                        /* Control what method is used to detect module-format JS files. */

    /* Modules */
    "module": "commonjs",                                /* Specify what module code is generated. */
    // "rootDir": "./",                                  /* Specify the root folder within your source files. */
    // "moduleResolution": "node10",                     /* Specify how TypeScript looks up a file from a given module specifier. */
    // "baseUrl": "./",                                  /* Specify the base directory to resolve non-relative module names. */
    // "paths": {},                                      /* Specify a set of entries that re-map imports to additional lookup locations. */
    // "rootDirs": [],                                   /* Allow multiple folders to be treated as one when resolving modules. */
    "typeRoots": ["types"],                              /* Specify multiple folders that act like './node_modules/@types'. */
    "resolveJsonModule": true,                           /* Enable importing .json files. */
    // "allowArbitraryExtensions": true,                 /* Enable importing files with any extension, provided a declaration file is present. */

    /* JavaScript Support */
    "allowJs": true,                                     /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */
    "checkJs": true,                                     /* Enable error reporting in type-checked JavaScript files. */
    "maxNodeModuleJsDepth": 0,                           /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */

    /* Emit */
    "declaration": true,                                 /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
    "declarationMap": true,                              /* Create sourcemaps for d.ts files. */
    "noEmit": true,                                      /* Disable emitting files from a compilation. */

    /* Interop Constraints */
    "allowSyntheticDefaultImports": true,                /* Allow 'import x from y' when a module doesn't have a default export. */
    "esModuleInterop": true,                             /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */
    "forceConsistentCasingInFileNames": true,            /* Ensure that casing is correct in imports. */

    /* Type Checking */
    "strict": true,                                      /* Enable all strict type-checking options. */

    /* Completeness */
    //"skipLibCheck": true                                 /* Skip type checking all .d.ts files. */
  },
  "exclude": [
    "coverage"
  ]
}


code:
{
	"root": true,

	"extends": "@ljharb",

	"rules": {
		"max-statements-per-line": [2, { "max": 2 }],
		"no-magic-numbers": 0,
		"multiline-comment-style": 0,
	}
}


code:
# These are supported funding model platforms

github: [ljharb]
patreon: # Replace with a single Patreon username
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
tidelift: npm/has-symbols
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']


code:
# Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [v1.0.3](https://github.com/inspect-js/has-symbols/compare/v1.0.2...v1.0.3) - 2022-03-01

### Commits

- [actions] use `node/install` instead of `node/run`; use `codecov` action [`518b28f`](https://github.com/inspect-js/has-symbols/commit/518b28f6c5a516cbccae30794e40aa9f738b1693)
- [meta] add `bugs` and `homepage` fields; reorder package.json [`c480b13`](https://github.com/inspect-js/has-symbols/commit/c480b13fd6802b557e1cef9749872cb5fdeef744)
- [actions] reuse common workflows [`01d0ee0`](https://github.com/inspect-js/has-symbols/commit/01d0ee0a8d97c0947f5edb73eb722027a77b2b07)
- [actions] update codecov uploader [`6424ebe`](https://github.com/inspect-js/has-symbols/commit/6424ebe86b2c9c7c3d2e9bd4413a4e4f168cb275)
- [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `aud`, `auto-changelog`, `tape` [`dfa7e7f`](https://github.com/inspect-js/has-symbols/commit/dfa7e7ff38b594645d8c8222aab895157fa7e282)
- [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `safe-publish-latest`, `tape` [`0c8d436`](https://github.com/inspect-js/has-symbols/commit/0c8d43685c45189cea9018191d4fd7eca91c9d02)
- [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `aud`, `tape` [`9026554`](https://github.com/inspect-js/has-symbols/commit/902655442a1bf88e72b42345494ef0c60f5d36ab)
- [readme] add actions and codecov badges [`eaa9682`](https://github.com/inspect-js/has-symbols/commit/eaa9682f990f481d3acf7a1c7600bec36f7b3adc)
- [Dev Deps] update `eslint`, `tape` [`bc7a3ba`](https://github.com/inspect-js/has-symbols/commit/bc7a3ba46f27b7743f8a2579732d59d1b9ac791e)
- [Dev Deps] update `eslint`, `auto-changelog` [`0ace00a`](https://github.com/inspect-js/has-symbols/commit/0ace00af08a88cdd1e6ce0d60357d941c60c2d9f)
- [meta] use `prepublishOnly` script for npm 7+ [`093f72b`](https://github.com/inspect-js/has-symbols/commit/093f72bc2b0ed00c781f444922a5034257bf561d)
- [Tests] test on all 16 minors [`9b80d3d`](https://github.com/inspect-js/has-symbols/commit/9b80d3d9102529f04c20ec5b1fcc6e38426c6b03)

## [v1.0.2](https://github.com/inspect-js/has-symbols/compare/v1.0.1...v1.0.2) - 2021-02-27

### Fixed

- [Fix] use a universal way to get the original Symbol [`#11`](https://github.com/inspect-js/has-symbols/issues/11)

### Commits

- [Tests] migrate tests to Github Actions [`90ae798`](https://github.com/inspect-js/has-symbols/commit/90ae79820bdfe7bc703d67f5f3c5e205f98556d3)
- [meta] do not publish github action workflow files [`29e60a1`](https://github.com/inspect-js/has-symbols/commit/29e60a1b7c25c7f1acf7acff4a9320d0d10c49b4)
- [Tests] run `nyc` on all tests [`8476b91`](https://github.com/inspect-js/has-symbols/commit/8476b915650d360915abe2522505abf4b0e8f0ae)
- [readme] fix repo URLs, remove defunct badges [`126288e`](https://github.com/inspect-js/has-symbols/commit/126288ecc1797c0a40247a6b78bcb2e0bc5d7036)
- [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `aud`, `auto-changelog`, `core-js`, `get-own-property-symbols` [`d84bdfa`](https://github.com/inspect-js/has-symbols/commit/d84bdfa48ac5188abbb4904b42614cd6c030940a)
- [Tests] fix linting errors [`0df3070`](https://github.com/inspect-js/has-symbols/commit/0df3070b981b6c9f2ee530c09189a7f5c6def839)
- [actions] add "Allow Edits" workflow [`1e6bc29`](https://github.com/inspect-js/has-symbols/commit/1e6bc29b188f32b9648657b07eda08504be5aa9c)
- [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `tape` [`36cea2a`](https://github.com/inspect-js/has-symbols/commit/36cea2addd4e6ec435f35a2656b4e9ef82498e9b)
- [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `aud`, `tape` [`1278338`](https://github.com/inspect-js/has-symbols/commit/127833801865fbc2cc8979beb9ca869c7bfe8222)
- [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `aud`, `tape` [`1493254`](https://github.com/inspect-js/has-symbols/commit/1493254eda13db5fb8fc5e4a3e8324b3d196029d)
- [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `core-js` [`b090bf2`](https://github.com/inspect-js/has-symbols/commit/b090bf214d3679a30edc1e2d729d466ab5183e1d)
- [actions] switch Automatic Rebase workflow to `pull_request_target` event [`4addb7a`](https://github.com/inspect-js/has-symbols/commit/4addb7ab4dc73f927ae99928d68817554fc21dc0)
- [Dev Deps] update `auto-changelog`, `tape` [`81d0baf`](https://github.com/inspect-js/has-symbols/commit/81d0baf3816096a89a8558e8043895f7a7d10d8b)
- [Dev Deps] update `auto-changelog`; add `aud` [`1a4e561`](https://github.com/inspect-js/has-symbols/commit/1a4e5612c25d91c3a03d509721d02630bc4fe3da)
- [readme] remove unused testling URLs [`3000941`](https://github.com/inspect-js/has-symbols/commit/3000941f958046e923ed8152edb1ef4a599e6fcc)
- [Tests] only audit prod deps [`692e974`](https://github.com/inspect-js/has-symbols/commit/692e9743c912410e9440207631a643a34b4741a1)
- [Dev Deps] update `@ljharb/eslint-config` [`51c946c`](https://github.com/inspect-js/has-symbols/commit/51c946c7f6baa793ec5390bb5a45cdce16b4ba76)

## [v1.0.1](https://github.com/inspect-js/has-symbols/compare/v1.0.0...v1.0.1) - 2019-11-16

### Commits

- [Tests] use shared travis-ci configs [`ce396c9`](https://github.com/inspect-js/has-symbols/commit/ce396c9419ff11c43d0da5d05cdbb79f7fb42229)
- [Tests] up to `node` `v12.4`, `v11.15`, `v10.15`, `v9.11`, `v8.15`, `v7.10`, `v6.17`, `v4.9`; use `nvm install-latest-npm` [`0690732`](https://github.com/inspect-js/has-symbols/commit/0690732801f47ab429f39ba1962f522d5c462d6b)
- [meta] add `auto-changelog` [`2163d0b`](https://github.com/inspect-js/has-symbols/commit/2163d0b7f36343076b8f947cd1667dd1750f26fc)
- [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `core-js`, `safe-publish-latest`, `tape` [`8e0951f`](https://github.com/inspect-js/has-symbols/commit/8e0951f1a7a2e52068222b7bb73511761e6e4d9c)
- [actions] add automatic rebasing / merge commit blocking [`b09cdb7`](https://github.com/inspect-js/has-symbols/commit/b09cdb7cd7ee39e7a769878f56e2d6066f5ccd1d)
- [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `safe-publish-latest`, `core-js`, `get-own-property-symbols`, `tape` [`1dd42cd`](https://github.com/inspect-js/has-symbols/commit/1dd42cd86183ed0c50f99b1062345c458babca91)
- [meta] create FUNDING.yml [`aa57a17`](https://github.com/inspect-js/has-symbols/commit/aa57a17b19708906d1927f821ea8e73394d84ca4)
- Only apps should have lockfiles [`a2d8bea`](https://github.com/inspect-js/has-symbols/commit/a2d8bea23a97d15c09eaf60f5b107fcf9a4d57aa)
- [Tests] use `npx aud` instead of `nsp` or `npm audit` with hoops [`9e96cb7`](https://github.com/inspect-js/has-symbols/commit/9e96cb783746cbed0c10ef78e599a8eaa7ebe193)
- [meta] add `funding` field [`a0b32cf`](https://github.com/inspect-js/has-symbols/commit/a0b32cf68e803f963c1639b6d47b0a9d6440bab0)
- [Dev Deps] update `safe-publish-latest` [`cb9f0a5`](https://github.com/inspect-js/has-symbols/commit/cb9f0a521a3a1790f1064d437edd33bb6c3d6af0)

## v1.0.0 - 2016-09-19

### Commits

- Tests. [`ecb6eb9`](https://github.com/inspect-js/has-symbols/commit/ecb6eb934e4883137f3f93b965ba5e0a98df430d)
- package.json [`88a337c`](https://github.com/inspect-js/has-symbols/commit/88a337cee0864a0da35f5d19e69ff0ef0150e46a)
- Initial commit [`42e1e55`](https://github.com/inspect-js/has-symbols/commit/42e1e5502536a2b8ac529c9443984acd14836b1c)
- Initial implementation. [`33f5cc6`](https://github.com/inspect-js/has-symbols/commit/33f5cc6cdff86e2194b081ee842bfdc63caf43fb)
- read me [`01f1170`](https://github.com/inspect-js/has-symbols/commit/01f1170188ff7cb1558aa297f6ba5b516c6d7b0c)


code:
# has-symbols <sup>[![Version Badge][2]][1]</sup>

[![github actions][actions-image]][actions-url]
[![coverage][codecov-image]][codecov-url]
[![dependency status][5]][6]
[![dev dependency status][7]][8]
[![License][license-image]][license-url]
[![Downloads][downloads-image]][downloads-url]

[![npm badge][11]][1]

Determine if the JS environment has Symbol support. Supports spec, or shams.

## Example

```js
var hasSymbols = require('has-symbols');

hasSymbols() === true; // if the environment has native Symbol support. Not polyfillable, not forgeable.

var hasSymbolsKinda = require('has-symbols/shams');
hasSymbolsKinda() === true; // if the environment has a Symbol sham that mostly follows the spec.
```

## Supported Symbol shams
 - get-own-property-symbols [npm](https://www.npmjs.com/package/get-own-property-symbols) | [github](https://github.com/WebReflection/get-own-property-symbols)
 - core-js [npm](https://www.npmjs.com/package/core-js) | [github](https://github.com/zloirock/core-js)

## Tests
Simply clone the repo, `npm install`, and run `npm test`

[1]: https://npmjs.org/package/has-symbols
[2]: https://versionbadg.es/inspect-js/has-symbols.svg
[5]: https://david-dm.org/inspect-js/has-symbols.svg
[6]: https://david-dm.org/inspect-js/has-symbols
[7]: https://david-dm.org/inspect-js/has-symbols/dev-status.svg
[8]: https://david-dm.org/inspect-js/has-symbols#info=devDependencies
[11]: https://nodei.co/npm/has-symbols.png?downloads=true&stars=true
[license-image]: https://img.shields.io/npm/l/has-symbols.svg
[license-url]: LICENSE
[downloads-image]: https://img.shields.io/npm/dm/has-symbols.svg
[downloads-url]: https://npm-stat.com/charts.html?package=has-symbols
[codecov-image]: https://codecov.io/gh/inspect-js/has-symbols/branch/main/graphs/badge.svg
[codecov-url]: https://app.codecov.io/gh/inspect-js/has-symbols/
[actions-image]: https://img.shields.io/endpoint?url=https://github-actions-badge-u3jn4tfpocch.runkit.sh/inspect-js/has-symbols
[actions-url]: https://github.com/inspect-js/has-symbols/actions


code:
'use strict';

var origSymbol = typeof Symbol !== 'undefined' && Symbol;
var hasSymbolSham = require('./shams');

module.exports = function hasNativeSymbols() {
	if (typeof origSymbol !== 'function') { return false; }
	if (typeof Symbol !== 'function') { return false; }
	if (typeof origSymbol('foo') !== 'symbol') { return false; }
	if (typeof Symbol('bar') !== 'symbol') { return false; }

	return hasSymbolSham();
};


has-symbols

description: Determine if the JS environment has Symbol support. Supports spec, or shams.

pretest: npm run --silent lint

tests-only: npm run test:stock && npm run test:staging && npm run test:shams

test:stock: nyc node test

test:staging: nyc node --harmony --es-staging test

test:shams: npm run --silent test:shams:getownpropertysymbols && npm run --silent test:shams:corejs

test:shams:corejs: nyc node test/shams/core-js.js

keywords: Symbol symbols typeof sham polyfill native core-js ES6

output: CHANGELOG.md


code:
'use strict';

/* eslint complexity: [2, 18], max-statements: [2, 33] */
module.exports = function hasSymbols() {
	if (typeof Symbol !== 'function' || typeof Object.getOwnPropertySymbols !== 'function') { return false; }
	if (typeof Symbol.iterator === 'symbol') { return true; }

	var obj = {};
	var sym = Symbol('test');
	var symObj = Object(sym);
	if (typeof sym === 'string') { return false; }

	if (Object.prototype.toString.call(sym) !== '[object Symbol]') { return false; }
	if (Object.prototype.toString.call(symObj) !== '[object Symbol]') { return false; }

	// temp disabled per https://github.com/ljharb/object.assign/issues/17
	// if (sym instanceof Symbol) { return false; }
	// temp disabled per https://github.com/WebReflection/get-own-property-symbols/issues/4
	// if (!(symObj instanceof Symbol)) { return false; }

	// if (typeof Symbol.prototype.toString !== 'function') { return false; }
	// if (String(sym) !== Symbol.prototype.toString.call(sym)) { return false; }

	var symVal = 42;
	obj[sym] = symVal;
	for (sym in obj) { return false; } // eslint-disable-line no-restricted-syntax, no-unreachable-loop
	if (typeof Object.keys === 'function' && Object.keys(obj).length !== 0) { return false; }

	if (typeof Object.getOwnPropertyNames === 'function' && Object.getOwnPropertyNames(obj).length !== 0) { return false; }

	var syms = Object.getOwnPropertySymbols(obj);
	if (syms.length !== 1 || syms[0] !== sym) { return false; }

	if (!Object.prototype.propertyIsEnumerable.call(obj, sym)) { return false; }

	if (typeof Object.getOwnPropertyDescriptor === 'function') {
		var descriptor = Object.getOwnPropertyDescriptor(obj, sym);
		if (descriptor.value !== symVal || descriptor.enumerable !== true) { return false; }
	}

	return true;
};


code:
'use strict';

var test = require('tape');
var hasSymbols = require('../');
var runSymbolTests = require('./tests');

test('interface', function (t) {
	t.equal(typeof hasSymbols, 'function', 'is a function');
	t.equal(typeof hasSymbols(), 'boolean', 'returns a boolean');
	t.end();
});

test('Symbols are supported', { skip: !hasSymbols() }, function (t) {
	runSymbolTests(t);
	t.end();
});

test('Symbols are not supported', { skip: hasSymbols() }, function (t) {
	t.equal(typeof Symbol, 'undefined', 'global Symbol is undefined');
	t.equal(typeof Object.getOwnPropertySymbols, 'undefined', 'Object.getOwnPropertySymbols does not exist');
	t.end();
});


code:
'use strict';

var test = require('tape');

if (typeof Symbol === 'function' && typeof Symbol() === 'symbol') {
	test('has native Symbol support', function (t) {
		t.equal(typeof Symbol, 'function');
		t.equal(typeof Symbol(), 'symbol');
		t.end();
	});
	return;
}

var hasSymbols = require('../../shams');

test('polyfilled Symbols', function (t) {
	/* eslint-disable global-require */
	t.equal(hasSymbols(), false, 'hasSymbols is false before polyfilling');
	require('core-js/fn/symbol');
	require('core-js/fn/symbol/to-string-tag');

	require('../tests')(t);

	var hasSymbolsAfter = hasSymbols();
	t.equal(hasSymbolsAfter, true, 'hasSymbols is true after polyfilling');
	/* eslint-enable global-require */
	t.end();
});


code:
'use strict';

var test = require('tape');

if (typeof Symbol === 'function' && typeof Symbol() === 'symbol') {
	test('has native Symbol support', function (t) {
		t.equal(typeof Symbol, 'function');
		t.equal(typeof Symbol(), 'symbol');
		t.end();
	});
	return;
}

var hasSymbols = require('../../shams');

test('polyfilled Symbols', function (t) {
	/* eslint-disable global-require */
	t.equal(hasSymbols(), false, 'hasSymbols is false before polyfilling');

	require('get-own-property-symbols');

	require('../tests')(t);

	var hasSymbolsAfter = hasSymbols();
	t.equal(hasSymbolsAfter, true, 'hasSymbols is true after polyfilling');
	/* eslint-enable global-require */
	t.end();
});


code:
'use strict';

// eslint-disable-next-line consistent-return
module.exports = function runSymbolTests(t) {
	t.equal(typeof Symbol, 'function', 'global Symbol is a function');

	if (typeof Symbol !== 'function') { return false; }

	t.notEqual(Symbol(), Symbol(), 'two symbols are not equal');

	/*
	t.equal(
		Symbol.prototype.toString.call(Symbol('foo')),
		Symbol.prototype.toString.call(Symbol('foo')),
		'two symbols with the same description stringify the same'
	);
	*/

	/*
	var foo = Symbol('foo');

	t.notEqual(
		String(foo),
		String(Symbol('bar')),
		'two symbols with different descriptions do not stringify the same'
	);
	*/

	t.equal(typeof Symbol.prototype.toString, 'function', 'Symbol#toString is a function');
	// t.equal(String(foo), Symbol.prototype.toString.call(foo), 'Symbol#toString equals String of the same symbol');

	t.equal(typeof Object.getOwnPropertySymbols, 'function', 'Object.getOwnPropertySymbols is a function');

	var obj = {};
	var sym = Symbol('test');
	var symObj = Object(sym);
	t.notEqual(typeof sym, 'string', 'Symbol is not a string');
	t.equal(Object.prototype.toString.call(sym), '[object Symbol]', 'symbol primitive Object#toStrings properly');
	t.equal(Object.prototype.toString.call(symObj), '[object Symbol]', 'symbol primitive Object#toStrings properly');

	var symVal = 42;
	obj[sym] = symVal;
	// eslint-disable-next-line no-restricted-syntax
	for (sym in obj) { t.fail('symbol property key was found in for..in of object'); }

	t.deepEqual(Object.keys(obj), [], 'no enumerable own keys on symbol-valued object');
	t.deepEqual(Object.getOwnPropertyNames(obj), [], 'no own names on symbol-valued object');
	t.deepEqual(Object.getOwnPropertySymbols(obj), [sym], 'one own symbol on symbol-valued object');
	t.equal(Object.prototype.propertyIsEnumerable.call(obj, sym), true, 'symbol is enumerable');
	t.deepEqual(Object.getOwnPropertyDescriptor(obj, sym), {
		configurable: true,
		enumerable: true,
		value: 42,
		writable: true
	}, 'property descriptor is correct');
};


code:
# editorconfig.org
root = true

[*]
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true

[*.md]
trim_trailing_whitespace = false


code:
# 2.0.0

- Now takes into account result of calling `valueOf` functions when they exist

# 1.0.2 Quick Sort

- Sorts object keys so that property order doesn't affect outcome

# 1.0.1 Perfect Circle

- Guard against circular references

# 1.0.0 IPO

- Initial Public Release


code:
'use strict';

function pad (hash, len) {
  while (hash.length < len) {
    hash = '0' + hash;
  }
  return hash;
}

function fold (hash, text) {
  var i;
  var chr;
  var len;
  if (text.length === 0) {
    return hash;
  }
  for (i = 0, len = text.length; i < len; i++) {
    chr = text.charCodeAt(i);
    hash = ((hash << 5) - hash) + chr;
    hash |= 0;
  }
  return hash < 0 ? hash * -2 : hash;
}

function foldObject (hash, o, seen) {
  return Object.keys(o).sort().reduce(foldKey, hash);
  function foldKey (hash, key) {
    return foldValue(hash, o[key], key, seen);
  }
}

function foldValue (input, value, key, seen) {
  var hash = fold(fold(fold(input, key), toString(value)), typeof value);
  if (value === null) {
    return fold(hash, 'null');
  }
  if (value === undefined) {
    return fold(hash, 'undefined');
  }
  if (typeof value === 'object' || typeof value === 'function') {
    if (seen.indexOf(value) !== -1) {
      return fold(hash, '[Circular]' + key);
    }
    seen.push(value);

    var objHash = foldObject(hash, value, seen)

    if (!('valueOf' in value) || typeof value.valueOf !== 'function') {
      return objHash;
    }

    try {
      return fold(objHash, String(value.valueOf()))
    } catch (err) {
      return fold(objHash, '[valueOf exception]' + (err.stack || err.message))
    }
  }
  return fold(hash, value.toString());
}

function toString (o) {
  return Object.prototype.toString.call(o);
}

function sum (o) {
  return pad(foldValue(0, o, '', []).toString(16), 8);
}

module.exports = sum;


hash-sum

description: Blazing fast unique hash generator

test: jshint . && tape test.js


code:
# hash-sum

> blazing fast unique hash generator

# install

```shell
npm i hash-sum -S
```

# features

- no dependencies
- minimal footprint
- works in all of node.js, io.js, and the browser
- hashes functions based on their source code
- produces different hashes for different object types
- support for circular references in objects
- ignores property assignment order

# `sum(value)`

yields a four-byte hexadecimal hash based off of `value`.

```
# creates unique hashes
00a34759 from: [ 0, 1, 2, 3 ]
a8996f0c from: { '0': 0, '1': 1, '2': 2, '3': 3 }
5b4c2116 from: { '0': 0, '1': 1, '2': 2, '3': 3, length: 4 }
2c937c45 from: { url: 12 }
31d55010 from: { headers: 12 }
2d2e11bc from: { headers: 122 }
ec99d958 from: { headers: '122' }
18c00eee from: { headers: { accept: 'text/plain' } }
6cb332c8 from: { payload: [ 0, 1, 2, 3 ], headers: [ { a: 'b' } ] }
12ff55db from: { a: [Function: a] }
46f806d2 from: { b: [Function: b] }
0660d9c4 from: { b: [Function: b] }
6c95fc65 from: function () {}
2941766e from: function (a) {}
294f8def from: function (b) {}
2d9c0cb8 from: function (a) { return a;}
ed5c63fc from: function (a) {return a;}
bba68bf6 from: ''
2d27667d from: 'null'
774b96ed from: 'false'
2d2a1684 from: 'true'
8daa1a0c from: '0'
8daa1a0a from: '1'
e38f07cc from: 'void 0'
6037ea1a from: 'undefined'
9b7df12e from: null
3c206f76 from: false
01e34ba8 from: true
8a8f9624 from: Infinity
0315bf8f from: -Infinity
64a48b16 from: NaN
1a96284a from: 0
1a96284b from: 1
29172c1a from: undefined
59322f29 from: {}
095b3a22 from: { a: {}, b: {} }
63be56dd from: { valueOf: [Function: valueOf] }
63be4f5c from: { valueOf: [Function: valueOf] }
5d844489 from: []
ba0bfa14 from: 2019-06-28T21:24:31.215Z
49324d16 from: 2019-06-28T03:00:00.000Z
434c9188 from: 1988-06-09T03:00:00.000Z
ce1b5e44 from: global
```

# license

MIT


code:
'use strict';

var _ = require('lodash');
var test = require('tape');
var sum = require('./');

test('creates unique hashes', function (t) {
  var cases = [];

  test_case([0,1,2,3]);
  test_case({0:0,1:1,2:2,3:3});
  test_case({0:0,1:1,2:2,3:3,length:4});
  test_case({url:12});
  test_case({headers:12});
  test_case({headers:122});
  test_case({headers:'122'});
  test_case({headers:{accept:'text/plain'}});
  test_case({payload:[0,1,2,3],headers:[{a:'b'}]});
  test_case({a:function () {}});
  test_case({b:function () {}});
  test_case({b:function (a) {}});
  test_case(function () {});
  test_case(function (a) {});
  test_case(function (b) {});
  test_case(function (a) { return a;});
  test_case(function (a) {return a;});
  test_case('', '\'\'');
  test_case('null', '\'null\'');
  test_case('false', '\'false\'');
  test_case('true', '\'true\'');
  test_case('0', '\'0\'');
  test_case('1', '\'1\'');
  test_case('void 0', '\'void 0\'');
  test_case('undefined', '\'undefined\'');
  test_case(null);
  test_case(false);
  test_case(true);
  test_case(Infinity);
  test_case(-Infinity);
  test_case(NaN);
  test_case(0);
  test_case(1);
  test_case(void 0);
  test_case({});
  test_case({a:{},b:{}});
  test_case({valueOf(){return 1}});
  test_case({valueOf(){return 2}});
  test_case([]);
  test_case(new Date());
  test_case(new Date(2019, 5, 28));
  test_case(new Date(1988, 5, 9));
  test_case(global, 'global');

  const uniqCases = _.uniqBy(cases, 'hash')
  _.uniqBy(cases, 'hash').forEach(function (expected) {
    var matches = _.filter(cases, { hash: expected.hash })
    t.equal(matches.length, 1, expected.hash + ': ' + _.map(matches, 'value').join(' '))
  })

  t.end();

  function test_case(value, name) {
    var hash = sum(value);
    cases.push({ value, hash });
    console.log('%s from:', hash, name || value);
  }
});

test('hashes clash if same properties', function (t) {
  equals(function () {}, function () {});
  equals(function (a) {}, function (a) {});
  equals({a:'1'},{a:'1'});
  equals({a:'1',b:1},{b:1,a:'1'});
  equals({valueOf(){return 1}},{valueOf(){return 1}});
  t.end();

  function equals (a, b) {
    t.equal(sum(a), sum(b));
  }
});


code:
{
	"root": true,

	"extends": "@ljharb",
}


code:
# These are supported funding model platforms

github: [ljharb]
patreon: # Replace with a single Patreon username
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
tidelift: npm/hasown
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
custom: # Replace with a single custom sponsorship URL


code:
# Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [v2.0.2](https://github.com/inspect-js/hasOwn/compare/v2.0.1...v2.0.2) - 2024-03-10

### Commits

- [types] use shared config [`68e9d4d`](https://github.com/inspect-js/hasOwn/commit/68e9d4dab6facb4f05f02c6baea94a3f2a4e44b2)
- [actions] remove redundant finisher; use reusable workflow [`241a68e`](https://github.com/inspect-js/hasOwn/commit/241a68e13ea1fe52bec5ba7f74144befc31fae7b)
- [Tests] increase coverage [`4125c0d`](https://github.com/inspect-js/hasOwn/commit/4125c0d6121db56ae30e38346dfb0c000b04f0a7)
- [Tests] skip `npm ls` in old node due to TS [`01b9282`](https://github.com/inspect-js/hasOwn/commit/01b92822f9971dea031eafdd14767df41d61c202)
- [types] improve predicate type [`d340f85`](https://github.com/inspect-js/hasOwn/commit/d340f85ce02e286ef61096cbbb6697081d40a12b)
- [Dev Deps] update `tape` [`70089fc`](https://github.com/inspect-js/hasOwn/commit/70089fcf544e64acc024cbe60f5a9b00acad86de)
- [Tests] use `@arethetypeswrong/cli` [`50b272c`](https://github.com/inspect-js/hasOwn/commit/50b272c829f40d053a3dd91c9796e0ac0b2af084)

## [v2.0.1](https://github.com/inspect-js/hasOwn/compare/v2.0.0...v2.0.1) - 2024-02-10

### Commits

- [types] use a handwritten d.ts file; fix exported type [`012b989`](https://github.com/inspect-js/hasOwn/commit/012b9898ccf91dc441e2ebf594ff70270a5fda58)
- [Dev Deps] update `@types/function-bind`, `@types/mock-property`, `@types/tape`, `aud`, `mock-property`, `npmignore`, `tape`, `typescript` [`977a56f`](https://github.com/inspect-js/hasOwn/commit/977a56f51a1f8b20566f3c471612137894644025)
- [meta] add `sideEffects` flag [`3a60b7b`](https://github.com/inspect-js/hasOwn/commit/3a60b7bf42fccd8c605e5f145a6fcc83b13cb46f)

## [v2.0.0](https://github.com/inspect-js/hasOwn/compare/v1.0.1...v2.0.0) - 2023-10-19

### Commits

- revamped implementation, tests, readme [`72bf8b3`](https://github.com/inspect-js/hasOwn/commit/72bf8b338e77a638f0a290c63ffaed18339c36b4)
- [meta] revamp package.json [`079775f`](https://github.com/inspect-js/hasOwn/commit/079775fb1ec72c1c6334069593617a0be3847458)
- Only apps should have lockfiles [`6640e23`](https://github.com/inspect-js/hasOwn/commit/6640e233d1bb8b65260880f90787637db157d215)

## v1.0.1 - 2023-10-10

### Commits

- Initial commit [`8dbfde6`](https://github.com/inspect-js/hasOwn/commit/8dbfde6e8fb0ebb076fab38d138f2984eb340a62)


code:
# hasown <sup>[![Version Badge][npm-version-svg]][package-url]</sup>

[![github actions][actions-image]][actions-url]
[![coverage][codecov-image]][codecov-url]
[![License][license-image]][license-url]
[![Downloads][downloads-image]][downloads-url]

[![npm badge][npm-badge-png]][package-url]

A robust, ES3 compatible, "has own property" predicate.

## Example

```js
const assert = require('assert');
const hasOwn = require('hasown');

assert.equal(hasOwn({}, 'toString'), false);
assert.equal(hasOwn([], 'length'), true);
assert.equal(hasOwn({ a: 42 }, 'a'), true);
```

## Tests
Simply clone the repo, `npm install`, and run `npm test`

[package-url]: https://npmjs.org/package/hasown
[npm-version-svg]: https://versionbadg.es/inspect-js/hasown.svg
[deps-svg]: https://david-dm.org/inspect-js/hasOwn.svg
[deps-url]: https://david-dm.org/inspect-js/hasOwn
[dev-deps-svg]: https://david-dm.org/inspect-js/hasOwn/dev-status.svg
[dev-deps-url]: https://david-dm.org/inspect-js/hasOwn#info=devDependencies
[npm-badge-png]: https://nodei.co/npm/hasown.png?downloads=true&stars=true
[license-image]: https://img.shields.io/npm/l/hasown.svg
[license-url]: LICENSE
[downloads-image]: https://img.shields.io/npm/dm/hasown.svg
[downloads-url]: https://npm-stat.com/charts.html?package=hasown
[codecov-image]: https://codecov.io/gh/inspect-js/hasOwn/branch/main/graphs/badge.svg
[codecov-url]: https://app.codecov.io/gh/inspect-js/hasOwn/
[actions-image]: https://img.shields.io/endpoint?url=https://github-actions-badge-u3jn4tfpocch.runkit.sh/inspect-js/hasOwn
[actions-url]: https://github.com/inspect-js/hasOwn/actions


code:
declare function hasOwn<O, K extends PropertyKey, V = unknown>(o: O, p: K): o is O & Record<K, V>;

export = hasOwn;


code:
'use strict';

var call = Function.prototype.call;
var $hasOwn = Object.prototype.hasOwnProperty;
var bind = require('function-bind');

/** @type {import('.')} */
module.exports = bind.call(call, $hasOwn);


hasown

description: A robust, ES3 compatible, "has own property" predicate.

postlint: npm run tsc

tsc: tsc -p .

posttsc: attw -P

keywords: has hasOwnProperty hasOwn has-own own has property in javascript ecmascript

output: CHANGELOG.md

ignore: .github/workflows test


code:
{
  "extends": "@ljharb/tsconfig",
  "exclude": [
    "coverage",
  ],
}


code:
Copyright Mathias Bynens <https://mathiasbynens.be/>

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.


code:
# he [![Build status](https://travis-ci.org/mathiasbynens/he.svg?branch=master)](https://travis-ci.org/mathiasbynens/he) [![Code coverage status](https://codecov.io/github/mathiasbynens/he/coverage.svg?branch=master)](https://codecov.io/github/mathiasbynens/he?branch=master) [![Dependency status](https://gemnasium.com/mathiasbynens/he.svg)](https://gemnasium.com/mathiasbynens/he)

_he_ (for “HTML entities”) is a robust HTML entity encoder/decoder written in JavaScript. It supports [all standardized named character references as per HTML](https://html.spec.whatwg.org/multipage/syntax.html#named-character-references), handles [ambiguous ampersands](https://mathiasbynens.be/notes/ambiguous-ampersands) and other edge cases [just like a browser would](https://html.spec.whatwg.org/multipage/syntax.html#tokenizing-character-references), has an extensive test suite, and — contrary to many other JavaScript solutions — _he_ handles astral Unicode symbols just fine. [An online demo is available.](https://mothereff.in/html-entities)

## Installation

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

```bash
npm install he
```

Via [Bower](http://bower.io/):

```bash
bower install he
```

Via [Component](https://github.com/component/component):

```bash
component install mathiasbynens/he
```

In a browser:

```html
<script src="he.js"></script>
```

In [Node.js](https://nodejs.org/), [io.js](https://iojs.org/), [Narwhal](http://narwhaljs.org/), and [RingoJS](http://ringojs.org/):

```js
var he = require('he');
```

In [Rhino](http://www.mozilla.org/rhino/):

```js
load('he.js');
```

Using an AMD loader like [RequireJS](http://requirejs.org/):

```js
require(
  {
    'paths': {
      'he': 'path/to/he'
    }
  },
  ['he'],
  function(he) {
    console.log(he);
  }
);
```

## API

### `he.version`

A string representing the semantic version number.

### `he.encode(text, options)`

This function takes a string of text and encodes (by default) any symbols that aren’t printable ASCII symbols and `&`, `<`, `>`, `"`, `'`, and `` ` ``, replacing them with character references.

```js
he.encode('foo © bar ≠ baz 𝌆 qux');
// → 'foo © bar ≠ baz 𝌆 qux'
```

As long as the input string contains [allowed code points](https://html.spec.whatwg.org/multipage/parsing.html#preprocessing-the-input-stream) only, the return value of this function is always valid HTML. Any [(invalid) code points that cannot be represented using a character reference](https://html.spec.whatwg.org/multipage/syntax.html#table-charref-overrides) in the input are not encoded:

```js
he.encode('foo \0 bar');
// → 'foo \0 bar'
```

However, enabling [the `strict` option](https://github.com/mathiasbynens/he#strict) causes invalid code points to throw an exception. With `strict` enabled, `he.encode` either throws (if the input contains invalid code points) or returns a string of valid HTML.

The `options` object is optional. It recognizes the following properties:

#### `useNamedReferences`

The default value for the `useNamedReferences` option is `false`. This means that `encode()` will not use any named character references (e.g. `©`) in the output — hexadecimal escapes (e.g. `©`) will be used instead. Set it to `true` to enable the use of named references.

**Note that if compatibility with older browsers is a concern, this option should remain disabled.**

```js
// Using the global default setting (defaults to `false`):
he.encode('foo © bar ≠ baz 𝌆 qux');
// → 'foo © bar ≠ baz 𝌆 qux'

// Passing an `options` object to `encode`, to explicitly disallow named references:
he.encode('foo © bar ≠ baz 𝌆 qux', {
  'useNamedReferences': false
});
// → 'foo © bar ≠ baz 𝌆 qux'

// Passing an `options` object to `encode`, to explicitly allow named references:
he.encode('foo © bar ≠ baz 𝌆 qux', {
  'useNamedReferences': true
});
// → 'foo © bar ≠ baz 𝌆 qux'
```

#### `decimal`

The default value for the `decimal` option is `false`. If the option is enabled, `encode` will generally use decimal escapes (e.g. `©`) rather than hexadecimal escapes (e.g. `©`). Beside of this replacement, the basic behavior remains the same when combined with other options. For example: if both options `useNamedReferences` and `decimal` are enabled, named references (e.g. `©`) are used over decimal escapes. HTML entities without a named reference are encoded using decimal escapes.

```js
// Using the global default setting (defaults to `false`):
he.encode('foo © bar ≠ baz 𝌆 qux');
// → 'foo © bar ≠ baz 𝌆 qux'

// Passing an `options` object to `encode`, to explicitly disable decimal escapes:
he.encode('foo © bar ≠ baz 𝌆 qux', {
  'decimal': false
});
// → 'foo © bar ≠ baz 𝌆 qux'

// Passing an `options` object to `encode`, to explicitly enable decimal escapes:
he.encode('foo © bar ≠ baz 𝌆 qux', {
  'decimal': true
});
// → 'foo © bar ≠ baz 𝌆 qux'

// Passing an `options` object to `encode`, to explicitly allow named references and decimal escapes:
he.encode('foo © bar ≠ baz 𝌆 qux', {
  'useNamedReferences': true,
  'decimal': true
});
// → 'foo © bar ≠ baz 𝌆 qux'
```

#### `encodeEverything`

The default value for the `encodeEverything` option is `false`. This means that `encode()` will not use any character references for printable ASCII symbols that don’t need escaping. Set it to `true` to encode every symbol in the input string. When set to `true`, this option takes precedence over `allowUnsafeSymbols` (i.e. setting the latter to `true` in such a case has no effect).

```js
// Using the global default setting (defaults to `false`):
he.encode('foo © bar ≠ baz 𝌆 qux');
// → 'foo © bar ≠ baz 𝌆 qux'

// Passing an `options` object to `encode`, to explicitly encode all symbols:
he.encode('foo © bar ≠ baz 𝌆 qux', {
  'encodeEverything': true
});
// → 'foo © bar ≠ baz 𝌆 qux'

// This setting can be combined with the `useNamedReferences` option:
he.encode('foo © bar ≠ baz 𝌆 qux', {
  'encodeEverything': true,
  'useNamedReferences': true
});
// → 'foo © bar ≠ baz 𝌆 qux'
```

#### `strict`

The default value for the `strict` option is `false`. This means that `encode()` will encode any HTML text content you feed it, even if it contains any symbols that cause [parse errors](https://html.spec.whatwg.org/multipage/parsing.html#preprocessing-the-input-stream). To throw an error when such invalid HTML is encountered, set the `strict` option to `true`. This option makes it possible to use _he_ as part of HTML parsers and HTML validators.

```js
// Using the global default setting (defaults to `false`, i.e. error-tolerant mode):
he.encode('\x01');
// → ''

// Passing an `options` object to `encode`, to explicitly enable error-tolerant mode:
he.encode('\x01', {
  'strict': false
});
// → ''

// Passing an `options` object to `encode`, to explicitly enable strict mode:
he.encode('\x01', {
  'strict': true
});
// → Parse error
```

#### `allowUnsafeSymbols`

The default value for the `allowUnsafeSymbols` option is `false`. This means that characters that are unsafe for use in HTML content (`&`, `<`, `>`, `"`, `'`, and `` ` ``) will be encoded. When set to `true`, only non-ASCII characters will be encoded. If the `encodeEverything` option is set to `true`, this option will be ignored.

```js
he.encode('foo © and & ampersand', {
  'allowUnsafeSymbols': true
});
// → 'foo © and & ampersand'
```

#### Overriding default `encode` options globally

The global default setting can be overridden by modifying the `he.encode.options` object. This saves you from passing in an `options` object for every call to `encode` if you want to use the non-default setting.

```js
// Read the global default setting:
he.encode.options.useNamedReferences;
// → `false` by default

// Override the global default setting:
he.encode.options.useNamedReferences = true;

// Using the global default setting, which is now `true`:
he.encode('foo © bar ≠ baz 𝌆 qux');
// → 'foo © bar ≠ baz 𝌆 qux'
```

### `he.decode(html, options)`

This function takes a string of HTML and decodes any named and numerical character references in it using [the algorithm described in section 12.2.4.69 of the HTML spec](https://html.spec.whatwg.org/multipage/syntax.html#tokenizing-character-references).

```js
he.decode('foo © bar ≠ baz 𝌆 qux');
// → 'foo © bar ≠ baz 𝌆 qux'
```

The `options` object is optional. It recognizes the following properties:

#### `isAttributeValue`

The default value for the `isAttributeValue` option is `false`. This means that `decode()` will decode the string as if it were used in [a text context in an HTML document](https://html.spec.whatwg.org/multipage/syntax.html#data-state). HTML has different rules for [parsing character references in attribute values](https://html.spec.whatwg.org/multipage/syntax.html#character-reference-in-attribute-value-state) — set this option to `true` to treat the input string as if it were used as an attribute value.

```js
// Using the global default setting (defaults to `false`, i.e. HTML text context):
he.decode('foo&ampbar');
// → 'foo&bar'

// Passing an `options` object to `decode`, to explicitly assume an HTML text context:
he.decode('foo&ampbar', {
  'isAttributeValue': false
});
// → 'foo&bar'

// Passing an `options` object to `decode`, to explicitly assume an HTML attribute value context:
he.decode('foo&ampbar', {
  'isAttributeValue': true
});
// → 'foo&ampbar'
```

#### `strict`

The default value for the `strict` option is `false`. This means that `decode()` will decode any HTML text content you feed it, even if it contains any entities that cause [parse errors](https://html.spec.whatwg.org/multipage/syntax.html#tokenizing-character-references). To throw an error when such invalid HTML is encountered, set the `strict` option to `true`. This option makes it possible to use _he_ as part of HTML parsers and HTML validators.

```js
// Using the global default setting (defaults to `false`, i.e. error-tolerant mode):
he.decode('foo&ampbar');
// → 'foo&bar'

// Passing an `options` object to `decode`, to explicitly enable error-tolerant mode:
he.decode('foo&ampbar', {
  'strict': false
});
// → 'foo&bar'

// Passing an `options` object to `decode`, to explicitly enable strict mode:
he.decode('foo&ampbar', {
  'strict': true
});
// → Parse error
```

#### Overriding default `decode` options globally

The global default settings for the `decode` function can be overridden by modifying the `he.decode.options` object. This saves you from passing in an `options` object for every call to `decode` if you want to use a non-default setting.

```js
// Read the global default setting:
he.decode.options.isAttributeValue;
// → `false` by default

// Override the global default setting:
he.decode.options.isAttributeValue = true;

// Using the global default setting, which is now `true`:
he.decode('foo&ampbar');
// → 'foo&ampbar'
```

### `he.escape(text)`

This function takes a string of text and escapes it for use in text contexts in XML or HTML documents. Only the following characters are escaped: `&`, `<`, `>`, `"`, `'`, and `` ` ``.

```js
he.escape('<img src=\'x\' onerror="prompt(1)">');
// → '<img src='x' onerror="prompt(1)">'
```

### `he.unescape(html, options)`

`he.unescape` is an alias for `he.decode`. It takes a string of HTML and decodes any named and numerical character references in it.

### Using the `he` binary

To use the `he` binary in your shell, simply install _he_ globally using npm:

```bash
npm install -g he
```

After that you will be able to encode/decode HTML entities from the command line:

```bash
$ he --encode 'föo ♥ bår 𝌆 baz'
föo ♥ bår 𝌆 baz

$ he --encode --use-named-refs 'föo ♥ bår 𝌆 baz'
föo ♥ bår 𝌆 baz

$ he --decode 'föo ♥ bår 𝌆 baz'
föo ♥ bår 𝌆 baz
```

Read a local text file, encode it for use in an HTML text context, and save the result to a new file:

```bash
$ he --encode < foo.txt > foo-escaped.html
```

Or do the same with an online text file:

```bash
$ curl -sL "http://git.io/HnfEaw" | he --encode > escaped.html
```

Or, the opposite — read a local file containing a snippet of HTML in a text context, decode it back to plain text, and save the result to a new file:

```bash
$ he --decode < foo-escaped.html > foo.txt
```

Or do the same with an online HTML snippet:

```bash
$ curl -sL "http://git.io/HnfEaw" | he --decode > decoded.txt
```

See `he --help` for the full list of options.

## Support

_he_ has been tested in at least:

* Chrome 27-50
* Firefox 3-45
* Safari 4-9
* Opera 10-12, 15–37
* IE 6–11
* Edge
* Narwhal 0.3.2
* Node.js v0.10, v0.12, v4, v5
* PhantomJS 1.9.0
* Rhino 1.7RC4
* RingoJS 0.8-0.11

## Unit tests & code coverage

After cloning this repository, run `npm install` to install the dependencies needed for he development and testing. You may want to install Istanbul _globally_ using `npm install istanbul -g`.

Once that’s done, you can run the unit tests in Node using `npm test` or `node tests/tests.js`. To run the tests in Rhino, Ringo, Narwhal, and web browsers as well, use `grunt test`.

To generate the code coverage report, use `grunt cover`.

## Acknowledgements

Thanks to [Simon Pieters](https://simon.html5.org/) ([@zcorpan](https://twitter.com/zcorpan)) for the many suggestions.

## Author

| [![twitter/mathias](https://gravatar.com/avatar/24e08a9ea84deb17ae121074d0f17125?s=70)](https://twitter.com/mathias "Follow @mathias on Twitter") |
|---|
| [Mathias Bynens](https://mathiasbynens.be/) |

## License

_he_ is available under the [MIT](https://mths.be/mit) license.


code:
#!/usr/bin/env node
(function() {

	var fs = require('fs');
	var he = require('../he.js');
	var strings = process.argv.splice(2);
	var stdin = process.stdin;
	var data;
	var timeout;
	var action;
	var options = {};
	var log = console.log;

	var main = function() {
		var option = strings[0];
		var count = 0;

		if (/^(?:-h|--help|undefined)$/.test(option)) {
			log(
				'he v%s - https://mths.be/he',
				he.version
			);
			log([
				'\nUsage:\n',
				'\the [--escape] string',
				'\the [--encode] [--use-named-refs] [--everything] [--allow-unsafe] [--decimal] string',
				'\the [--decode] [--attribute] [--strict] string',
				'\the [-v | --version]',
				'\the [-h | --help]',
				'\nExamples:\n',
				'\the --escape \\<img\\ src\\=\\\'x\\\'\\ onerror\\=\\"prompt\\(1\\)\\"\\>',
				'\techo \'© 𝌆\' | he --decode'
			].join('\n'));
			return process.exit(option ? 0 : 1);
		}

		if (/^(?:-v|--version)$/.test(option)) {
			log('v%s', he.version);
			return process.exit(0);
		}

		strings.forEach(function(string) {
			// Process options
			if (string == '--escape') {
				action = 'escape';
				return;
			}
			if (string == '--encode') {
				action = 'encode';
				return;
			}
			if (string == '--use-named-refs') {
				action = 'encode';
				options.useNamedReferences = true;
				return;
			}
			if (string == '--everything') {
				action = 'encode';
				options.encodeEverything = true;
				return;
			}
			if (string == '--allow-unsafe') {
				action = 'encode';
				options.allowUnsafeSymbols = true;
				return;
			}
			if (string == '--decimal') {
				action = 'encode';
				options.decimal = true;
				return;
			}
			if (string == '--decode') {
				action = 'decode';
				return;
			}
			if (string == '--attribute') {
				action = 'decode';
				options.isAttributeValue = true;
				return;
			}
			if (string == '--strict') {
				action = 'decode';
				options.strict = true;
				return;
			}
			// Process string(s)
			var result;
			if (!action) {
				log('Error: he requires at least one option and a string argument.');
				log('Try `he --help` for more information.');
				return process.exit(1);
			}
			try {
				result = he[action](string, options);
				log(result);
				count++;
			} catch(error) {
				log(error.message + '\n');
				log('Error: failed to %s.', action);
				log('If you think this is a bug in he, please report it:');
				log('https://github.com/mathiasbynens/he/issues/new');
				log(
					'\nStack trace using he@%s:\n',
					he.version
				);
				log(error.stack);
				return process.exit(1);
			}
		});
		if (!count) {
			log('Error: he requires a string argument.');
			log('Try `he --help` for more information.');
			return process.exit(1);
		}
		// Return with exit status 0 outside of the `forEach` loop, in case
		// multiple strings were passed in.
		return process.exit(0);
	};

	if (stdin.isTTY) {
		// handle shell arguments
		main();
	} else {
		// Either the script is called from within a non-TTY context, or `stdin`
		// content is being piped in.
		if (!process.stdout.isTTY) {
			// The script was called from a non-TTY context. This is a rather uncommon
			// use case we don’t actively support. However, we don’t want the script
			// to wait forever in such cases, so…
			timeout = setTimeout(function() {
				// …if no piped data arrived after a whole minute, handle shell
				// arguments instead.
				main();
			}, 60000);
		}
		data = '';
		stdin.on('data', function(chunk) {
			clearTimeout(timeout);
			data += chunk;
		});
		stdin.on('end', function() {
			strings.push(data.trim());
			main();
		});
		stdin.resume();
	}

}());