UNPKG

jscrewit

Version:

Converts plain JavaScript into JSFuck code, which consists of only six different characters: ! ( ) + [ ]

1,281 lines (1,228 loc) 294 kB
// JScrewIt 3.2.0 – https://jscrew.it (function () { 'use strict'; var _Array = Array; var _Array_isArray$1 = _Array.isArray; var _Array_prototype_forEach_call; var _Array_prototype_map_call; var _Array_prototype_push_apply; var _Array_prototype_slice_call; var _Date = Date; var _Error$1 = Error; var _Function = Function; var _JSON_parse = JSON.parse; var _JSON_stringify$1 = JSON.stringify; var _Math_abs = Math.abs; var _Math_max = Math.max; var _Math_min = Math.min; var _Object = Object; var _Object_create$1 = _Object.create; var _Object_defineProperty$1 = _Object.defineProperty; var _Object_getOwnPropertyDescriptor$1 = _Object.getOwnPropertyDescriptor; var _Object_keys$1 = _Object.keys; var _RegExp = RegExp; var _String$1 = String; var _SyntaxError = SyntaxError; var _TypeError$1 = TypeError; var _parseInt = parseInt; var _setTimeout = setTimeout; function assignNoEnum$1(target, source) { var names = _Object_keys$1(source); names.forEach ( function (name) { var descriptor = _Object_getOwnPropertyDescriptor$1(source, name); descriptor.enumerable = false; _Object_defineProperty$1(target, name, descriptor); } ); return target; } var createEmpty = _Object_create$1.bind(null, null, undefined); function esToString$1(arg) { if (typeof arg === 'symbol') throw _TypeError$1('Cannot convert a symbol to a string'); var str = _String$1(arg); return str; } function noProto(obj) { var result = createEmpty(); _Object_keys$1(obj).forEach ( function (name) { result[name] = obj[name]; } ); return result; } function tryCreateRegExp(pattern, flags) { try { var regExp = _RegExp(pattern, flags); return regExp; } catch (error) { } } var noop = _Function(); (function () { var _Array_prototype = _Array.prototype; var _Function_prototype = _Function.prototype; var _Function_prototype_apply = _Function_prototype.apply; var _Function_prototype_call = _Function_prototype.call; _Function_prototype_call.bind(_Array_prototype.every); _Array_prototype_forEach_call = _Function_prototype_call.bind(_Array_prototype.forEach); _Array_prototype_map_call = _Function_prototype_call.bind(_Array_prototype.map); _Array_prototype_slice_call = _Function_prototype_call.bind(_Array_prototype.slice); _Array_prototype_push_apply = _Function_prototype_apply.bind(_Array_prototype.push); } )(); function addCluster(start, length, data, saving) { var startLink = getOrCreateStartLink(this.startLinks, start); var cluster = startLink[length]; if (cluster) { if (cluster.saving < saving) { cluster.data = data; cluster.saving = saving; } } else { cluster = startLink[length] = { start: start, length: length, data: data, saving: saving }; this.clusters.push(cluster); } if (this.maxLength < length) this.maxLength = length; } function compareClustersByQuality(cluster1, cluster2) { var diff = cluster1.saving - cluster2.saving || cluster2.length - cluster1.length || compareClustersByStart(cluster2, cluster1); return diff; } function compareClustersByStart(cluster1, cluster2) { var diff = cluster2.start - cluster1.start; return diff; } function conclude() { var bestClusters = []; var clusters = this.clusters; if (clusters.length) { clusters.sort(compareClustersByQuality); var cluster; while (cluster = pickBestCluster(this.startLinks, clusters, this.maxLength)) bestClusters.push(cluster); bestClusters.sort(compareClustersByStart); } return bestClusters; } function getOrCreateStartLink(startLinks, start) { var startLink = startLinks[start] || (startLinks[start] = []); return startLink; } function pickBestCluster(startLinks, clusters, maxLength) { var cluster; while (cluster = clusters.pop()) { if (cluster.saving != null) { unlinkClusters(startLinks, maxLength, cluster); return cluster; } } } function unlinkClusters(startLinks, maxLength, cluster) { var startLink; var start = cluster.start; var index = start; var end = start + cluster.length; do { startLink = startLinks[index]; if (startLink) { unlinkClustersFromLength(startLink, 0); delete startLinks[index]; } } while (++index < end); for (var length = 1; length < maxLength;) { startLink = startLinks[start - length++]; if (startLink) { unlinkClustersFromLength(startLink, length); startLink.length = length; } } } function unlinkClustersFromLength(startLink, fromLength) { for (var length = startLink.length; length-- > fromLength;) { var cluster = startLink[length]; if (cluster) delete cluster.saving; } } function createClusteringPlan() { var plan = { addCluster: addCluster, clusters: [], conclude: conclude, maxLength: 0, startLinks: createEmpty(), }; return plan; } /****************************************************************************** Copyright (c) Microsoft Corporation. Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ***************************************************************************** */ var extendStatics = function(d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; return extendStatics(d, b); }; function __extends(d, b) { if (typeof b !== "function" && b !== null) throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); } var __assign = function() { __assign = Object.assign || function __assign(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) { var e = new Error(message); return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e; }; // ~feature-hub – https://github.com/fasttime/JScrewIt/tree/master/packages/~feature-hub /** An empty mask. */ var MASK_EMPTY = 0; /** Determines whether two specified masks are equal. */ function maskAreEqual(mask1, mask2) { return mask1 === mask2; } /** Determines whether a specified mask includes another one. */ function maskIncludes(includingMask, includedMask) { var returnValue = (includingMask & includedMask) === includedMask; return returnValue; } /** Returns a new mask that is the intersection of two specified masks. */ function maskIntersection(mask1, mask2) { var intersectionMask = (mask1 & mask2); return intersectionMask; } /** * Returns a new non-empty mask that does not intersect the specified mask. * * @throws If the specified mask is full, a `RangeError` is thrown. */ function maskNext(mask) { var nextValue = mask + 1 & ~mask; if (!nextValue) throw RangeError('Mask full'); return nextValue; } /** Returns a new mask that is the union of two specified masks. */ function maskUnion(mask1, mask2) { var unionMask = (mask1 | mask2); return unionMask; } var keyFor = function (mask) { return mask; }; var MaskIndex = /** @class */ (function () { function MaskIndex() { this._index = Object.create(null); this._size = 0; } Object.defineProperty(MaskIndex.prototype, "size", { /* The number of entries in the current collection. */ get: function () { return this._size; }, enumerable: false, configurable: true }); /** Determines whether the current collection contains an entry for a specified mask. */ MaskIndex.prototype.has = function (mask) { var key = keyFor(mask); var returnValue = key in this._index; return returnValue; }; MaskIndex.prototype._setEntry = function (mask, value) { var key = keyFor(mask); var _index = this._index; if (!(key in _index)) ++this._size; _index[key] = value; }; return MaskIndex; }()); /** A data structure that maps masks to arbitrary values. */ var MaskMap = /** @class */ (function (_super) { __extends(MaskMap, _super); function MaskMap() { return _super !== null && _super.apply(this, arguments) || this; } /** * Retrieves the value associated with a specified mask, or `undefined` if the mask has not been * set. */ MaskMap.prototype.get = function (mask) { var key = keyFor(mask); var value = this._index[key]; return value; }; /** * Associates a specified value with a specified mask. * If the mask has already been set, the previous value will be overwritten. */ MaskMap.prototype.set = function (mask, value) { this._setEntry(mask, value); }; return MaskMap; }(MaskIndex)); /** A data structure that stores unique masks. */ var MaskSet = /** @class */ (function (_super) { __extends(MaskSet, _super); function MaskSet() { return _super !== null && _super.apply(this, arguments) || this; } /** * Adds a specified mask to the current `MaskSet` object. * If the mask has already been added, nothing is done. */ MaskSet.prototype.add = function (mask) { this._setEntry(mask, undefined); }; return MaskSet; }(MaskIndex)); var _Array_isArray = Array.isArray; var _Error = Error; var _JSON_stringify = JSON.stringify; var _Object_create = Object.create, _Object_defineProperty = Object.defineProperty, _Object_freeze = Object.freeze, _Object_getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor, _Object_keys = Object.keys; var _String = String; var _TypeError = TypeError; function assignNoEnum(target, source) { var names = _Object_keys(source); for (var _i = 0, names_1 = names; _i < names_1.length; _i++) { var name_1 = names_1[_i]; var descriptor = _Object_getOwnPropertyDescriptor(source, name_1); descriptor.enumerable = false; _Object_defineProperty(target, name_1, descriptor); } } function createFeatureClass(featureInfos, formatEngineDescription) { var ALL = createMap(); var DESCRIPTION_MAP = createMap(); var ELEMENTARY = []; var ENGINE = []; var FAMILIES = createMap(); var FEATURE_PROTOTYPE = Feature.prototype; var INCOMPATIBLE_MASK_LIST = []; var PRISTINE_ELEMENTARY; function Feature() { var features = []; for (var _i = 0; _i < arguments.length; _i++) { features[_i] = arguments[_i]; } var mask = MASK_EMPTY; for (var _a = 0, features_1 = features; _a < features_1.length; _a++) { var feature = features_1[_a]; var otherMask = validMaskFromArrayOrStringOrFeature(feature); mask = maskUnion(mask, otherMask); } if (features.length > 1) validateMask(mask); var featureObj = this instanceof Feature ? this : _Object_create(FEATURE_PROTOTYPE); initMask(featureObj, mask); return featureObj; } function _fromMask(mask) { if (isMaskCompatible(mask)) { var includedMask = MASK_EMPTY; for (var _i = 0, ELEMENTARY_1 = ELEMENTARY; _i < ELEMENTARY_1.length; _i++) { var featureMask = ELEMENTARY_1[_i].mask; if (maskIncludes(mask, featureMask)) includedMask = maskUnion(includedMask, featureMask); } if (maskAreEqual(mask, includedMask)) { var featureObj = featureFromMask(mask); return featureObj; } } return null; } function _getMask(feature) { var mask = feature !== undefined ? validMaskFromArrayOrStringOrFeature(feature) : MASK_EMPTY; return mask; } function areCompatible() { var features = []; for (var _i = 0; _i < arguments.length; _i++) { features[_i] = arguments[_i]; } var mask = featureArrayToMask(features); var compatible = isMaskCompatible(mask); return compatible; } function areEqual() { var features = []; for (var _i = 0; _i < arguments.length; _i++) { features[_i] = arguments[_i]; } var mask; var equal = features.every(function (feature, index) { var returnValue; var otherMask = validMaskFromArrayOrStringOrFeature(feature); if (index) returnValue = maskAreEqual(otherMask, mask); else { mask = otherMask; returnValue = true; } return returnValue; }); return equal; } function commonOf() { var features = []; for (var _i = 0; _i < arguments.length; _i++) { features[_i] = arguments[_i]; } var featureObj; if (features.length) { var mask = void 0; for (var _a = 0, features_2 = features; _a < features_2.length; _a++) { var feature = features_2[_a]; var otherMask = validMaskFromArrayOrStringOrFeature(feature); if (mask != null) mask = maskIntersection(mask, otherMask); else mask = otherMask; } featureObj = featureFromMask(mask); } else featureObj = null; return featureObj; } function createFeature(name, mask, check, attributes, elementary) { _Object_freeze(attributes); var descriptors = { attributes: { value: attributes }, check: { value: check }, name: { value: name } }; if (elementary) descriptors.elementary = { value: true }; var featureObj = _Object_create(FEATURE_PROTOTYPE, descriptors); initMask(featureObj, mask); return featureObj; } function descriptionFor(name) { name = esToString(name); if (!(name in DESCRIPTION_MAP)) throwUnknownFeatureError(name); var description = DESCRIPTION_MAP[name]; return description; } function featureArrayToMask(features) { var mask = MASK_EMPTY; for (var _i = 0, features_3 = features; _i < features_3.length; _i++) { var feature = features_3[_i]; var otherMask = maskFromStringOrFeature(feature); mask = maskUnion(mask, otherMask); } return mask; } function featureFromMask(mask) { var featureObj = _Object_create(FEATURE_PROTOTYPE); initMask(featureObj, mask); return featureObj; } /** * Node.js custom inspection function. * * @see * {@link https://nodejs.org/api/util.html#util_custom_inspection_functions_on_objects} for * further information. */ function inspect(depth, opts) { var _a, _b, _c; var breakLength = (_a = opts.breakLength) !== null && _a !== void 0 ? _a : 80; var compact = (_b = opts.compact) !== null && _b !== void 0 ? _b : true; var name = (_c = this.name) !== null && _c !== void 0 ? _c : joinParts(compact, '<', '', this.canonicalNames, ',', '>', breakLength - 3); var parts = [name]; if (this.elementary) parts.push('(elementary)'); if (this.check) parts.push('(check)'); { var attributes = this.attributes; if (typeof attributes === 'object') { var str_1 = utilInspect(__assign({}, attributes), opts); parts.push(str_1); } } var str = joinParts(compact, '[Feature', ' ', parts, '', ']', breakLength - 1); return str; } function isMaskCompatible(mask) { var compatible = INCOMPATIBLE_MASK_LIST.every(function (incompatibleMask) { return !maskIncludes(mask, incompatibleMask); }); return compatible; } function maskFromStringOrFeature(feature) { var featureObj; if (feature instanceof Feature) featureObj = feature; else { var name_2 = esToString(feature); if (!(name_2 in ALL)) throwUnknownFeatureError(name_2); featureObj = ALL[name_2]; } var mask = featureObj.mask; return mask; } function validMaskFromArrayOrStringOrFeature(feature) { var mask; if (_Array_isArray(feature)) { mask = featureArrayToMask(feature); if (feature.length > 1) validateMask(mask); } else mask = maskFromStringOrFeature(feature); return mask; } function validateMask(mask) { if (!isMaskCompatible(mask)) throw _Error('Incompatible features'); } var utilInspect; try { /* eslint-disable @typescript-eslint/no-require-imports, n/prefer-node-protocol */ utilInspect = require('util').inspect; /* eslint-enable @typescript-eslint/no-require-imports, n/prefer-node-protocol */ } catch (_a) { } { var protoSource = { get canonicalNames() { var mask = this.mask; var names = []; var includedMask = MASK_EMPTY; for (var index = PRISTINE_ELEMENTARY.length; index--;) { var featureObj = PRISTINE_ELEMENTARY[index]; var featureMask = featureObj.mask; if (maskIncludes(mask, featureMask) && !maskIncludes(includedMask, featureMask)) { includedMask = maskUnion(includedMask, featureMask); names.push(featureObj.name); } } names.sort(); return names; }, elementary: false, get elementaryNames() { var names = []; var mask = this.mask; for (var _i = 0, ELEMENTARY_2 = ELEMENTARY; _i < ELEMENTARY_2.length; _i++) { var featureObj = ELEMENTARY_2[_i]; var included = maskIncludes(mask, featureObj.mask); if (included) names.push(featureObj.name); } return names; }, includes: function () { var features = []; for (var _i = 0; _i < arguments.length; _i++) { features[_i] = arguments[_i]; } var mask = this.mask; var included = features.every(function (feature) { var otherMask = validMaskFromArrayOrStringOrFeature(feature); var returnValue = maskIncludes(mask, otherMask); return returnValue; }); return included; }, name: undefined, toString: function () { var _a; var name = (_a = this.name) !== null && _a !== void 0 ? _a : "<".concat(this.canonicalNames.join(', '), ">"); var str = "[Feature ".concat(name, "]"); return str; }, }; assignNoEnum(FEATURE_PROTOTYPE, protoSource); } (function () { var compareFeatureNames = function (feature1, feature2) { return feature1.name < feature2.name ? -1 : 1; }; function completeExclusions() { var incompatibleMaskSet = new MaskSet(); for (var _i = 0, featureNames_1 = featureNames; _i < featureNames_1.length; _i++) { var name_3 = featureNames_1[_i]; var excludes = featureInfos[name_3].excludes; if (excludes) { var mask = ALL[name_3].mask; for (var _a = 0, excludes_1 = excludes; _a < excludes_1.length; _a++) { var exclude = excludes_1[_a]; var excludeMask = completeFeature(exclude); var incompatibleMask = maskUnion(mask, excludeMask); if (!incompatibleMaskSet.has(incompatibleMask)) { INCOMPATIBLE_MASK_LIST.push(incompatibleMask); incompatibleMaskSet.add(incompatibleMask); } } } } } function completeFeature(name) { var mask; if (name in ALL) (mask = ALL[name].mask); else { var info_1 = featureInfos[name]; var getInfoStringField = function (fieldName) { return fieldName in info_1 ? esToString(info_1[fieldName]) : undefined; }; var description = getInfoStringField('description'); var featureObj = void 0; if ('aliasFor' in info_1) { var aliasFor = esToString(info_1.aliasFor); mask = completeFeature(aliasFor); featureObj = ALL[aliasFor]; description !== null && description !== void 0 ? description : (description = DESCRIPTION_MAP[aliasFor]); } else { var inherits = getInfoStringField('inherits'); if (inherits != null) completeFeature(inherits); var wrappedCheck = void 0; var compatibilities = void 0; var check = info_1.check; if (check !== undefined) { mask = maskNext(unionMask); unionMask = maskUnion(unionMask, mask); wrappedCheck = wrapCheck(check); } else { mask = MASK_EMPTY; wrappedCheck = null; } { var includes = info_1.includes; var includeSet = includeSetMap[name] = createMap(); if (_Array_isArray(includes)) { for (var _i = 0, includes_1 = includes; _i < includes_1.length; _i++) { var include = includes_1[_i]; includeSet[include] = null; } } else { if (inherits != null) { var inheritedIncludeSet = includeSetMap[inherits]; for (var include in inheritedIncludeSet) includeSet[include] = null; } if (includes) { var includeDiffNames = _Object_keys(includes); for (var _a = 0, includeDiffNames_1 = includeDiffNames; _a < includeDiffNames_1.length; _a++) { var include = includeDiffNames_1[_a]; if (includes[include]) includeSet[include] = null; else delete includeSet[include]; } } } for (var include in includeSet) { var includeMask = completeFeature(include); mask = maskUnion(mask, includeMask); } } if ('versions' in info_1) { var families = info_1.families; var infoVersions_1 = info_1.versions; if (inherits != null) families !== null && families !== void 0 ? families : (families = familiesMap[inherits]); familiesMap[name] = families; var tag_1 = getInfoStringField('compatibilityTag'); var shortTag_1 = getInfoStringField('compatibilityShortTag'); compatibilities = families.map(function (family, index) { var _a; family = esToString(family); var versionInfo = esToString(infoVersions_1[index]); var parts = versionInfo.split('|'); var versions = parts.map(function (part) { var match = /^([^-]+)-(?:([^-]+))?$/.exec(part); if (match) { var from = match[1], to = match[2]; var engineVersion = _Object_freeze({ from: from, to: to }); return engineVersion; } return part; }); var compatibility = _Object_freeze({ family: family, featureName: name, versions: versions, tag: tag_1, shortTag: shortTag_1 }); var familyCompatibilities = (_a = FAMILIES[family]) !== null && _a !== void 0 ? _a : (FAMILIES[family] = []); familyCompatibilities.push(compatibility); return compatibility; }); description !== null && description !== void 0 ? description : (description = formatEngineDescription === null || formatEngineDescription === void 0 ? void 0 : formatEngineDescription(compatibilities)); } var attributes = createMap(); if (inherits != null) { var inheritedAttributes = ALL[inherits].attributes; for (var attributeName in inheritedAttributes) attributes[attributeName] = inheritedAttributes[attributeName]; } { var infoAttributes = info_1.attributes; if (infoAttributes !== undefined) { var attributeNames = _Object_keys(infoAttributes); for (var _b = 0, attributeNames_1 = attributeNames; _b < attributeNames_1.length; _b++) { var attributeName = attributeNames_1[_b]; var attributeValue = infoAttributes[attributeName]; if (attributeValue !== undefined) { attributes[attributeName] = typeof attributeValue === 'string' ? attributeValue : null; } else delete attributes[attributeName]; } } } var elementary = wrappedCheck !== null && wrappedCheck !== void 0 ? wrappedCheck : info_1.excludes; featureObj = createFeature(name, mask, wrappedCheck, attributes, elementary); if (elementary) ELEMENTARY.push(featureObj); if (compatibilities) ENGINE.push(featureObj); } ALL[name] = featureObj; DESCRIPTION_MAP[name] = description; } return mask; } { var constructorSource = { ALL: ALL, ELEMENTARY: ELEMENTARY, ENGINE: ENGINE, FAMILIES: FAMILIES, _fromMask: _fromMask, _getMask: _getMask, areCompatible: areCompatible, areEqual: areEqual, commonOf: commonOf, descriptionFor: descriptionFor, }; assignNoEnum(Feature, constructorSource); } if (utilInspect) { _Object_defineProperty(FEATURE_PROTOTYPE, utilInspect.custom, { configurable: true, value: inspect, writable: true }); } var featureNames = _Object_keys(featureInfos); var includeSetMap = createMap(); var familiesMap = createMap(); var unionMask = MASK_EMPTY; featureNames.forEach(completeFeature); completeExclusions(); PRISTINE_ELEMENTARY = ELEMENTARY.slice(); ELEMENTARY.sort(compareFeatureNames); _Object_freeze(ELEMENTARY); ENGINE.sort(compareFeatureNames); _Object_freeze(ENGINE); _Object_freeze(ALL); _Object_freeze(FAMILIES); for (var family in FAMILIES) _Object_freeze(FAMILIES[family]); })(); return Feature; } var createMap = function () { return _Object_create(null); }; function esToString(name) { if (typeof name === 'symbol') throw _TypeError('Cannot convert a symbol to a string'); var str = _String(name); return str; } function featuresToMask(featureObjs) { var mask = featureObjs.reduce(function (mask, featureObj) { return maskUnion(mask, featureObj.mask); }, MASK_EMPTY); return mask; } function indent(text) { var returnValue = text.replace(/^/gm, ' '); return returnValue; } function initMask(featureObj, mask) { _Object_defineProperty(featureObj, 'mask', { value: mask }); } function joinParts(compact, intro, preSeparator, parts, partSeparator, outro, maxLength) { function isMultiline() { var length = intro.length + preSeparator.length + (parts.length - 1) * (partSeparator.length + 1) + outro.length; for (var _i = 0, parts_1 = parts; _i < parts_1.length; _i++) { var part = parts_1[_i]; if (~part.indexOf('\n')) return true; length += part.replace(/\x1b\[\d+m/g, '').length; if (length > maxLength) return true; } return false; } var str = parts.length && (!compact || isMultiline()) ? "".concat(intro, "\n").concat(indent(parts.join("".concat(partSeparator, "\n"))), "\n").concat(outro) : "".concat(intro).concat(preSeparator).concat(parts.join("".concat(partSeparator, " "))).concat(outro); return str; } function throwUnknownFeatureError(name) { throw _Error("Unknown feature ".concat(_JSON_stringify(name))); } function wrapCheck(check) { var wrappedCheck = function () { return !!check(); }; return wrappedCheck; } // End of module ~feature-hub var ELEMENTARY; var Feature; function checkLocaleNumeral(locale, number, regExp) { var localizedNumeral = number.toLocaleString(locale); var returnValue = regExp.test(localizedNumeral); return returnValue; } function describeEngine(engine) { var description = 'Features available in ' + engine + '.'; return description; } function isExcludingAttribute(restrictionCache, restrictionName, featureObjs) { var returnValue = restrictionCache[restrictionName]; if (returnValue === undefined) { restrictionCache[restrictionName] = returnValue = featureObjs.some ( function (featureObj) { var returnValue = restrictionName in featureObj.attributes; return returnValue; } ); } return returnValue; } function makeSelfFeatureCheck(regExp) { function check() { var available = typeof self !== 'undefined' && regExp.test(self + ''); return available; } return check; } function restrict(environment, engineFeatureObjs) { var restrictionCache = createEmpty(); var elementaryFeatureObjs = ELEMENTARY.filter ( function (elementaryFeatureObj) { var included = this.includes(elementaryFeatureObj); if (included) { var attributes = elementaryFeatureObj.attributes; included = !( environment in attributes && ( engineFeatureObjs === undefined || isExcludingAttribute (restrictionCache, attributes[environment], engineFeatureObjs) ) ); } return included; }, this ); var restrictedFeatureObj = Feature(elementaryFeatureObjs); return restrictedFeatureObj; } var featureInfos = { ARRAY_ITERATOR: { description: 'The property that the string representation of Array.prototype.entries() evaluates to ' + '"[object Array Iterator]".', check: function () { if (Array.prototype.entries) { var available = [].entries() + '' === '[object Array Iterator]'; return available; } }, }, ARROW: { description: 'Support for arrow functions.', check: function () { try { Function('()=>{}')(); return true; } catch (error) { } }, }, AT: { description: 'Existence of the native functions Array.prototype.at and String.prototype.at.', check: function () { var available = Array.prototype.at && String.prototype.at; return available; }, }, BARPROP: { description: 'Existence of the global object statusbar having the string representation "[object ' + 'BarProp]".', check: function () { var available = typeof statusbar === 'object' && statusbar + '' === '[object BarProp]'; return available; }, attributes: { 'web-worker': 'web-worker-restriction' }, }, CAPITAL_HTML: { description: 'The property that the various string methods returning HTML code such as ' + 'String.prototype.big or String.prototype.link have both the tag name and attributes ' + 'written in capital letters.', check: function () { var available = ''.big() === '<BIG></BIG>' && ''.fontcolor('') === '<FONT COLOR=""></FONT>' && ''.fontsize('') === '<FONT SIZE=""></FONT>' && ''.link('') === '<A HREF=""></A>' && ''.small() === '<SMALL></SMALL>' && ''.strike() === '<STRIKE></STRIKE>' && ''.sub() === '<SUB></SUB>' && ''.sup() === '<SUP></SUP>'; return available; }, }, CONSOLE: { description: 'Existence of the global object console having the string representation "[object ' + 'Console]".\n' + 'This feature may become unavailable when certain browser extensions are active.', check: function () { var available = typeof console === 'object' && console + '' === '[object Console]'; return available; }, }, DOCUMENT: { description: 'Existence of the global object document whose string representation starts with ' + '"[object " and ends with "Document]".', check: function () { var available = typeof document === 'object' && /^\[object [\S\s]*Document]$/.test(document + ''); return available; }, attributes: { 'web-worker': 'web-worker-restriction' }, }, ESC_HTML_QUOT: { description: 'The property that double quotation marks in the argument of String.prototype.fontcolor ' + 'are escaped as "&quot;".', check: function () { var available = ~''.fontcolor('"').indexOf('&quot;'); return available; }, }, FF_SRC: { description: 'A string representation of native functions typical for Firefox and Safari.\n' + 'Remarkable traits are the lack of line feed characters at the beginning and at the end ' + 'of the string and the presence of a line feed followed by four whitespaces ("\\n ") ' + 'before the "[native code]" sequence.', includes: ['NO_IE_SRC', 'NO_V8_SRC'], excludes: ['NO_FF_SRC'], }, FLAT: { description: 'Existence of the native function Array.prototype.flat.', check: function () { var available = Array.prototype.flat; return available; }, }, FROM_CODE_POINT: { description: 'Existence of the function String.fromCodePoint.', check: function () { var available = String.fromCodePoint; return available; }, }, FUNCTION_19_LF: { description: 'A string representation of dynamically generated functions where the character at index ' + '19 is a line feed ("\\n").', check: function () { var available = (Function() + '')[19] === '\n'; return available; }, }, FUNCTION_22_LF: { description: 'A string representation of dynamically generated functions where the character at index ' + '22 is a line feed ("\\n").', check: function () { var available = (Function() + '')[22] === '\n'; return available; }, }, IE_SRC: { description: 'A string representation of native functions typical for Internet Explorer.\n' + 'Remarkable traits are the presence of a line feed character ("\\n") at the beginning ' + 'and at the end of the string and a line feed followed by four whitespaces ("\\n ") ' + 'before the "[native code]" sequence.', includes: ['NO_FF_SRC', 'NO_V8_SRC'], excludes: ['NO_IE_SRC'], }, INCR_CHAR: { description: 'The ability to use unary increment operators with string characters, like in ( ++"some ' + 'string"[0] ): this will result in a TypeError in strict mode in ECMAScript compliant ' + 'engines.', check: function () { return true; }, attributes: { 'forced-strict-mode': 'char-increment-restriction' }, }, ITERATOR_HELPER: { description: 'Availability of iterator helpers.', check: function () { var available = typeof Iterator === 'function'; return available; }, }, LOCALE_INFINITY: { description: 'Language sensitive string representation of Infinity as "∞".', check: function () { var available = Infinity.toLocaleString() === '∞'; return available; }, }, LOCALE_NUMERALS_BN: { description: 'Localized number formatting for Bengali.', check: function () { var available = checkLocaleNumeral('bn', 1234567890, /^১,২৩,৪৫,৬৭,৮৯০/); return available; }, }, LOCALE_NUMERALS_EXT: { description: 'Extended localized number formatting.\n' + 'Localized number formatting including the output of the first three letters in the ' + 'second word of the Arabic string representation of NaN ("رقم"), the letters in the ' + 'Russian string representation of NaN ("не\xa0число") and the letters in the Persian ' + 'string representation of NaN ("ناعدد").', check: function () { var available = checkLocaleNumeral('ar', NaN, /^ليس.رقم/) && checkLocaleNumeral('fa', NaN, /^ناعد/) && checkLocaleNumeral('ru', NaN, /^не.число/); return available; }, }, NAME: { description: 'Existence of the name property for functions.', check: function () { var available = 'name' in Function(); return available; }, }, NO_FF_SRC: { description: 'A string representation of native functions typical for V8 or for Internet Explorer but ' + 'not for Firefox and Safari.', check: function () { var available = /^(\n?)function Object\(\) \{\1 +\[native code]\s\}/.test(Object); return available; }, excludes: ['FF_SRC'], }, NO_IE_SRC: { description: 'A string representation of native functions typical for most engines with the notable ' + 'exception of Internet Explorer.\n' + 'A remarkable trait of this feature is the lack of line feed characters at the beginning ' + 'and at the end of the string.', check: function () { var available = /^function Object\(\) \{(\n )? \[native code]\s\}/.test(Object); return available; }, excludes: ['IE_SRC'], }, NO_V8_SRC: { description: 'A string representation of native functions typical for Firefox, Internet Explorer and ' + 'Safari.\n' + 'A most remarkable trait of this feature is the presence of a line feed followed by four ' + 'whitespaces ("\\n ") before the "[native code]" sequence.', check: function () { var available = /^\n?function Object\(\) \{\n \[native code]\s\}/.test(Object); return available; }, excludes: ['V8_SRC'], }, OBJECT_ARRAY_ENTRIES_CTOR: { description: 'The property that the Array.prototype.entries().constructor is the Object constructor.', check: function () { var available = Array.prototype.entries && [].entries().constructor === Object; return available; }, }, OBJECT_W_SELF: { description: 'The property that the string representation of the global object self starts ' + 'with "[object W".', check: makeSelfFeatureCheck(/^\[object W/), includes: ['SELF'], attributes: { 'web-worker': 'non-ie-restriction' }, }, PLAIN_INTL: { description: 'Existence of the global object Intl having the string representation "[object Object]".', check: function () { var available = typeof Intl === 'object' && Intl + '' === '[object Object]'; return available; }, }, REGEXP_STRING_ITERATOR: { description: 'The property that the string representation of String.prototype.matchAll() e